feat: 完善核心逻辑

This commit is contained in:
wangyu 2024-06-24 23:48:29 +08:00
parent 4cceda5734
commit c662fa1c65
23 changed files with 347 additions and 1151 deletions

View File

@ -39,6 +39,11 @@ public class ModuleDelegateService {
// 审批的服务们
private Map<String, BaseReactiveService<ApprovalDomain>> approvalServices;
private String getModuleName(BaseReactiveService<ApprovalDomain> service) {
return ReflectionUtils.getGenericType(service.getClass()).map(Class::getSimpleName)
.orElseThrow(() -> new InvalidBusinessException("系统模块名称抽取失败!"));
}
@Autowired
@SuppressWarnings("all")
public void setApprovalServices(ObjectProvider<BaseReactiveService> services) {
@ -47,7 +52,7 @@ public class ModuleDelegateService {
.map(clazz -> ClassUtils.isAssignable(clazz, ApprovalDomain.class))
.orElse(false))
.map(service -> (BaseReactiveService<ApprovalDomain>) service)
.collect(Collectors.toMap(s -> s.getEntityInformation().getCollectionName(), s -> s));
.collect(Collectors.toMap(this::getModuleName, s -> s));
}
/**

View File

@ -5,8 +5,7 @@ import com.flyfish.framework.query.*;
import com.flyfish.framework.query.support.DomainFunction;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
/**
* 默认的查询修改逻辑
@ -24,6 +23,25 @@ public class DefaultQueryMutation implements QueryMutation {
private final boolean within;
/**
* 根据实际的参数合并查询链
*
* @param newChain 新链
* @param <P> 参数类型
* @param <C> 查询链类型
* @return 结果
*/
private <P, C extends QueryChain<C, P>> C merge(C newChain) {
if (within) {
// 内联模式旧条件不修改
newChain.and(Collections.singletonList(previous));
} else {
// 修改模式直接修改
previous.and(newChain);
}
return newChain;
}
/**
* 以lambda的形式修改
* 注意如果之前用过lambda的形式此处应该校验类型
@ -33,11 +51,7 @@ public class DefaultQueryMutation implements QueryMutation {
*/
@Override
public <T extends Domain> QueryCondition<LambdaQueryChain<T>> and(DomainFunction<T> getter) {
LambdaQueryChain<T> newChain = new DefaultLambdaQueryChain<>();
QueryCondition<LambdaQueryChain<T>> condition = newChain.and(getter);
List<QueryChain<?, ?>> chains = Arrays.asList(previous, newChain);
previous.and(chains);
return condition;
return merge(new DefaultLambdaQueryChain<T>()).and(getter);
}
/**
@ -48,7 +62,7 @@ public class DefaultQueryMutation implements QueryMutation {
*/
@Override
public QueryCondition<NamedQueryChain> and(String column) {
return null;
return merge(new DefaultNamedQueryChain()).and(column);
}
/**
@ -59,7 +73,7 @@ public class DefaultQueryMutation implements QueryMutation {
*/
@Override
public <T extends Domain> LambdaQueryChain<T> and(LambdaQueryChain<T> chain) {
return null;
return merge(chain);
}
/**
@ -70,7 +84,7 @@ public class DefaultQueryMutation implements QueryMutation {
*/
@Override
public NamedQueryChain and(NamedQueryChain chain) {
return null;
return merge(chain);
}
/**
@ -82,7 +96,7 @@ public class DefaultQueryMutation implements QueryMutation {
*/
@Override
public <T extends Domain> QueryCondition<LambdaQueryChain<T>> or(DomainFunction<T> getter) {
return null;
return merge(new DefaultLambdaQueryChain<T>()).or(getter);
}
/**
@ -93,7 +107,7 @@ public class DefaultQueryMutation implements QueryMutation {
*/
@Override
public QueryCondition<NamedQueryChain> or(String column) {
return null;
return merge(new DefaultNamedQueryChain()).or(column);
}
/**
@ -104,7 +118,7 @@ public class DefaultQueryMutation implements QueryMutation {
*/
@Override
public <T extends Domain> LambdaQueryChain<T> or(LambdaQueryChain<T> chain) {
return null;
return merge(chain);
}
/**
@ -115,6 +129,6 @@ public class DefaultQueryMutation implements QueryMutation {
*/
@Override
public NamedQueryChain or(NamedQueryChain chain) {
return null;
return merge(chain);
}
}

View File

@ -11,7 +11,6 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.index.Indexed;
import javax.persistence.Index;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;

View File

@ -0,0 +1,39 @@
package com.flyfish.framework.mongodb.query;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.mongodb.query.adaptor.MongoCriteriaAdaptor;
import com.flyfish.framework.mongodb.query.converter.MongoQueryConverter;
import com.flyfish.framework.query.spi.QueryFactory;
import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor;
import com.flyfish.framework.query.spi.converter.QueryConverter;
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.repository.core.EntityInformation;
/**
* mongo查询工厂
*
* @author wangyu
*/
public class MongoQueryFactory implements QueryFactory<Criteria, Query> {
private final CriteriaAdaptor<Criteria> adaptor = new MongoCriteriaAdaptor();
private final QueryConverter<Query> converter = new MongoQueryConverter(adaptor);
@Override
public boolean supports(EntityInformation<? extends Domain, String> entity) {
return entity instanceof MongoEntityInformation;
}
@Override
public QueryConverter<Query> getConverter() {
return converter;
}
@Override
public CriteriaAdaptor<Criteria> getAdaptor() {
return adaptor;
}
}

