本类型泛型
+ * @param 参数泛型
+ * @author wangyu
+ */
+public interface QueryChain, P> extends QueryDefinition {
+
+ /**
+ * 以且连接下一个字段
+ *
+ * @param column 列
+ * @return 查询条件
+ */
+ QueryCondition and(P column);
+
+ /**
+ * 直接拼接提供者,此处懒加载,最终build才会执行
+ *
+ * @param supplier 提供者
+ * @param 泛型,支持其他类型的链
+ * @return 结果
+ */
+ > C and(Supplier> supplier);
+
+ /**
+ * 条件列表
+ *
+ * @param chain 多个条件们
+ * @return 结果
+ */
+ C and(C chain);
+
+ /**
+ * 多个嵌套子条件列表
+ *
+ * @param chains 多条链
+ * @return 结果
+ */
+ default C and(List chains) {
+ return and(chains, Combinator.AND);
+ }
+
+ /**
+ * 多个嵌套子条件列表
+ *
+ * @param chains 多条链
+ * @param combinator 各个链条之间的连接方式
+ * @return 结果
+ */
+ C and(List chains, Combinator combinator);
+
+ /**
+ * 以或连接下一个字段
+ *
+ * @param column 列
+ * @return 查询条件
+ */
+ QueryCondition or(P column);
+
+ /**
+ * 以或连接条件列表
+ *
+ * @param chain 多个条件们
+ * @return 结果
+ */
+ C or(C chain);
+
+ /**
+ * 以或连接嵌套多个子条件列表
+ *
+ * @param chains 多条链
+ * @return 结果
+ */
+ default C or(List chains) {
+ return and(chains, Combinator.AND);
+ }
+
+ /**
+ * 以或连接嵌套多个子条件列表
+ *
+ * @param chains 多条链
+ * @param combinator 各个链条之间的连接方式
+ * @return 结果
+ */
+ C or(List chains, Combinator combinator);
+
+ /**
+ * 直接拼接提供者,此处懒加载,最终build才会执行
+ *
+ * @param supplier 提供者
+ * @param 泛型,支持其他类型的链
+ * @return 结果
+ */
+ > C or(Supplier> supplier);
+}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryCondition.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryCondition.java
new file mode 100644
index 0000000..cd1b916
--- /dev/null
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryCondition.java
@@ -0,0 +1,102 @@
+package com.flyfish.framework.query;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 查询条件
+ *
+ * @param 条件本类型
+ * @author wangyu
+ */
+public interface QueryCondition> {
+
+ /**
+ * 相等判定
+ *
+ * @param value 值
+ * @return 结果
+ */
+ C eq(Object value);
+
+ /**
+ * 判定某列的值中存在指定值,特指json array数据类型且子类型中带有id的场景
+ * 用于兼容mongodb查询,mysql查询使用JSON_CONTAINS进行判定。
+ * 当且仅当mongodb会拼接.$id,mysql一律匹配id字段
+ *
+ * 等价于 .eq(value)
+ *
+ * @param value 值
+ * @return 结果
+ */
+ C hasId(Object value);
+
+ /**
+ * 对于mongodb,自动处理。对于关系型数据库,代表json array中是否包含对应值,值仅支持基本数据类型
+ *
+ * 等价于 .eq(value)
+ *
+ * @param value 基本数据类型的值
+ * @return 结果
+ */
+ C has(Object value);
+
+ /**
+ * 不等判定
+ *
+ * @param value 值
+ * @return 结果
+ */
+ C ne(Object value);
+
+ /**
+ * 值介于两者之间
+ *
+ * @param items 双值列表
+ * @return 结果
+ */
+ C between(List> items);
+
+ /**
+ * 模糊匹配,这里是全模糊
+ *
+ * @param keyword 查询关键字
+ * @return 结果
+ */
+ C like(String keyword);
+
+ /**
+ * 根据指定的方向进行模糊查询
+ *
+ * @param keyword 关键字
+ * @param direction 方向,可以匹配开头和结尾
+ * @return 结果
+ */
+ C like(String keyword, Queries.Direction direction);
+
+ /**
+ * 判定为空
+ *
+ * @return 结果
+ */
+ C isNull();
+
+ /**
+ * 包含在内
+ *
+ * @param list 集合
+ * @return 结果
+ */
+ C in(Collection> list);
+
+ /**
+ * 包含在内
+ * 注意,需要根据字段类型推断。
+ * 如果是json数组,需要进行双向匹配
+ *
+ * @param values 值们
+ * @return 结果
+ */
+ C in(Object... values);
+
+}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryDefinition.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryDefinition.java
new file mode 100644
index 0000000..46b1bfd
--- /dev/null
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryDefinition.java
@@ -0,0 +1,31 @@
+package com.flyfish.framework.query;
+
+/**
+ * 可构建的
+ *
+ * @author wangyu
+ */
+public interface QueryDefinition {
+
+ /**
+ * 构建
+ *
+ * @param 泛型
+ * @return 构建结果
+ */
+ T build();
+
+ /**
+ * 修改,此修改会直接接着查询条件进行拼接
+ *
+ * @return 修改句柄
+ */
+ QueryMutation mutate();
+
+ /**
+ * 会直接添加嵌套查询到当前查询末尾
+ *
+ * @return 修改句柄
+ */
+ QueryMutation within();
+}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryMutation.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryMutation.java
new file mode 100644
index 0000000..9d1217d
--- /dev/null
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryMutation.java
@@ -0,0 +1,81 @@
+package com.flyfish.framework.query;
+
+import com.flyfish.framework.domain.base.Domain;
+
+import java.util.function.Function;
+
+/**
+ * 查询修改逻辑
+ *
+ * @author wangyu
+ */
+public interface QueryMutation {
+
+ /**
+ * 以lambda的形式修改
+ * 注意,如果之前用过lambda的形式,此处应该校验类型
+ *
+ * @param getter 方法引用
+ * @param 实体泛型
+ * @return 结果
+ */
+ QueryCondition> and(Function getter);
+
+ /**
+ * 以column的形式修改
+ *
+ * @param column 列名
+ * @return 结果
+ */
+ QueryCondition and(String column);
+
+ /**
+ * 直接以and拼接其他的所有条件
+ *
+ * @param chain 传入的查询
+ * @return 结果
+ */
+ LambdaQueryChain and(LambdaQueryChain chain);
+
+ /**
+ * 直接以and拼接其他的所有条件
+ *
+ * @param chain 传入的查询
+ * @return 结果
+ */
+ NamedQueryChain and(NamedQueryChain chain);
+
+ /**
+ * 以lambda的形式修改
+ * 注意,如果之前用过lambda的形式,此处应该校验类型
+ *
+ * @param getter 方法引用
+ * @param 实体泛型
+ * @return 结果
+ */
+ QueryCondition> or(Function getter);
+
+ /**
+ * 以column的形式修改
+ *
+ * @param column 列名
+ * @return 结果
+ */
+ QueryCondition or(String column);
+
+ /**
+ * 直接以or拼接其他的所有条件
+ *
+ * @param chain 传入的查询
+ * @return 结果
+ */
+ LambdaQueryChain or(LambdaQueryChain chain);
+
+ /**
+ * 直接以or拼接其他的所有条件
+ *
+ * @param chain 传入的查询
+ * @return 结果
+ */
+ NamedQueryChain or(NamedQueryChain chain);
+}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/DomainFunction.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/DomainFunction.java
new file mode 100644
index 0000000..6af2533
--- /dev/null
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/DomainFunction.java
@@ -0,0 +1,12 @@
+package com.flyfish.framework.query.support;
+
+import com.flyfish.framework.domain.base.Domain;
+
+/**
+ * 支持序列化的实体方法
+ *
+ * @param 泛型,父类为实体
+ */
+@FunctionalInterface
+public interface DomainFunction extends SFunction {
+}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/SFunction.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/SFunction.java
new file mode 100644
index 0000000..ccffeb9
--- /dev/null
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/support/SFunction.java
@@ -0,0 +1,14 @@
+package com.flyfish.framework.query.support;
+
+import java.io.Serializable;
+import java.util.function.Function;
+
+/**
+ * 支持序列化的function
+ *
+ * @param 泛型入参
+ * @param 泛型返回值
+ */
+@FunctionalInterface
+public interface SFunction extends Function, Serializable {
+}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/ReactiveEntityOperations.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/ReactiveEntityOperations.java
new file mode 100644
index 0000000..8582fba
--- /dev/null
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/ReactiveEntityOperations.java
@@ -0,0 +1,23 @@
+package com.flyfish.framework.repository;
+
+import com.flyfish.framework.domain.base.Domain;
+import com.flyfish.framework.query.Query;
+import reactor.core.publisher.Flux;
+
+/**
+ * 高层封装的模型操作
+ *
+ * @author wangyu
+ */
+public interface ReactiveEntityOperations {
+
+ /**
+ * 查询,通过查询条件和类进行精确查询
+ *
+ * @param query 查询
+ * @param entityClass 查询实体类
+ * @param 实体类的实例化结果
+ * @return 查询结果
+ */
+ Flux find(Query query, Class entityClass);
+}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/impl/QueryBuildUtils.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/impl/QueryBuildUtils.java
index 2dedee1..b5b6c38 100644
--- a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/impl/QueryBuildUtils.java
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/repository/impl/QueryBuildUtils.java
@@ -34,19 +34,19 @@ abstract class QueryBuildUtils {
* @return 结果
*/
static Optional buildQuery(Qo qo) {
- Criteria criteria = null;
- if (null != qo.getCriteria()) {
- criteria = qo.getCriteria();
- } else if (null != qo.getExample()) {
- criteria = new Criteria().alike(qo.getExample());
- } else {
- Class type = qo.pojoType();
- if (null != type && !Object.class.equals(type)) {
- try {
- T pojo = CopyUtils.copyQueryProps(qo, qo.pojoType().newInstance());
- criteria = new Criteria().alike(Example.of(pojo));
- } catch (InstantiationException | IllegalAccessException e) {
- e.printStackTrace();
+ Criteria criteria = qo.getCriteria();
+ if (null == criteria) {
+ if (null != qo.getExample()) {
+ criteria = new Criteria().alike(qo.getExample());
+ } else {
+ Class type = qo.pojoType();
+ if (null != type && !Object.class.equals(type)) {
+ try {
+ T pojo = CopyUtils.copyQueryProps(qo, qo.pojoType().newInstance());
+ criteria = new Criteria().alike(Example.of(pojo));
+ } catch (InstantiationException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
}
}
}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/Query.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/Query.java
deleted file mode 100644
index afb659a..0000000
--- a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/utils/Query.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.flyfish.framework.utils;
-
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * 查询参数
- */
-public class Query extends LinkedHashMap {
- private static final long serialVersionUID = 1L;
- //当前页码
- private int page = 1;
- //每页条数
- private int limit = 10;
-
- public Query(Map params) {
- this.putAll(params);
- //分页参数
- if (params.get("page") != null) {
- this.page = Integer.parseInt(params.get("page").toString());
- }
- if (params.get("limit") != null) {
- this.limit = Integer.parseInt(params.get("limit").toString());
- }
- this.remove("page");
- this.remove("limit");
- }
-
-
- public int getPage() {
- return page;
- }
-
- public void setPage(int page) {
- this.page = page;
- }
-
- public int getLimit() {
- return limit;
- }
-
- public void setLimit(int limit) {
- this.limit = limit;
- }
-}
diff --git a/flyfish-data/flyfish-data-mongodb/pom.xml b/flyfish-data/flyfish-data-mongodb/pom.xml
index f79189c..2a55c88 100644
--- a/flyfish-data/flyfish-data-mongodb/pom.xml
+++ b/flyfish-data/flyfish-data-mongodb/pom.xml
@@ -16,4 +16,21 @@
8
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb-reactive
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+
+ com.flyfish.framework
+ flyfish-data-common
+ ${project.version}
+
+
diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/DefaultReactiveRepositoryImpl.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/DefaultReactiveRepositoryImpl.java
new file mode 100644
index 0000000..8e333fc
--- /dev/null
+++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/DefaultReactiveRepositoryImpl.java
@@ -0,0 +1,184 @@
+package com.flyfish.framework.mongodb.repository;
+
+import com.flyfish.framework.domain.base.Domain;
+import com.flyfish.framework.domain.base.Qo;
+import com.flyfish.framework.repository.DefaultReactiveRepository;
+import lombok.Getter;
+import lombok.NonNull;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.ReactiveMongoOperations;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
+import org.springframework.data.mongodb.repository.support.SimpleReactiveMongoRepository;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 默认的异步仓库实现
+ *
+ * @param 泛型
+ */
+public class DefaultReactiveRepositoryImpl extends SimpleReactiveMongoRepository
+ implements DefaultReactiveRepository {
+
+ @Getter
+ private final MongoEntityInformation entityInformation;
+
+ private final ReactiveMongoOperations mongoOperations;
+
+ public DefaultReactiveRepositoryImpl(@NonNull MongoEntityInformation entityInformation,
+ @NonNull ReactiveMongoOperations mongoOperations) {
+ super(entityInformation, mongoOperations);
+ this.mongoOperations = mongoOperations;
+ this.entityInformation = entityInformation;
+ }
+
+ /**
+ * 通过名称查找一个
+ *
+ * @param name 名称
+ * @return 结果
+ */
+ @Override
+ public Mono findByName(String name) {
+ if (StringUtils.isNotBlank(name)) {
+ return mongoOperations.findOne(Query.query(Criteria.where("name").is(name)),
+ entityInformation.getJavaType(), entityInformation.getCollectionName());
+ }
+ return Mono.empty();
+ }
+
+ /**
+ * Returns a single entity matching the given {@link Qo} or {@link Optional#empty()} if none was found.
+ *
+ * @param query must not be {@literal null}.
+ * @return a single entity matching the given {@link Qo} or {@link Optional#empty()} if none was found.
+ * @throws IncorrectResultSizeDataAccessException if the Qo yields more than one
+ * result.
+ */
+ @Override
+ public Mono findOne(Qo query) {
+ return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
+ .flatMap(querying -> mongoOperations.findOne(querying, entityInformation.getJavaType(),
+ entityInformation.getCollectionName()));
+ }
+
+ /**
+ * Returns all entities matching the given {@link Qo}. In case no match could be found an empty
+ * {@link Iterable} is returned.
+ *
+ * @param query must not be {@literal null}.
+ * @return all entities matching the given {@link Qo}.
+ */
+ @Override
+ public Flux findAll(Qo query) {
+ return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
+ .flatMapMany(querying -> mongoOperations.find(querying,
+ entityInformation.getJavaType(),
+ entityInformation.getCollectionName()))
+ .doOnNext(t -> t.setCurrentUser(query.getUser()));
+ }
+
+ /**
+ * Returns all entities matching the given {@link Qo} applying the given {@link Sort}. In case no match could
+ * be found an empty {@link Iterable} is returned.
+ *
+ * @param query must not be {@literal null}.
+ * @param sort the {@link Sort} specification to sort the results by, may be {@link Sort#empty()}, must not be
+ * {@literal null}.
+ * @return all entities matching the given {@link Qo}.
+ * @since 1.10
+ */
+ @Override
+ public Flux findAll(Qo query, Sort sort) {
+ return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
+ .flatMapMany(querying -> mongoOperations.find(querying.with(sort),
+ entityInformation.getJavaType(),
+ entityInformation.getCollectionName()));
+ }
+
+ /**
+ * Returns a {@link Page} of entities matching the given {@link Qo}. In case no match could be found, an empty
+ * {@link Page} is returned.
+ *
+ * @param query must not be {@literal null}.
+ * @param pageable may be {@link Pageable#unpaged()}, must not be {@literal null}.
+ * @return a {@link Page} of entities matching the given {@link Qo}.
+ */
+ @Override
+ public Mono> findAll(Qo query, Pageable pageable) {
+ return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
+ .flatMap(querying -> mongoOperations.find(querying.with(pageable),
+ entityInformation.getJavaType(), entityInformation.getCollectionName())
+ .doOnNext(t -> t.setCurrentUser(query.getUser()))
+ .collectList()
+ .flatMap(list -> ReactivePageableExecutionUtils.getPage(list, pageable, this.count(query))))
+ .defaultIfEmpty(Page.empty());
+ }
+
+ /**
+ * Returns the number of instances matching the given {@link Qo}.
+ *
+ * @param query the {@link Qo} to count instances for, must not be {@literal null}.
+ * @return the number of instances matching the {@link Qo}.
+ */
+ @Override
+ public Mono count(Qo query) {
+ return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
+ .flatMap(querying -> this.mongoOperations.count(querying, entityInformation.getJavaType(),
+ entityInformation.getCollectionName()))
+ .defaultIfEmpty(0L);
+ }
+
+ /**
+ * 通过特定键的集合查询
+ *
+ * @param key 键
+ * @param values 集合
+ * @return 结果
+ */
+ @Override
+ public Flux findAllByValues(String key, List> values) {
+ Criteria criteria = Criteria.where(key).in(values);
+ Query query = new Query(criteria);
+ return mongoOperations.find(query,
+ entityInformation.getJavaType(),
+ entityInformation.getCollectionName());
+ }
+
+ /**
+ * Checks whether the data store contains elements that match the given {@link Qo}.
+ *
+ * @param query the {@link Qo} to use for the existence check, must not be {@literal null}.
+ * @return {@literal true} if the data store contains elements that match the given {@link Qo}.
+ */
+ @Override
+ public Mono exists(Qo query) {
+ return Mono.justOrEmpty(QueryBuildUtils.getQuery(query))
+ .flatMap(querying -> mongoOperations.exists(querying,
+ entityInformation.getJavaType(), entityInformation.getCollectionName()))
+ .defaultIfEmpty(false);
+ }
+
+ /**
+ * 删除全部
+ *
+ * @param qo 查询实体
+ * @return 结果
+ */
+ @Override
+ public Mono deleteAll(Qo qo) {
+ return Mono.justOrEmpty(QueryBuildUtils.getQuery(qo))
+ .flatMap(querying -> mongoOperations.remove(querying, entityInformation.getJavaType(),
+ entityInformation.getCollectionName()))
+ .then(Mono.empty());
+ }
+}
diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/DefaultRepositoryImpl.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/DefaultRepositoryImpl.java
new file mode 100644
index 0000000..10f7b23
--- /dev/null
+++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/DefaultRepositoryImpl.java
@@ -0,0 +1,173 @@
+package com.flyfish.framework.mongodb.repository;
+
+import com.flyfish.framework.domain.base.Domain;
+import com.flyfish.framework.domain.base.Qo;
+import com.flyfish.framework.repository.DefaultRepository;
+import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
+import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
+import org.springframework.data.support.PageableExecutionUtils;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 查询模型支持
+ *
+ * @author wangyu
+ * 基于repo的公共扩展
+ */
+public class DefaultRepositoryImpl extends SimpleMongoRepository
+ implements DefaultRepository {
+
+ private MongoOperations mongoOperations;
+ @Getter
+ private MongoEntityInformation entityInformation;
+
+ /**
+ * Creates a new {@link SimpleMongoRepository} for the given {@link MongoEntityInformation} and {@link MongoTemplate}.
+ *
+ * @param metadata must not be {@literal null}.
+ * @param mongoOperations must not be {@literal null}.
+ */
+ public DefaultRepositoryImpl(MongoEntityInformation metadata, MongoOperations mongoOperations) {
+ super(metadata, mongoOperations);
+ this.mongoOperations = mongoOperations;
+ this.entityInformation = metadata;
+ }
+
+ /**
+ * 通过名称查找一个
+ *
+ * @param name 名称
+ * @return 结果
+ */
+ @Override
+ public Optional findByName(String name) {
+ if (StringUtils.isNotBlank(name)) {
+ return Optional.ofNullable(mongoOperations.findOne(Query.query(Criteria.where("name").is(name)),
+ entityInformation.getJavaType(), entityInformation.getCollectionName()));
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Returns a single entity matching the given {@link Qo} or {@link Optional#empty()} if none was found.
+ *
+ * @param query must not be {@literal null}.
+ * @return a single entity matching the given {@link Qo} or {@link Optional#empty()} if none was found.
+ * @throws IncorrectResultSizeDataAccessException if the Qo yields more than one
+ * result.
+ */
+ @Override
+ public Optional findOne(Qo query) {
+ return QueryBuildUtils.getQuery(query)
+ .map(querying -> mongoOperations.findOne(querying,
+ entityInformation.getJavaType(),
+ entityInformation.getCollectionName()));
+ }
+
+ /**
+ * Returns all entities matching the given {@link Qo}. In case no match could be found an empty
+ * {@link Iterable} is returned.
+ *
+ * @param query must not be {@literal null}.
+ * @return all entities matching the given {@link Qo}.
+ */
+ @Override
+ public Iterable findAll(Qo query) {
+ return QueryBuildUtils.getQuery(query)
+ .map(querying -> mongoOperations.find(querying,
+ entityInformation.getJavaType(),
+ entityInformation.getCollectionName()))
+ .orElse(Collections.emptyList());
+ }
+
+ /**
+ * Returns all entities matching the given {@link Qo} applying the given {@link Sort}. In case no match could
+ * be found an empty {@link Iterable} is returned.
+ *
+ * @param query must not be {@literal null}.
+ * @param sort the {@link Sort} specification to sort the results by, may be {@link Sort#empty()}, must not be
+ * {@literal null}.
+ * @return all entities matching the given {@link Qo}.
+ * @since 1.10
+ */
+ @Override
+ public Iterable findAll(Qo query, Sort sort) {
+ return QueryBuildUtils.getQuery(query)
+ .map(querying -> mongoOperations.find(querying.with(sort),
+ entityInformation.getJavaType(),
+ entityInformation.getCollectionName()))
+ .orElse(Collections.emptyList());
+ }
+
+ /**
+ * Returns a {@link Page} of entities matching the given {@link Qo}. In case no match could be found, an empty
+ * {@link Page} is returned.
+ *
+ * @param query must not be {@literal null}.
+ * @param pageable may be {@link Pageable#unpaged()}, must not be {@literal null}.
+ * @return a {@link Page} of entities matching the given {@link Qo}.
+ */
+ @Override
+ public Page findAll(Qo query, Pageable pageable) {
+ return QueryBuildUtils.getQuery(query).map(querying -> {
+ List queryResult = mongoOperations.find(querying.with(pageable),
+ entityInformation.getJavaType(), entityInformation.getCollectionName());
+ return PageableExecutionUtils.getPage(queryResult, pageable, () -> count(query));
+ }).orElse(Page.empty());
+ }
+
+ /**
+ * Returns the number of instances matching the given {@link Qo}.
+ *
+ * @param query the {@link Qo} to count instances for, must not be {@literal null}.
+ * @return the number of instances matching the {@link Qo}.
+ */
+ @Override
+ public long count(Qo query) {
+ return QueryBuildUtils.getQuery(query)
+ .map(q -> this.mongoOperations.count(q, entityInformation.getJavaType(), entityInformation.getCollectionName()))
+ .orElse(0L);
+ }
+
+ /**
+ * 通过特定键的集合查询
+ *
+ * @param key 键
+ * @param values 集合
+ * @return 结果
+ */
+ @Override
+ public List findAllByValues(String key, List> values) {
+ Criteria criteria = Criteria.where(key).in(values);
+ Query query = new Query(criteria);
+ return mongoOperations.find(query,
+ entityInformation.getJavaType(),
+ entityInformation.getCollectionName());
+ }
+
+ /**
+ * Checks whether the data store contains elements that match the given {@link Qo}.
+ *
+ * @param query the {@link Qo} to use for the existence check, must not be {@literal null}.
+ * @return {@literal true} if the data store contains elements that match the given {@link Qo}.
+ */
+ @Override
+ public boolean exists(Qo query) {
+ return QueryBuildUtils.getQuery(query).map(querying -> mongoOperations.exists(querying,
+ entityInformation.getJavaType(), entityInformation.getCollectionName()))
+ .orElse(false);
+ }
+}
diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/QueryBuildUtils.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/QueryBuildUtils.java
new file mode 100644
index 0000000..e0b42c8
--- /dev/null
+++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/QueryBuildUtils.java
@@ -0,0 +1,60 @@
+package com.flyfish.framework.mongodb.repository;
+
+import com.flyfish.framework.domain.base.Qo;
+import com.flyfish.framework.utils.CopyUtils;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.data.domain.Example;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+
+import java.util.Optional;
+
+abstract class QueryBuildUtils {
+
+ /**
+ * 从查询实体抽取内部查询信息
+ *
+ * @param qo 查询实体
+ * @return 结果
+ */
+ static Optional getQuery(Qo qo) {
+ return buildQuery(qo).map(query -> {
+ if (CollectionUtils.isNotEmpty(qo.getFields())) {
+ query.fields().include(qo.getFields().toArray(new String[]{}));
+ }
+ return query;
+ });
+ }
+
+ /**
+ * 构建查询
+ *
+ * @param qo 查询实体
+ * @param 泛型
+ * @return 结果
+ */
+ static Optional buildQuery(Qo qo) {
+ Criteria criteria = qo.getCriteria();
+ if (null == criteria) {
+ if (null != qo.getExample()) {
+ criteria = new Criteria().alike(qo.getExample());
+ } else {
+ Class type = qo.pojoType();
+ if (null != type && !Object.class.equals(type)) {
+ try {
+ T pojo = CopyUtils.copyQueryProps(qo, qo.pojoType().newInstance());
+ criteria = new Criteria().alike(Example.of(pojo));
+ } catch (InstantiationException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ if (criteria != null) {
+ // 针对删除状态全局筛选
+ return Optional.of(new Query(Criteria.where("delete").ne(true).andOperator(criteria))
+ .with(qo.sorts()));
+ }
+ return Optional.empty();
+ }
+}
diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/ReactivePageableExecutionUtils.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/ReactivePageableExecutionUtils.java
new file mode 100644
index 0000000..656414f
--- /dev/null
+++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/repository/ReactivePageableExecutionUtils.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.flyfish.framework.mongodb.repository;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.Pageable;
+import org.springframework.util.Assert;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+/**
+ * Support for query execution using {@link Pageable}. Using {@link ReactivePageableExecutionUtils} assumes that data
+ * queries are cheaper than {@code COUNT} queries and so some cases can take advantage of optimizations.
+ *
+ * @author Mark Paluch
+ * @since 3.3
+ */
+abstract class ReactivePageableExecutionUtils {
+
+ private ReactivePageableExecutionUtils() {}
+
+ /**
+ * Constructs a {@link Page} based on the given {@code content}, {@link Pageable} and {@link Mono} applying
+ * optimizations. The construction of {@link Page} omits a count query if the total can be determined based on the
+ * result size and {@link Pageable}.
+ *
+ * @param content must not be {@literal null}.
+ * @param pageable must not be {@literal null}.
+ * @param totalSupplier must not be {@literal null}.
+ * @return the {@link Page}.
+ */
+ public static Mono> getPage(List content, Pageable pageable, Mono totalSupplier) {
+
+ Assert.notNull(content, "Content must not be null!");
+ Assert.notNull(pageable, "Pageable must not be null!");
+ Assert.notNull(totalSupplier, "TotalSupplier must not be null!");
+
+ if (pageable.isUnpaged() || pageable.getOffset() == 0) {
+
+ if (pageable.isUnpaged() || pageable.getPageSize() > content.size()) {
+ return Mono.just(new PageImpl<>(content, pageable, content.size()));
+ }
+
+ return totalSupplier.map(total -> new PageImpl<>(content, pageable, total));
+ }
+
+ if (!content.isEmpty() && pageable.getPageSize() > content.size()) {
+ return Mono.just(new PageImpl<>(content, pageable, pageable.getOffset() + content.size()));
+ }
+
+ return totalSupplier.map(total -> new PageImpl<>(content, pageable, total));
+ }
+}
diff --git a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryQo.java b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryQo.java
index 0fc7c81..0b1c6ad 100644
--- a/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryQo.java
+++ b/flyfish-dict/src/main/java/com/flyfish/framework/dict/domain/DictionaryQo.java
@@ -1,7 +1,7 @@
package com.flyfish.framework.dict.domain;
-import com.flyfish.framework.builder.CriteriaBuilder;
import com.flyfish.framework.domain.base.NameLikeQo;
+import com.flyfish.framework.query.QueryDefinition;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
@@ -22,8 +22,8 @@ public class DictionaryQo extends NameLikeQo {
private List codes;
@Override
- public CriteriaBuilder criteriaBuilder() {
- return super.criteriaBuilder().with("codes", "code", CriteriaBuilder.Builders.IN);
+ public QueryDefinition queryBuilder() {
+ return super.queryBuilder().mutate().and(Dictionary::getCode).in(codes);
}
@Override
diff --git a/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/LogQo.java b/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/LogQo.java
index 49b578b..c42d9fb 100644
--- a/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/LogQo.java
+++ b/flyfish-logging/src/main/java/com/flyfish/framework/logging/domain/LogQo.java
@@ -1,8 +1,7 @@
package com.flyfish.framework.logging.domain;
-import com.flyfish.framework.builder.CriteriaBuilder;
-import com.flyfish.framework.domain.base.BaseQo;
import com.flyfish.framework.domain.base.NameLikeQo;
+import com.flyfish.framework.query.QueryDefinition;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.domain.Sort;
@@ -29,11 +28,14 @@ public class LogQo extends NameLikeQo {
private String type;
@Override
- public CriteriaBuilder criteriaBuilder() {
- return super.criteriaBuilder()
- .with("operator", CriteriaBuilder.Builders.LIKE)
- .with("type", "module", "success")
- .with("range", "startTime", CriteriaBuilder.Builders.DATE_RANGE);
+ public QueryDefinition queryBuilder() {
+ return super.queryBuilder()
+ .mutate()
+ .and(Log::getOperator).like(operator)
+ .and(Log::getType).eq(type)
+ .and(Log::getModule).eq(module)
+ .and(Log::getSuccess).eq(success)
+ .and(Log::getStartTime).between(range);
}
@Override
diff --git a/flyfish-user/src/main/java/com/flyfish/framework/domain/PermissionQo.java b/flyfish-user/src/main/java/com/flyfish/framework/domain/PermissionQo.java
index 98e5832..fb78326 100644
--- a/flyfish-user/src/main/java/com/flyfish/framework/domain/PermissionQo.java
+++ b/flyfish-user/src/main/java/com/flyfish/framework/domain/PermissionQo.java
@@ -1,9 +1,9 @@
package com.flyfish.framework.domain;
-import com.flyfish.framework.builder.CriteriaBuilder;
-import com.flyfish.framework.domain.tree.TreeQo;
import com.flyfish.framework.domain.po.Permission;
+import com.flyfish.framework.domain.tree.TreeQo;
+import com.flyfish.framework.query.QueryDefinition;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.domain.Sort;
@@ -27,7 +27,9 @@ public class PermissionQo extends TreeQo {
}
@Override
- public CriteriaBuilder criteriaBuilder() {
- return super.criteriaBuilder().with("admin", "type");
+ public QueryDefinition queryBuilder() {
+ return super.queryBuilder().mutate()
+ .and(Permission::isAdmin).eq(admin)
+ .and(Permission::getType).eq(type);
}
}
diff --git a/flyfish-user/src/main/java/com/flyfish/framework/domain/RoleQo.java b/flyfish-user/src/main/java/com/flyfish/framework/domain/RoleQo.java
index bc842dd..ff48ddc 100644
--- a/flyfish-user/src/main/java/com/flyfish/framework/domain/RoleQo.java
+++ b/flyfish-user/src/main/java/com/flyfish/framework/domain/RoleQo.java
@@ -1,8 +1,8 @@
package com.flyfish.framework.domain;
-import com.flyfish.framework.builder.CriteriaBuilder;
import com.flyfish.framework.domain.base.NameLikeQo;
import com.flyfish.framework.domain.po.Role;
+import com.flyfish.framework.query.QueryDefinition;
import lombok.Getter;
import lombok.Setter;
@@ -33,8 +33,11 @@ public class RoleQo extends NameLikeQo {
private List additions;
@Override
- public CriteriaBuilder criteriaBuilder() {
- return super.criteriaBuilder().with("admin", "system");
+ public QueryDefinition queryBuilder() {
+ return super.queryBuilder()
+ .mutate()
+ .and(Role::getAdmin).eq(admin)
+ .and(Role::isSystem).eq(system);
}
/**
diff --git a/flyfish-user/src/main/java/com/flyfish/framework/domain/UserQo.java b/flyfish-user/src/main/java/com/flyfish/framework/domain/UserQo.java
index 5dc29d9..fd667cb 100644
--- a/flyfish-user/src/main/java/com/flyfish/framework/domain/UserQo.java
+++ b/flyfish-user/src/main/java/com/flyfish/framework/domain/UserQo.java
@@ -1,10 +1,9 @@
package com.flyfish.framework.domain;
-import com.flyfish.framework.builder.CriteriaBuilder;
import com.flyfish.framework.domain.base.NameLikeQo;
import com.flyfish.framework.domain.po.User;
+import com.flyfish.framework.query.QueryDefinition;
import lombok.*;
-import org.springframework.data.mongodb.core.query.Criteria;
import java.util.List;
@@ -28,8 +27,14 @@ public class UserQo extends NameLikeQo {
private List departments;
@Override
- public CriteriaBuilder criteriaBuilder() {
- return super.criteriaBuilder().with("type", "username", "password", "phone", "status")
- .with("departments", "departments", CriteriaBuilder.Builders.IN);
+ public QueryDefinition queryBuilder() {
+ return super.queryBuilder()
+ .mutate()
+ .and(User::getType).eq(type)
+ .and(User::getUsername).eq(username)
+ .and(User::getPassword).eq(password)
+ .and(User::getPhone).eq(phone)
+ .and(User::getStatus).eq(status)
+ .and(User::getDepartments).in(departments);
}
}
diff --git a/flyfish-user/src/main/java/com/flyfish/framework/service/RoleService.java b/flyfish-user/src/main/java/com/flyfish/framework/service/RoleService.java
index e45f330..44e1d86 100644
--- a/flyfish-user/src/main/java/com/flyfish/framework/service/RoleService.java
+++ b/flyfish-user/src/main/java/com/flyfish/framework/service/RoleService.java
@@ -10,14 +10,13 @@ import com.flyfish.framework.domain.po.Permission;
import com.flyfish.framework.domain.po.Role;
import com.flyfish.framework.enums.RoleType;
import com.flyfish.framework.enums.UserType;
+import com.flyfish.framework.query.Queries;
+import com.flyfish.framework.query.Query;
+import com.flyfish.framework.repository.ReactiveEntityOperations;
import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.data.mongodb.core.ReactiveMongoOperations;
-import org.springframework.data.mongodb.core.query.Criteria;
-import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -32,7 +31,7 @@ public class RoleService extends BaseReactiveServiceImpl {
private final PermissionService permissionService;
- private final ReactiveMongoOperations reactiveMongoOperations;
+ private final ReactiveEntityOperations reactiveEntityOperations;
/**
* 如果是管理员,设置拥有所有权限
@@ -69,9 +68,8 @@ public class RoleService extends BaseReactiveServiceImpl {
* @return 结果
*/
private Mono> getOwnedIds(IUser user) {
- Query query = Query.query(Criteria.where("creatorId").is(user.getId()));
- query.fields().include("_id");
- return reactiveMongoOperations.find(query, Role.class).map(Domain::getId).collect(Collectors.toSet());
+ Query query = Query.query(Queries.where(Role::getCreatorId).eq(user.getId())).select(Role::getId);
+ return reactiveEntityOperations.find(query, Role.class).map(Domain::getId).collect(Collectors.toSet());
}
/**
diff --git a/flyfish-web/src/main/java/com/flyfish/framework/beans/enums/ValidationCandidate.java b/flyfish-web/src/main/java/com/flyfish/framework/beans/enums/ValidationCandidate.java
index 0fe49a1..1f18fe6 100644
--- a/flyfish-web/src/main/java/com/flyfish/framework/beans/enums/ValidationCandidate.java
+++ b/flyfish-web/src/main/java/com/flyfish/framework/beans/enums/ValidationCandidate.java
@@ -78,7 +78,7 @@ public enum ValidationCandidate {
ID_CARD((annotation, validation) -> validation.setValidator("idCard"), IdCard.class),
// 唯一字段
UNIQUE_FIELD((annotation, validation) -> validation.setValidator("uniqueField")
- .prop("field", annotation.getString("value")), UniqueField.class);
+ .prop("column", annotation.getString("value")), UniqueField.class);
private final BiConsumer, BeanValidation> mapper;
From 4742c1d50c48921e72ce6cc04ca8f4e9744e2000 Mon Sep 17 00:00:00 2001
From: wangyu <727842003@qq.com>
Date: Fri, 5 Aug 2022 15:56:40 +0800
Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=E4=BF=9D=E8=AF=81=E6=95=B4?=
=?UTF-8?q?=E4=BD=93=E7=BB=93=E6=9E=84=E7=A8=B3=E5=AE=9A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../framework/adaptor/CriteriaAdaptors.java | 34 ------
.../adaptor/spi/CriteriaAdaptorFactory.java | 26 -----
.../com/flyfish/framework/query/Queries.java | 46 +++++---
.../flyfish/framework/query/QueryChain.java | 2 +-
.../framework/{adaptor => query}/README.md | 0
.../{ => query}/adaptor/CriteriaAdaptor.java | 2 +-
.../query/spi/QueryChainFactory.java | 29 +++++
.../factory/MongoLambdaQueryFactory.java | 38 ++++++
.../query/factory/MongoNamedQueryFactory.java | 35 ++++++
.../query/impl/MongoLambdaQueryChain.java | 106 +++++++++++++++++
.../query/impl/MongoNamedQueryChain.java | 107 +++++++++++++++++
.../query/impl/MongoQueryDefinition.java | 42 +++++++
.../main/resources/META-INF/spring.factories | 3 +
.../adaptor/R2DbcCriteriaAdaptorFactory.java | 34 ------
.../factory/R2dbcLambdaQueryFactory.java | 36 ++++++
.../query/factory/R2dbcNamedQueryFactory.java | 35 ++++++
.../query/impl/R2dbcLambdaQueryChain.java | 109 ++++++++++++++++++
.../query/impl/R2dbcNamedQueryChain.java | 107 +++++++++++++++++
.../query/impl/R2dbcQueryDefinition.java | 42 +++++++
.../main/resources/META-INF/spring.factories | 3 +
20 files changed, 723 insertions(+), 113 deletions(-)
delete mode 100644 flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/CriteriaAdaptors.java
delete mode 100644 flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/spi/CriteriaAdaptorFactory.java
rename flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/{adaptor => query}/README.md (100%)
rename flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/{ => query}/adaptor/CriteriaAdaptor.java (98%)
create mode 100644 flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryChainFactory.java
create mode 100644 flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoLambdaQueryFactory.java
create mode 100644 flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoNamedQueryFactory.java
create mode 100644 flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoLambdaQueryChain.java
create mode 100644 flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoNamedQueryChain.java
create mode 100644 flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoQueryDefinition.java
create mode 100644 flyfish-data/flyfish-data-mongodb/src/main/resources/META-INF/spring.factories
delete mode 100644 flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/adaptor/R2DbcCriteriaAdaptorFactory.java
create mode 100644 flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/factory/R2dbcLambdaQueryFactory.java
create mode 100644 flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/factory/R2dbcNamedQueryFactory.java
create mode 100644 flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcLambdaQueryChain.java
create mode 100644 flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcNamedQueryChain.java
create mode 100644 flyfish-data/flyfish-data-r2dbc/src/main/java/com/flyfish/framework/r2dbc/query/impl/R2dbcQueryDefinition.java
create mode 100644 flyfish-data/flyfish-data-r2dbc/src/main/resources/META-INF/spring.factories
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/CriteriaAdaptors.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/CriteriaAdaptors.java
deleted file mode 100644
index c3771ca..0000000
--- a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/CriteriaAdaptors.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.flyfish.framework.adaptor;
-
-import com.flyfish.framework.adaptor.spi.CriteriaAdaptorFactory;
-import org.springframework.core.io.support.SpringFactoriesLoader;
-import org.springframework.dao.InvalidDataAccessApiUsageException;
-
-import java.util.List;
-
-/**
- * 可以通过该工具类快速创建适配器
- *
- * @author wangyu
- */
-public final class CriteriaAdaptors {
-
- private static final List FACTORIES =
- SpringFactoriesLoader.loadFactories(CriteriaAdaptorFactory.class, null);
-
- public static CriteriaAdaptor getAdaptor() {
- return FACTORIES.stream()
- .findFirst()
- .map(CriteriaAdaptorFactory::produce)
- .orElseThrow(() -> new InvalidDataAccessApiUsageException("未实现当前查询的适配工厂!"));
- }
-
-
- public static CriteriaAdaptor getAdaptor(Object criteria) {
- return FACTORIES.stream()
- .filter(factory -> factory.criteriaType().isAssignableFrom(criteria.getClass()))
- .findFirst()
- .map(CriteriaAdaptorFactory::produce)
- .orElseThrow(() -> new InvalidDataAccessApiUsageException("未实现当前查询的适配工厂!"));
- }
-}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/spi/CriteriaAdaptorFactory.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/spi/CriteriaAdaptorFactory.java
deleted file mode 100644
index 192fe7a..0000000
--- a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/spi/CriteriaAdaptorFactory.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.flyfish.framework.adaptor.spi;
-
-import com.flyfish.framework.adaptor.CriteriaAdaptor;
-
-/**
- * 查询适配器
- * 基于spi提供实现类,最终返回对应的
- *
- * @author wangyu
- */
-public interface CriteriaAdaptorFactory {
-
- /**
- * 生产适配器
- *
- * @return 结果
- */
- CriteriaAdaptor produce();
-
- /**
- * 查询类型
- *
- * @return 结果
- */
- Class> criteriaType();
-}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Queries.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Queries.java
index 4980664..84462fb 100644
--- a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Queries.java
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/Queries.java
@@ -1,9 +1,12 @@
package com.flyfish.framework.query;
import com.flyfish.framework.domain.base.Domain;
-import com.flyfish.framework.domain.base.Qo;
+import com.flyfish.framework.query.spi.QueryChainFactory;
+import com.flyfish.framework.query.support.DomainFunction;
+import org.springframework.core.io.support.SpringFactoriesLoader;
+import org.springframework.dao.InvalidDataAccessApiUsageException;
-import java.util.function.Function;
+import java.util.List;
/**
* 查询工具类
@@ -15,15 +18,8 @@ import java.util.function.Function;
*/
public final class Queries {
- /**
- * 通过qo快速创建一个绑定上下文
- *
- * @param qo 查询实体
- * @return 结果
- */
- public static NamedQueryChain of(Qo> qo) {
- return (NamedQueryChain) new Object();
- }
+ private static final List FACTORIES =
+ SpringFactoriesLoader.loadFactories(QueryChainFactory.class, null);
/**
* 创建基于字符串字段名的查询
@@ -32,7 +28,8 @@ public final class Queries {
* @return 结果
*/
public static QueryCondition where(String column) {
- return (QueryCondition) new Object();
+ NamedQueryChain chain = getFactory(NamedQueryChain.class).produce();
+ return chain.and(column);
}
/**
@@ -41,8 +38,9 @@ public final class Queries {
* @param getter 列引用
* @return 结果
*/
- public static QueryCondition> where(Function getter) {
- return (QueryCondition>) new Object();
+ public static QueryCondition> where(DomainFunction getter) {
+ LambdaQueryChain chain = getFactory(LambdaQueryChain.class).produce();
+ return chain.and(getter);
}
/**
@@ -52,7 +50,8 @@ public final class Queries {
* @return 结果
*/
public static NamedQueryChain within(NamedQueryChain chain) {
- return (NamedQueryChain) new Object();
+ NamedQueryChain created = getFactory(LambdaQueryChain.class).produce();
+ return created.and(chain);
}
@@ -63,7 +62,21 @@ public final class Queries {
* @return 结果
*/
public static LambdaQueryChain within(LambdaQueryChain chain) {
- return (LambdaQueryChain) new Object();
+ LambdaQueryChain created = getFactory(LambdaQueryChain.class).produce();
+ return created.and(chain);
+ }
+
+ /**
+ * 通过特定产出类获取工厂
+ *
+ * @param targetType 目标类型
+ * @return 匹配的工厂
+ */
+ private static QueryChainFactory getFactory(Class> targetType) {
+ return FACTORIES.stream()
+ .filter(factory -> factory.supports(targetType))
+ .findFirst()
+ .orElseThrow(() -> new InvalidDataAccessApiUsageException("未实现当前查询的适配工厂!"));
}
/**
@@ -81,5 +94,4 @@ public final class Queries {
LEFT, RIGHT, ALL
}
-
}
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryChain.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryChain.java
index ccc8899..e0ed7ed 100644
--- a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryChain.java
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/QueryChain.java
@@ -28,7 +28,7 @@ public interface QueryChain, P> extends QueryDefiniti
* 直接拼接提供者,此处懒加载,最终build才会执行
*
* @param supplier 提供者
- * @param 泛型,支持其他类型的链
+ * @param 泛型,支持其他类型的链
* @return 结果
*/
> C and(Supplier> supplier);
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/README.md b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/README.md
similarity index 100%
rename from flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/README.md
rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/README.md
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/CriteriaAdaptor.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/adaptor/CriteriaAdaptor.java
similarity index 98%
rename from flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/CriteriaAdaptor.java
rename to flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/adaptor/CriteriaAdaptor.java
index 3c15229..4628a40 100644
--- a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/adaptor/CriteriaAdaptor.java
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/adaptor/CriteriaAdaptor.java
@@ -1,4 +1,4 @@
-package com.flyfish.framework.adaptor;
+package com.flyfish.framework.query.adaptor;
import org.bson.BsonRegularExpression;
import org.springframework.data.domain.Example;
diff --git a/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryChainFactory.java b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryChainFactory.java
new file mode 100644
index 0000000..5ed27e5
--- /dev/null
+++ b/flyfish-data/flyfish-data-common/src/main/java/com/flyfish/framework/query/spi/QueryChainFactory.java
@@ -0,0 +1,29 @@
+package com.flyfish.framework.query.spi;
+
+import com.flyfish.framework.query.QueryChain;
+
+/**
+ * 查询链创建抽象工厂
+ * 基于spi提供实现类,最终返回真正实例化的内容
+ * 根据引入的jar包自动加载,无需手动处理
+ *
+ * @author wangyu
+ */
+public interface QueryChainFactory> {
+
+ /**
+ * 生产适配器
+ * 此接口为高度抽象接口,目的是兼容更多的查询链类型,便于后续扩展
+ *
+ * @return 生产结果
+ */
+ C produce();
+
+ /**
+ * 判定是否支持特定的实例类型
+ *
+ * @param targetType 工厂目标类型
+ * @return 是否匹配
+ */
+ boolean supports(Class> targetType);
+}
diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoLambdaQueryFactory.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoLambdaQueryFactory.java
new file mode 100644
index 0000000..9e6b9a3
--- /dev/null
+++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoLambdaQueryFactory.java
@@ -0,0 +1,38 @@
+package com.flyfish.framework.mongodb.query.factory;
+
+import com.flyfish.framework.domain.base.Domain;
+import com.flyfish.framework.mongodb.query.impl.MongoLambdaQueryChain;
+import com.flyfish.framework.mongodb.query.impl.MongoNamedQueryChain;
+import com.flyfish.framework.query.LambdaQueryChain;
+import com.flyfish.framework.query.QueryChain;
+import com.flyfish.framework.query.spi.QueryChainFactory;
+
+/**
+ * mongo lambda 查询工厂
+ *
+ * @author wangyu
+ */
+public class MongoLambdaQueryFactory implements QueryChainFactory> {
+
+ /**
+ * 生产适配器
+ * 此接口为高度抽象接口,目的是兼容更多的查询链类型,便于后续扩展
+ *
+ * @return 生产结果
+ */
+ @Override
+ public LambdaQueryChain produce() {
+ return new MongoLambdaQueryChain<>();
+ }
+
+ /**
+ * 判定是否支持特定的实例类型
+ *
+ * @param targetType 工厂目标类型
+ * @return 是否匹配
+ */
+ @Override
+ public boolean supports(Class> targetType) {
+ return targetType.isAssignableFrom(MongoLambdaQueryChain.class);
+ }
+}
diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoNamedQueryFactory.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoNamedQueryFactory.java
new file mode 100644
index 0000000..92444e7
--- /dev/null
+++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/factory/MongoNamedQueryFactory.java
@@ -0,0 +1,35 @@
+package com.flyfish.framework.mongodb.query.factory;
+
+import com.flyfish.framework.mongodb.query.impl.MongoNamedQueryChain;
+import com.flyfish.framework.query.NamedQueryChain;
+import com.flyfish.framework.query.spi.QueryChainFactory;
+
+/**
+ * mongo名称查询工厂
+ *
+ * @author wangyu
+ */
+public class MongoNamedQueryFactory implements QueryChainFactory {
+
+ /**
+ * 生产适配器
+ * 此接口为高度抽象接口,目的是兼容更多的查询链类型,便于后续扩展
+ *
+ * @return 生产结果
+ */
+ @Override
+ public NamedQueryChain produce() {
+ return new MongoNamedQueryChain();
+ }
+
+ /**
+ * 判定是否支持特定的实例类型
+ *
+ * @param targetType 工厂目标类型
+ * @return 是否匹配
+ */
+ @Override
+ public boolean supports(Class> targetType) {
+ return targetType.isAssignableFrom(MongoNamedQueryChain.class);
+ }
+}
diff --git a/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoLambdaQueryChain.java b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoLambdaQueryChain.java
new file mode 100644
index 0000000..1d64bcf
--- /dev/null
+++ b/flyfish-data/flyfish-data-mongodb/src/main/java/com/flyfish/framework/mongodb/query/impl/MongoLambdaQueryChain.java
@@ -0,0 +1,106 @@
+package com.flyfish.framework.mongodb.query.impl;
+
+import com.flyfish.framework.domain.base.Domain;
+import com.flyfish.framework.query.*;
+import com.flyfish.framework.query.support.DomainFunction;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * mongodb实现的基于lambda的查询链
+ *
+ * @author wangyu
+ */
+public class MongoLambdaQueryChain extends MongoQueryDefinition implements LambdaQueryChain {
+
+ /**
+ * 以且连接下一个字段
+ *
+ * @param column 列
+ * @return 查询条件
+ */
+ @Override
+ public QueryCondition> and(DomainFunction column) {
+ return null;
+ }
+
+ /**
+ * 直接拼接提供者,此处懒加载,最终build才会执行
+ *
+ * @param supplier 提供者
+ * @return 结果
+ */
+ @Override
+ public > LambdaQueryChain and(Supplier> supplier) {
+ return null;
+ }
+
+ /**
+ * 条件列表
+ *
+ * @param chain 多个条件们
+ * @return 结果
+ */
+ @Override
+ public LambdaQueryChain and(LambdaQueryChain chain) {
+ return null;
+ }
+
+ /**
+ * 多个嵌套子条件列表
+ *
+ * @param lambdaQueryChains 多条链
+ * @param combinator 各个链条之间的连接方式
+ * @return 结果
+ */
+ @Override
+ public LambdaQueryChain and(List> lambdaQueryChains, Queries.Combinator combinator) {
+ return null;
+ }
+
+ /**
+ * 以或连接下一个字段
+ *
+ * @param column 列
+ * @return 查询条件
+ */
+ @Override
+ public QueryCondition> or(DomainFunction