View File

@ -0,0 +1,103 @@
package com.flyfish.framework.mongodb.query.adaptor;
import com.flyfish.framework.query.Queries;
import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import java.util.Collection;
import java.util.List;
public class MongoCriteriaAdaptor implements CriteriaAdaptor<Criteria> {
@Override
public Criteria and(Criteria first, Criteria other) {
return first.andOperator(other);
}
@Override
public Criteria or(Criteria first, Criteria other) {
return first.orOperator(other);
}
@Override
public Criteria eq(String column, Object value) {
return Criteria.where(column).is(value);
}
@Override
public Criteria hasId(String column, Object value) {
return Criteria.where(column + ".$id").is(new ObjectId(String.valueOf(value)));
}
@Override
public Criteria has(String column, Object value) {
return Criteria.where(column).is(value);
}
@Override
public Criteria ne(String column, Object value) {
return Criteria.where(column).ne(value);
}
@Override
public Criteria between(String column, List<?> items) {
return Criteria.where(column).gte(items.get(0)).lte(items.get(1));
}
@Override
public Criteria like(String column, String keyword, Queries.Direction direction) {
// 匹配开头
if (direction == Queries.Direction.LEFT) {
keyword = "^" + keyword;
} else if (direction == Queries.Direction.RIGHT) {
keyword = keyword + "$";
}
return Criteria.where(column).regex(keyword);
}
@Override
public Criteria isNull(String column) {
return Criteria.where(column).isNull();
}
@Override
public Criteria lt(String column, Object value) {
return Criteria.where(column).lt(value);
}
@Override
public Criteria lte(String column, Object value) {
return Criteria.where(column).lte(value);
}
@Override
public Criteria gt(String column, Object value) {
return Criteria.where(column).gt(value);
}
@Override
public Criteria gte(String column, Object value) {
return Criteria.where(column).gte(value);
}
@Override
public Criteria in(String column, Collection<?> values) {
return Criteria.where(column).in(values);
}
@Override
public Criteria in(String column, Object... values) {
return Criteria.where(column).in(values);
}
@Override
public Criteria nin(String column, Object... values) {
return Criteria.where(column).nin(values);
}
@Override
public Criteria nin(String column, Collection<?> values) {
return Criteria.where(column).nin(values);
}
}

View File

@ -1,25 +1,16 @@
package com.flyfish.framework.mongodb.query.converter;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor;
import com.flyfish.framework.query.spi.converter.QueryConverter;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
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.repository.core.EntityInformation;
@RequiredArgsConstructor
public class MongoQueryConverter implements QueryConverter<Query> {
/**
* 判断是否支持实体
*
* @param entity 实体信息
* @return 结果
*/
@Override
public boolean supports(EntityInformation<? extends Domain, String> entity) {
return entity instanceof MongoEntityInformation;
}
private final CriteriaAdaptor<Criteria> adaptor;
/**
* 转换查询
@ -62,7 +53,7 @@ public class MongoQueryConverter implements QueryConverter<Query> {
}
// 如果存在查询定义直接使用查询定义
if (null != query.getDefinition()) {
return query.getDefinition().build();
return query.getDefinition().build(adaptor);
}
return null;
}

View File

@ -1,36 +0,0 @@
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.query.LambdaQueryChain;
import com.flyfish.framework.query.spi.QueryChainFactory;
/**
* mongo lambda 查询工厂
*
* @author wangyu
*/
public class MongoLambdaQueryFactory<T extends Domain> implements QueryChainFactory<LambdaQueryChain<T>> {
/**
* 生产适配器
* 此接口为高度抽象接口目的是兼容更多的查询链类型便于后续扩展
*
* @return 生产结果
*/
@Override
public LambdaQueryChain<T> produce() {
return new MongoLambdaQueryChain<>();
}
/**
* 判定是否支持特定的实例类型
*
* @param targetType 工厂目标类型
* @return 是否匹配
*/
@Override
public boolean supports(Class<?> targetType) {
return targetType.isAssignableFrom(MongoLambdaQueryChain.class);
}
}

View File

@ -1,35 +0,0 @@
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<NamedQueryChain> {
/**
* 生产适配器
* 此接口为高度抽象接口目的是兼容更多的查询链类型便于后续扩展
*
* @return 生产结果
*/
@Override
public NamedQueryChain produce() {
return new MongoNamedQueryChain();
}
/**
* 判定是否支持特定的实例类型
*
* @param targetType 工厂目标类型
* @return 是否匹配
*/
@Override
public boolean supports(Class<?> targetType) {
return targetType.isAssignableFrom(MongoNamedQueryChain.class);
}
}

View File

@ -1,239 +0,0 @@
package com.flyfish.framework.mongodb.query.impl;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.query.LambdaQueryChain;
import com.flyfish.framework.query.Queries;
import com.flyfish.framework.query.QueryChain;
import com.flyfish.framework.query.QueryCondition;
import com.flyfish.framework.query.support.DomainFunction;
import lombok.RequiredArgsConstructor;
import java.util.Collection;
import java.util.List;
import java.util.function.Supplier;
/**
* mongodb实现的基于lambda的查询链
*
* @author wangyu
*/
public class MongoLambdaQueryChain<T extends Domain> extends MongoQueryDefinition implements LambdaQueryChain<T> {
/**
* 以且连接下一个字段
*
* @param column
* @return 查询条件
*/
@Override
public QueryCondition<LambdaQueryChain<T>> and(DomainFunction<T> column) {
return null;
}
/**
* 直接拼接提供者此处懒加载最终build才会执行
*
* @param supplier 提供者
* @return 结果
*/
@Override
public <V extends QueryChain<V, ?>> LambdaQueryChain<T> and(Supplier<QueryChain<V, ?>> supplier) {
return null;
}
/**
* 条件列表
*
* @param chain 多个条件们
* @return 结果
*/
@Override
public LambdaQueryChain<T> and(LambdaQueryChain<T> chain) {
return null;
}
/**
* 多个嵌套子条件列表
*
* @param lambdaQueryChains 多条链
* @param combinator 各个链条之间的连接方式
* @return 结果
*/
@Override
public LambdaQueryChain<T> and(List<LambdaQueryChain<T>> lambdaQueryChains, Queries.Combinator combinator) {
return null;
}
/**
* 以或连接下一个字段
*
* @param column
* @return 查询条件
*/
@Override
public QueryCondition<LambdaQueryChain<T>> or(DomainFunction<T> column) {
return null;
}
/**
* 以或连接条件列表
*
* @param chain 多个条件们
* @return 结果
*/
@Override
public LambdaQueryChain<T> or(LambdaQueryChain<T> chain) {
return null;
}
/**
* 以或连接嵌套多个子条件列表
*
* @param lambdaQueryChains 多条链
* @param combinator 各个链条之间的连接方式
* @return 结果
*/
@Override
public LambdaQueryChain<T> or(List<LambdaQueryChain<T>> lambdaQueryChains, Queries.Combinator combinator) {
return null;
}
/**
* 直接拼接提供者此处懒加载最终build才会执行
*
* @param supplier 提供者
* @return 结果
*/
@Override
public <V extends QueryChain<V, ?>> LambdaQueryChain<T> or(Supplier<QueryChain<V, ?>> supplier) {
return null;
}
/**
* 用于lambda的条件拼接
*/
@RequiredArgsConstructor
class LambdaQueryCondition implements QueryCondition<LambdaQueryChain<T>> {
private final DomainFunction<T> field;
/**
* 相等判定
*
* @param value
* @return 结果
*/
@Override
public LambdaQueryChain<T> eq(Object value) {
criteria.and("").is(value);
return MongoLambdaQueryChain.this;
}
/**
* 判定某列的值中存在指定值特指json array数据类型且子类型中带有id的场景
* 用于兼容mongodb查询mysql查询使用JSON_CONTAINS进行判定
* 当且仅当mongodb会拼接.$idmysql一律匹配id字段
* <p>
* 等价于 .eq(value)
*
* @param value
* @return 结果
*/
@Override
public LambdaQueryChain<T> hasId(Object value) {
return null;
}
/**
* 对于mongodb自动处理对于关系型数据库代表json array中是否包含对应值值仅支持基本数据类型
* <p>
* 等价于 .eq(value)
*
* @param value 基本数据类型的值
* @return 结果
*/
@Override
public LambdaQueryChain<T> has(Object value) {
return null;
}
/**
* 不等判定
*
* @param value
* @return 结果
*/
@Override
public LambdaQueryChain<T> ne(Object value) {
return null;
}
/**
* 值介于两者之间
*
* @param items 双值列表
* @return 结果
*/
@Override
public LambdaQueryChain<T> between(List<?> items) {
return null;
}
/**
* 模糊匹配这里是全模糊
*
* @param keyword 查询关键字
* @return 结果
*/
@Override
public LambdaQueryChain<T> like(String keyword) {
return null;
}
/**
* 根据指定的方向进行模糊查询
*
* @param keyword 关键字
* @param direction 方向可以匹配开头和结尾
* @return 结果
*/
@Override
public LambdaQueryChain<T> like(String keyword, Queries.Direction direction) {
return null;
}
/**
* 判定为空
*
* @return 结果
*/
@Override
public LambdaQueryChain<T> isNull() {
return null;
}
/**
* 包含在内
*
* @param list 集合
* @return 结果
*/
@Override
public LambdaQueryChain<T> in(Collection<?> list) {
return null;
}
/**
* 包含在内
* 注意需要根据字段类型推断
* 如果是json数组需要进行双向匹配
*
* @param values 值们
* @return 结果
*/
@Override
public LambdaQueryChain<T> in(Object... values) {
return null;
}
}
}

View File

@ -1,318 +0,0 @@
package com.flyfish.framework.mongodb.query.impl;
import com.flyfish.framework.query.NamedQueryChain;
import com.flyfish.framework.query.Queries;
import com.flyfish.framework.query.QueryChain;
import com.flyfish.framework.query.QueryCondition;
import com.flyfish.framework.query.holder.QueryChainHolder;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import java.util.Collection;
import java.util.List;
import java.util.function.Supplier;
/**
* mongodb实现的基于名称的查询链
* 这里需要一个机制能够将父类上下文带入并且能够知晓实际查询对象的连接方式
* 这就需要用到观察者模式以便延迟执行将动作作为事件发布到对象里在具体的执行时机再进行fire
* 于是乎我们便可以优雅而且低耦合的实现链式了
*
* @author wangyu
*/
public class MongoNamedQueryChain extends MongoQueryDefinition implements NamedQueryChain {
/**
* 以且连接下一个字段
*
* @param column
* @return 查询条件
*/
@Override
public QueryCondition<NamedQueryChain> and(String column) {
and();
return new NamedQueryCondition(column);
}
/**
* 直接拼接提供者此处懒加载最终build才会执行
*
* @param supplier 提供者
* @return 结果
*/
@Override
public <V extends QueryChain<V, ?>> NamedQueryChain and(Supplier<QueryChain<V, ?>> supplier) {
and().with(() -> supplier.get().build());
return this;
}
/**
* 条件列表
*
* @param chain 多个条件们
* @return 结果
*/
@Override
public NamedQueryChain and(NamedQueryChain chain) {
and().with(chain::build);
return this;
}
/**
* 多个嵌套子条件列表
*
* @param chains 多条链
* @param combinator 各个链条之间的连接方式
* @return 结果
*/
@Override
public NamedQueryChain and(List<NamedQueryChain> chains, Queries.Combinator combinator) {
return and(combine(chains, combinator));
}
/**
* 以或连接下一个字段
*
* @param column
* @return 查询条件
*/
@Override
public QueryCondition<NamedQueryChain> or(String column) {
or();
return new NamedQueryCondition(column);
}
/**
* 以或连接条件列表
*
* @param chain 多个条件们
* @return 结果
*/
@Override
public NamedQueryChain or(NamedQueryChain chain) {
or().with(chain::build);
return this;
}
/**
* 以或连接嵌套多个子条件列表
*
* @param chains 多条链
* @param combinator 各个链条之间的连接方式
* @return 结果
*/
@Override
public NamedQueryChain or(List<NamedQueryChain> chains, Queries.Combinator combinator) {
return or(combine(chains, combinator));
}
/**
* 直接拼接提供者此处懒加载最终build才会执行
*
* @param supplier 提供者
* @return 结果
*/
@Override
public <V extends QueryChain<V, ?>> NamedQueryChain or(Supplier<QueryChain<V, ?>> supplier) {
or().with(() -> supplier.get().build());
return this;
}
/**
* 以且的关系进行拼接
*
* @return 结果
*/
private QueryChainHolder<Criteria> and() {
return holder.link(Criteria::andOperator);
}
/**
* 以或的关系进行拼接
*
* @return 结果
*/
private QueryChainHolder<Criteria> or() {
return holder.link(Criteria::orOperator);
}
/**
* 结合多个查询链并根据组合方式进行处理
*
* @param chains 查询链集合
* @param combinator 组合方式
* @return 结果
*/
private NamedQueryChain combine(List<NamedQueryChain> chains, Queries.Combinator combinator) {
return chains.stream().reduce((left, right) -> combinator == Queries.Combinator.OR ? left.or(right) : left.and(right))
.orElse(new MongoNamedQueryChain());
}
/**
* 条件操作实现
*
* @author wangyu
*/
@RequiredArgsConstructor
class NamedQueryCondition implements QueryCondition<NamedQueryChain> {
private final String column;
/**
* 相等判定
*
* @param value
* @return 结果
*/
@Override
public NamedQueryChain eq(Object value) {
if (null != value) {
holder.with(Criteria.where(column).is(value));
}
return MongoNamedQueryChain.this;
}
/**
* 判定某列的值中存在指定值特指json array数据类型且子类型中带有id的场景
* 用于兼容mongodb查询mysql查询使用JSON_CONTAINS进行判定
* 当且仅当mongodb会拼接.$idmysql一律匹配id字段
* <p>
* 等价于 .eq(value)
*
* @param value
* @return 结果
*/
@Override
public NamedQueryChain hasId(Object value) {
if (null != value) {
holder.with(Criteria.where(column + ".$id").is(new ObjectId(String.valueOf(value))));
}
return MongoNamedQueryChain.this;
}
/**
* 对于mongodb自动处理对于关系型数据库代表json array中是否包含对应值值仅支持基本数据类型
* <p>
* 等价于 .eq(value)
*
* @param value 基本数据类型的值
* @return 结果
*/
@Override
public NamedQueryChain has(Object value) {
if (null != value) {
holder.with(Criteria.where(column).is(value));
}
return MongoNamedQueryChain.this;
}
/**
* 不等判定
*
* @param value
* @return 结果
*/
@Override
public NamedQueryChain ne(Object value) {
if (null != value) {
holder.with(Criteria.where(column).ne(value));
}
return MongoNamedQueryChain.this;
}
/**
* 值介于两者之间
*
* @param items 双值列表
* @return 结果
*/
@Override
public NamedQueryChain between(List<?> items) {
if (CollectionUtils.size(items) == 2) {
holder.with(Criteria.where(column).gte(items.get(0)).lte(items.get(1)));
}
return MongoNamedQueryChain.this;
}
/**
* 模糊匹配这里是全模糊
*
* @param keyword 查询关键字
* @return 结果
*/
@Override
public NamedQueryChain like(String keyword) {
if (StringUtils.isNotBlank(keyword)) {
holder.with(Criteria.where(column).regex(keyword));
}
return MongoNamedQueryChain.this;
}
/**
* 根据指定的方向进行模糊查询
*
* @param keyword 关键字
* @param direction 方向可以匹配开头和结尾
* @return 结果
*/
@Override
public NamedQueryChain like(String keyword, Queries.Direction direction) {
if (StringUtils.isNotBlank(keyword)) {
// 匹配开头
if (direction == Queries.Direction.LEFT) {
keyword = "^" + keyword;
} else if (direction == Queries.Direction.RIGHT) {
keyword = keyword + "$";
}
holder.with(Criteria.where(column).regex(keyword));
}
return MongoNamedQueryChain.this;
}
/**
* 判定为空
*
* @return 结果
*/
@Override
public NamedQueryChain isNull() {
holder.with(Criteria.where(column).isNull());
return MongoNamedQueryChain.this;
}
/**
* 包含在内
*
* @param list 集合
* @return 结果
*/
@Override
public NamedQueryChain in(Collection<?> list) {
if (CollectionUtils.isNotEmpty(list)) {
holder.with(Criteria.where(column).in(list));
}
return MongoNamedQueryChain.this;
}
/**
* 包含在内
* 注意需要根据字段类型推断
* 如果是json数组需要进行双向匹配
*
* @param values 值们
* @return 结果
*/
@Override
public NamedQueryChain in(Object... values) {
if (ArrayUtils.isNotEmpty(values)) {
holder.with(Criteria.where(column).in(values));
}
return MongoNamedQueryChain.this;
}
}
}

View File

@ -1,61 +0,0 @@
package com.flyfish.framework.mongodb.query.impl;
import com.flyfish.framework.query.holder.QueryChainHolder;
import org.springframework.data.mongodb.core.query.Criteria;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
class MongoQueryChainHolder implements QueryChainHolder<Criteria> {
/**
* 等待下一步消费
*
* @param operator 操作方法
* @return 本身
*/
@Override
public QueryChainHolder<Criteria> link(BinaryOperator<Criteria> operator) {
return null;
}
/**
* 拼接条件
*
* @param criteria 条件
*/
@Override
public void with(Criteria criteria) {
}
/**
* 拼接懒加载的条件
*
* @param supplier 条件提供者
*/
@Override
public void with(Supplier<Criteria> supplier) {
}
/**
* 触发动作得到最终的
*
* @return 本身
*/
@Override
public Criteria get() {
return null;
}
/**
* 判断条件是否为空
*
* @return 结果
*/
@Override
public boolean isEmpty() {
return false;
}
}

View File

@ -1,55 +0,0 @@
package com.flyfish.framework.mongodb.query.impl;
import com.flyfish.framework.query.QueryDefinition;
import com.flyfish.framework.query.QueryMutation;
/**
* mongo的查询定义
*
* @author wangyu
*/
class MongoQueryDefinition implements QueryDefinition {
protected final MongoQueryChainHolder holder = new MongoQueryChainHolder();
/**
* 构建
*
* @return 构建结果
*/
@SuppressWarnings("unchecked")
@Override
public <T> T build() {
return (T) holder.get();
}
/**
* 修改此修改会直接接着查询条件进行拼接
*
* @return 修改句柄
*/
@Override
public QueryMutation mutate() {
return null;
}
/**
* 会直接添加嵌套查询到当前查询末尾
*
* @return 修改句柄
*/
@Override
public QueryMutation within() {
return null;
}
/**
* 判断查询条件是否为空
*
* @return 结果
*/
@Override
public boolean isEmpty() {
return holder.isEmpty();
}
}

View File

@ -1,9 +1,4 @@
com.flyfish.framework.query.spi.QueryChainFactory=\
com.flyfish.framework.mongodb.query.factory.MongoNamedQueryFactory,\
com.flyfish.framework.mongodb.query.factory.MongoLambdaQueryFactory
com.flyfish.framework.query.spi.converter.QueryConverter=\
com.flyfish.framework.mongodb.query.converter.MongoQueryConverter
com.flyfish.framework.query.spi.QueryFactory=\
com.flyfish.framework.mongodb.query.MongoQueryFactory
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.flyfish.framework.mongodb.config.MongoDataConfig

View File

@ -0,0 +1,39 @@
package com.flyfish.framework.r2dbc.query;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.query.spi.QueryFactory;
import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor;
import com.flyfish.framework.query.spi.converter.QueryConverter;
import com.flyfish.framework.r2dbc.query.adaptor.R2dbcCriteriaAdaptor;
import com.flyfish.framework.r2dbc.query.converter.R2dbcQueryConverter;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.relational.core.query.Query;
import org.springframework.data.relational.repository.query.RelationalEntityInformation;
import org.springframework.data.repository.core.EntityInformation;
/**
* r2dbc查询工厂
*
* @author wangyu
*/
public class R2dbcQueryFactory implements QueryFactory<Criteria, Query> {
private final CriteriaAdaptor<Criteria> adaptor = new R2dbcCriteriaAdaptor();
private final QueryConverter<Query> converter = new R2dbcQueryConverter(adaptor);
@Override
public boolean supports(EntityInformation<? extends Domain, String> entity) {
return entity instanceof RelationalEntityInformation;
}
@Override
public QueryConverter<Query> getConverter() {
return converter;
}
@Override
public CriteriaAdaptor<Criteria> getAdaptor() {
return adaptor;
}
}

View File

@ -0,0 +1,109 @@
package com.flyfish.framework.r2dbc.query.adaptor;
import com.flyfish.framework.query.Queries;
import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.relational.core.query.Criteria;
import java.util.Collection;
import java.util.List;
/**
* r2dbc查询适配器
*
* @author wangyu
*/
public class R2dbcCriteriaAdaptor implements CriteriaAdaptor<Criteria> {
@Override
public Criteria and(Criteria first, Criteria other) {
return first.and(other);
}
@Override
public Criteria or(Criteria first, Criteria other) {
return first.or(other);
}
@Override
public Criteria eq(String column, Object value) {
return Criteria.where(column).is(value);
}
@Override
public Criteria hasId(String column, Object value) {
throw new UnsupportedOperationException("暂时不支持嵌套操作");
}
@Override
public Criteria has(String column, Object value) {
throw new UnsupportedOperationException("暂时不支持嵌套操作");
}
@Override
public Criteria ne(String column, Object value) {
return Criteria.where(column).not(value);
}
@Override
public Criteria between(String column, List<?> items) {
return Criteria.where(column).between(items.get(0), items.get(1));
}
@Override
public Criteria like(String column, String keyword, Queries.Direction direction) {
if (direction == Queries.Direction.LEFT) {
keyword = keyword + "%";
} else if (direction == Queries.Direction.RIGHT) {
keyword = "%" + keyword;
} else {
keyword = StringUtils.wrap(keyword, "%");
}
return Criteria.where(column).like(keyword);
}
@Override
public Criteria isNull(String column) {
return Criteria.where(column).isNull();
}
@Override
public Criteria lt(String column, Object value) {
return Criteria.where(column).lessThan(value);
}
@Override
public Criteria lte(String column, Object value) {
return Criteria.where(column).lessThanOrEquals(value);
}
@Override
public Criteria gt(String column, Object value) {
return Criteria.where(column).greaterThan(value);
}
@Override
public Criteria gte(String column, Object value) {
return Criteria.where(column).greaterThanOrEquals(value);
}
@Override
public Criteria in(String column, Collection<?> values) {
return Criteria.where(column).in(values);
}
@Override
public Criteria in(String column, Object... values) {
return Criteria.where(column).in(values);
}
@Override
public Criteria nin(String column, Object... values) {
return Criteria.where(column).notIn(values);
}
@Override
public Criteria nin(String column, Collection<?> values) {
return Criteria.where(column).notIn(values);
}
}

View File

@ -1,16 +1,17 @@
package com.flyfish.framework.r2dbc.query.converter;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.context.SpringContext;
import com.flyfish.framework.query.spi.adaptor.CriteriaAdaptor;
import com.flyfish.framework.query.spi.converter.QueryConverter;
import lombok.Setter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.data.domain.Example;
import org.springframework.data.r2dbc.mapping.R2dbcMappingContext;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.relational.core.query.Query;
import org.springframework.data.relational.repository.query.RelationalEntityInformation;
import org.springframework.data.relational.repository.query.RelationalExampleMapper;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.util.function.SingletonSupplier;
import java.util.Optional;
@ -20,20 +21,16 @@ import java.util.Optional;
* @author wangyu
*/
@Slf4j
@RequiredArgsConstructor
public class R2dbcQueryConverter implements QueryConverter<Query> {
@Setter
private static RelationalExampleMapper exampleMapper;
private final CriteriaAdaptor<Criteria> adaptor;
/**
* 判断是否支持实体
*
* @param entity 实体信息
* @return 结果
*/
@Override
public boolean supports(EntityInformation<? extends Domain, String> entity) {
return entity instanceof RelationalEntityInformation;
private final SingletonSupplier<RelationalExampleMapper> exampleMapper = SingletonSupplier.of(R2dbcQueryConverter::getExampleMapper);
private static RelationalExampleMapper getExampleMapper() {
R2dbcMappingContext context = SpringContext.getBean(R2dbcMappingContext.class);
return new RelationalExampleMapper(context);
}
/**
@ -80,7 +77,7 @@ public class R2dbcQueryConverter implements QueryConverter<Query> {
}
// 如果存在查询定义直接使用查询定义
if (null != query.getDefinition()) {
return (Criteria) query.getDefinition().build();
return query.getDefinition().build(adaptor);
}
return null;
}
@ -92,7 +89,7 @@ public class R2dbcQueryConverter implements QueryConverter<Query> {
* @return 结果
*/
private Optional<Criteria> ofExample(Example<?> example) {
return exampleMapper.getMappedExample(example).getCriteria()
return exampleMapper.obtain().getMappedExample(example).getCriteria()
.map(cd -> (Criteria) cd);
}
}

View File

@ -1,36 +0,0 @@
package com.flyfish.framework.r2dbc.query.factory;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.query.LambdaQueryChain;
import com.flyfish.framework.query.spi.QueryChainFactory;
import com.flyfish.framework.r2dbc.query.impl.R2dbcLambdaQueryChain;
/**
* mongo lambda 查询工厂
*
* @author wangyu
*/
public class R2dbcLambdaQueryFactory<T extends Domain> implements QueryChainFactory<LambdaQueryChain<T>> {
/**
* 生产适配器
* 此接口为高度抽象接口目的是兼容更多的查询链类型便于后续扩展
*
* @return 生产结果
*/
@Override
public LambdaQueryChain<T> produce() {
return new R2dbcLambdaQueryChain<>();
}
/**
* 判定是否支持特定的实例类型
*
* @param targetType 工厂目标类型
* @return 是否匹配
*/
@Override
public boolean supports(Class<?> targetType) {
return targetType.isAssignableFrom(R2dbcLambdaQueryChain.class);
}
}

View File

@ -1,35 +0,0 @@
package com.flyfish.framework.r2dbc.query.factory;
import com.flyfish.framework.query.NamedQueryChain;
import com.flyfish.framework.query.spi.QueryChainFactory;
import com.flyfish.framework.r2dbc.query.impl.R2dbcNamedQueryChain;
/**
* mongo名称查询工厂
*
* @author wangyu
*/
public class R2dbcNamedQueryFactory implements QueryChainFactory<NamedQueryChain> {
/**
* 生产适配器
* 此接口为高度抽象接口目的是兼容更多的查询链类型便于后续扩展
*
* @return 生产结果
*/
@Override
public NamedQueryChain produce() {
return new R2dbcNamedQueryChain();
}
/**
* 判定是否支持特定的实例类型
*
* @param targetType 工厂目标类型
* @return 是否匹配
*/
@Override
public boolean supports(Class<?> targetType) {
return targetType.isAssignableFrom(R2dbcNamedQueryChain.class);
}
}

View File

@ -1,109 +0,0 @@
package com.flyfish.framework.r2dbc.query.impl;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.query.LambdaQueryChain;
import com.flyfish.framework.query.Queries;
import com.flyfish.framework.query.QueryChain;
import com.flyfish.framework.query.QueryCondition;
import com.flyfish.framework.query.support.DomainFunction;
import java.util.List;
import java.util.function.Supplier;
/**
* mongodb实现的基于lambda的查询链
*
* @author wangyu
*/
public class R2dbcLambdaQueryChain<T extends Domain> extends R2dbcQueryDefinition implements LambdaQueryChain<T> {
/**
* 以且连接下一个字段
*
* @param column
* @return 查询条件
*/
@Override
public QueryCondition<LambdaQueryChain<T>> and(DomainFunction<T> column) {
return null;
}
/**
* 直接拼接提供者此处懒加载最终build才会执行
*
* @param supplier 提供者
* @return 结果
*/
@Override
public <V extends QueryChain<V, ?>> LambdaQueryChain<T> and(Supplier<QueryChain<V, ?>> supplier) {
return null;
}
/**
* 条件列表
*
* @param chain 多个条件们
* @return 结果
*/
@Override
public LambdaQueryChain<T> and(LambdaQueryChain<T> chain) {
return null;
}
/**
* 多个嵌套子条件列表
*
* @param lambdaQueryChains 多条链
* @param combinator 各个链条之间的连接方式
* @return 结果
*/
@Override
public LambdaQueryChain<T> and(List<LambdaQueryChain<T>> lambdaQueryChains, Queries.Combinator combinator) {
return null;
}
/**
* 以或连接下一个字段
*
* @param column
* @return 查询条件
*/
@Override
public QueryCondition<LambdaQueryChain<T>> or(DomainFunction<T> column) {
return null;
}
/**
* 以或连接条件列表
*
* @param chain 多个条件们
* @return 结果
*/
@Override
public LambdaQueryChain<T> or(LambdaQueryChain<T> chain) {
return null;
}
/**
* 以或连接嵌套多个子条件列表
*
* @param lambdaQueryChains 多条链
* @param combinator 各个链条之间的连接方式
* @return 结果
*/
@Override
public LambdaQueryChain<T> or(List<LambdaQueryChain<T>> lambdaQueryChains, Queries.Combinator combinator) {
return null;
}
/**
* 直接拼接提供者此处懒加载最终build才会执行
*
* @param supplier 提供者
* @return 结果
*/
@Override
public <V extends QueryChain<V, ?>> LambdaQueryChain<T> or(Supplier<QueryChain<V, ?>> supplier) {
return null;
}
}

View File

@ -1,107 +0,0 @@
package com.flyfish.framework.r2dbc.query.impl;
import com.flyfish.framework.query.NamedQueryChain;
import com.flyfish.framework.query.Queries;
import com.flyfish.framework.query.QueryChain;
import com.flyfish.framework.query.QueryCondition;
import java.util.List;
import java.util.function.Supplier;
/**
* mongodb实现的基于名称的查询链
*
* @author wangyu
*/
public class R2dbcNamedQueryChain extends R2dbcQueryDefinition implements NamedQueryChain {
/**
* 以且连接下一个字段
*
* @param column
* @return 查询条件
*/
@Override
public QueryCondition<NamedQueryChain> and(String column) {
return null;
}
/**
* 直接拼接提供者此处懒加载最终build才会执行
*
* @param supplier 提供者
* @return 结果
*/
@Override
public <V extends QueryChain<V, ?>> NamedQueryChain and(Supplier<QueryChain<V, ?>> supplier) {
return null;
}
/**
* 条件列表
*
* @param chain 多个条件们
* @return 结果
*/
@Override
public NamedQueryChain and(NamedQueryChain chain) {
return null;
}
/**
* 多个嵌套子条件列表
*
* @param chains 多条链
* @param combinator 各个链条之间的连接方式
* @return 结果
*/
@Override
public NamedQueryChain and(List<NamedQueryChain> chains, Queries.Combinator combinator) {
return null;
}
/**
* 以或连接下一个字段
*
* @param column
* @return 查询条件
*/
@Override
public QueryCondition<NamedQueryChain> or(String column) {
return null;
}
/**
* 以或连接条件列表
*
* @param chain 多个条件们
* @return 结果
*/
@Override
public NamedQueryChain or(NamedQueryChain chain) {
return null;
}
/**
* 以或连接嵌套多个子条件列表
*
* @param chains 多条链
* @param combinator 各个链条之间的连接方式
* @return 结果
*/
@Override
public NamedQueryChain or(List<NamedQueryChain> chains, Queries.Combinator combinator) {
return null;
}
/**
* 直接拼接提供者此处懒加载最终build才会执行
*
* @param supplier 提供者
* @return 结果
*/
@Override
public <V extends QueryChain<V, ?>> NamedQueryChain or(Supplier<QueryChain<V, ?>> supplier) {
return null;
}
}

View File

@ -1,56 +0,0 @@
package com.flyfish.framework.r2dbc.query.impl;
import com.flyfish.framework.query.QueryDefinition;
import com.flyfish.framework.query.QueryMutation;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.util.CastUtils;
/**
* mongo的查询定义
*
* @author wangyu
*/
public class R2dbcQueryDefinition implements QueryDefinition {
private Criteria criteria;
/**
* 构建
*
* @return 构建结果
*/
@Override
public <T> T build() {
return CastUtils.cast(criteria);
}
/**
* 修改此修改会直接接着查询条件进行拼接
*
* @return 修改句柄
*/
@Override
public QueryMutation mutate() {
return null;
}
/**
* 会直接添加嵌套查询到当前查询末尾
*
* @return 修改句柄
*/
@Override
public QueryMutation within() {
return null;
}
/**
* 判断查询条件是否为空
*
* @return 结果
*/
@Override
public boolean isEmpty() {
return false;
}
}

View File

@ -2,7 +2,6 @@ package com.flyfish.framework.r2dbc.repository.impl;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.domain.base.Qo;
import com.flyfish.framework.r2dbc.query.converter.R2dbcQueryConverter;
import com.flyfish.framework.repository.DefaultReactiveRepository;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
@ -17,7 +16,6 @@ import org.springframework.data.r2dbc.repository.support.SimpleR2dbcRepository;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.relational.core.query.Query;
import org.springframework.data.relational.repository.query.RelationalEntityInformation;
import org.springframework.data.relational.repository.query.RelationalExampleMapper;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
@ -51,7 +49,6 @@ public class DefaultReactiveRepositoryImpl<T extends Domain> extends SimpleR2dbc
super(entity, entityOperations, converter);
this.entity = entity;
this.entityOperations = entityOperations;
R2dbcQueryConverter.setExampleMapper(new RelationalExampleMapper(converter.getMappingContext()));
}

View File

@ -1,9 +1,4 @@
com.flyfish.framework.query.spi.QueryChainFactory=\
com.flyfish.framework.r2dbc.query.factory.R2dbcLambdaQueryFactory,\
com.flyfish.framework.r2dbc.query.factory.R2dbcNamedQueryFactory
com.flyfish.framework.query.spi.converter.QueryConverter=\
com.flyfish.framework.r2dbc.query.converter.R2dbcQueryConverter
com.flyfish.framework.query.spi.QueryFactory=\
com.flyfish.framework.r2dbc.query.R2dbcQueryFactory
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.flyfish.framework.r2dbc.config.R2dbcDataConfig