diff --git a/README.md b/README.md index 035c55f..f3bc185 100644 --- a/README.md +++ b/README.md @@ -4,20 +4,25 @@ ## 介绍 LambdaQuery 将支持通过Lambda进行多种数据源的查询 实现java端的简单数据的统一查询 ## 功能规划 +### 总体功能规划 +* [x] 实现基础查询功能 +* [x] 实现LoadRef功能,通过selectIn的方式进行数据表join, 实现跨服务,分布式数据库,跨不同数据库之间的join +* [ ] 增加redisCache功能,实现在loadRef的时候 可以通过配置项进行设置是否通过cache 进行加载 ### 1. MongoDb * [x] 实现基础的Lambda查询(已完成) -* [ ] 实现 新增,删除,更新等基础操作[开发中] +* [ ] 实现 新增,删除,更新等基础操作 +* [x] 新增LoadJoin功能,通过selectIn的方式进行数据表join ### 2. mybatis-plus * [x] 接入mybatis-plus的查询接口(已完成) * [ ] 接入mybatis-plus 的新增,删除,更新操作 -* [ ] 新增LoadJoin功能,通过selectIn的方式进行数据表join +* [x] 新增LoadJoin功能,通过selectIn的方式进行数据表join * [ ] 新增Cache功能,采用redis 进行数据缓存,配合selectIn方式避免join查询直接访问数据库 * [ ] 新增Map接口,实现selectIn后数据合并问题 ### 3. HttpServer&HttpClient -* [ ] 新增Http模式,实现微服务之间 关联数据join 显示问题 -* [ ] 扩展全功能查询,实现微服务之间的HTTP接口数据查询功能 +* [x] 新增Http模式,实现微服务之间 关联数据join 显示问题 +* [x] 扩展全功能查询,实现微服务之间的HTTP接口数据查询功能 * [ ] 扩展 Http 自定义查询字段和结果集字段,可以实现灵活空值查询字段与条件 * [ ] 新增拦截器,实现对查询,新增,修改操作的全局拦截,可以实现后端租户拦截,http接口的权限拦截限制 @@ -102,7 +107,7 @@ LambdaQuery 将支持通过Lambda进行多种数据源的查询 实现java端的 ``` ### 2.Mongo查询器使用 -1. 创建实体类 +#### 1. 创建实体类 ```java @Document("demo_doc") @@ -125,16 +130,72 @@ public class TestDoc { } ``` + + +### 2.MybatisPlus查询器使用 + +mybatis-plus 实体初始化 -2. 进行查询 ```java +@Data +@TableName("u1") +@MyBatisPlusDaoSelect +public class U1 { + @TableId(type = IdType.AUTO) + private Long id; + private String name; + private String type; +} + + +``` + + +### 3. HTTP查询器 + +1. 暴露接口 +```java + @PostConstruct + public void init(){ + LambdaQueryHttpConfig.getInstance().registerService("u1", U1.class); + HttpClientFactory httpClientFactory = new HttpClientFactory(); + } +``` + +2. 定义查询器 +```java +@HttpDaoSelect( serverAddress = "http://127.0.0.1:7000",path = "/lambda/u1/") +@Data +public class HttpEntity { + private Long id; + private String name; + private String type; + private Long u2Id; +} + + +``` + +3. 使用查询功能 +```java + @Test + public void list(){ + JQuerys.lambdaQuery(HttpRequest.class).eq(HttpRequest::getName,"xxx").eq(HttpRequest::getUserName,"un").list(); + } +``` + +## 功能说明 + +### 1. 基础查询功能 + +```java /** * == 查询 */ @Test public void testEq(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).eq(TestDoc::getName, "name_1").list(); + List list = JQuerys.lambdaQuery(TestDoc.class).eq(TestDoc::getName, "name_1").list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_1"); @@ -146,7 +207,7 @@ public void testEq(){ */ @Test public void testGt(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).gt(TestDoc::getNum,3 ).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).gt(TestDoc::getNum,3 ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_4"); @@ -157,7 +218,7 @@ public void testGt(){ */ @Test public void testGte(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).gte(TestDoc::getNum,4 ).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).gte(TestDoc::getNum,4 ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_4"); @@ -168,7 +229,7 @@ public void testGte(){ */ @Test public void testLt(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).lt(TestDoc::getNum,1 ).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).lt(TestDoc::getNum,1 ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_0"); @@ -179,7 +240,7 @@ public void testLt(){ */ @Test public void testLte(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).lte(TestDoc::getNum,0 ).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).lte(TestDoc::getNum,0 ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_0"); @@ -190,7 +251,7 @@ public void testLte(){ */ @Test public void testIn(){ - List list = JkQuerys.lambdaQuery(TestDoc.class) + List list = JQuerys.lambdaQuery(TestDoc.class) .in(TestDoc::getTitle,"title_0" ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); @@ -202,7 +263,7 @@ public void testIn(){ */ @Test public void testNotIn(){ - List list = JkQuerys.lambdaQuery(TestDoc.class) + List list = JQuerys.lambdaQuery(TestDoc.class) .notIn(TestDoc::getTitle,"title_0","title_1","title_2","title_3" ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); @@ -214,10 +275,10 @@ public void testNotIn(){ */ @Test public void testOr(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).or().eq(TestDoc::getNum, 0).or().eq(TestDoc::getNum, 1).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).or().eq(TestDoc::getNum, 0).or().eq(TestDoc::getNum, 1).list(); Assertions.assertEquals(list.size(),2); - list = JkQuerys.lambdaQuery(TestDoc.class).or(it->{ + list = JQuerys.lambdaQuery(TestDoc.class).or(it->{ it.eq(TestDoc::getNum,0).eq(TestDoc::getName,"name_0"); }).or(it->{ it.eq(TestDoc::getNum,1).eq(TestDoc::getName,"name_1"); @@ -232,23 +293,30 @@ public void testOr(){ */ @Test public void testOrder(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).in(TestDoc::getNum, 1, 2).orderAsc(TestDoc::getNum).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).in(TestDoc::getNum, 1, 2).orderAsc(TestDoc::getNum).list(); Assertions.assertEquals(list.size(),2); Assertions.assertEquals(list.get(0).getNum(),1); Assertions.assertEquals(list.get(1).getNum(),2); - list = JkQuerys.lambdaQuery(TestDoc.class).in(TestDoc::getNum, 1, 2).orderDesc(TestDoc::getNum).list(); + list = JQuerys.lambdaQuery(TestDoc.class).in(TestDoc::getNum, 1, 2).orderDesc(TestDoc::getNum).list(); Assertions.assertEquals(list.size(),2); Assertions.assertEquals(list.get(0).getNum(),2); Assertions.assertEquals(list.get(1).getNum(),1); } + +``` + +### 2. 二级字段查询&json 字段查询(未完成) + +```java + /** * 二级字段查询 */ @Test public void testSubField(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).eq(of().subList(TestDoc::getToc).sub(TestDoc.Title::getTitle), "sub_title_0_0").list(); + List list = JQuerys.lambdaQuery(TestDoc.class).eq(of().subList(TestDoc::getToc).sub(TestDoc.Title::getTitle), "sub_title_0_0").list(); Assertions.assertEquals(list.size(),1); Assertions.assertEquals(list.get(0).getNum(),0); } @@ -258,21 +326,32 @@ public CascadeField of(){ ``` +### 3. loadJoin 功能查询 -### 3.MybatisPlus查询器使用 +采用selectIn 和并行计算方式进行 join查询合并 -mybatis-plus 实体初始化 +```java + @GetMapping("list") + public Object testList(){ + JLambdaQuery query = JQuerys.lambdaQuery(HttpEntity.class); + Object list = query.or().eq(HttpEntity::getName,"name1").or() + .eq(HttpEntity::getName,"name2") + // 属性 u2Id 关联实体 U2 的id字段,并映射结果到U1Vo + .loadRef(HttpEntity::getU2Id, U2.class,U2::getId).map(U1Vo.class).list(); + return list; + } +``` ```java @Data -@TableName("u1") -@MyBatisPlusDaoSelect -public class U1 { - @TableId(type = IdType.AUTO) +public class U1Vo { private Long id; private String name; private String type; - + @SetRefValue("u2") + private Long u2Id; + @RefValue("#u2.name") + private String u2Name; } diff --git a/lambda-query-core/pom.xml b/lambda-query-core/pom.xml index 99105df..dad7755 100644 --- a/lambda-query-core/pom.xml +++ b/lambda-query-core/pom.xml @@ -5,24 +5,30 @@ lambda-query com.github.xuejike - 1.0.1 + 1.0.2-SNAPSHOT lambda-query-core lambda-query-core Demo project for Spring Boot - 1.0.1 + 1.0.2-SNAPSHOT cn.hutool hutool-core - 5.5.2 + ${hutool.version} cn.hutool hutool-log - 5.5.2 + ${hutool.version} + + + cn.hutool + hutool-cache + ${hutool.version} + com.alibaba @@ -31,15 +37,21 @@ - org.projectlombok - lombok - 1.18.16 - provided + org.springframework + spring-expression + 5.2.10.RELEASE + + + cglib + cglib + 3.3.0 + + - junit - junit - 4.12 + org.junit.jupiter + junit-jupiter + 5.7.0 test diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/JkLambdaQuery.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/JLambdaQuery.java similarity index 56% rename from lambda-query-core/src/main/java/com/github/xuejike/query/core/JkLambdaQuery.java rename to lambda-query-core/src/main/java/com/github/xuejike/query/core/JLambdaQuery.java index 2c08f8f..5fd4297 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/JkLambdaQuery.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/JLambdaQuery.java @@ -1,11 +1,10 @@ package com.github.xuejike.query.core; +import com.github.xuejike.query.core.base.BaseDao; import com.github.xuejike.query.core.base.BaseNestedWhereQuery; -import com.github.xuejike.query.core.criteria.DaoCriteria; -import com.github.xuejike.query.core.criteria.InjectionBaseQuery; -import com.github.xuejike.query.core.criteria.OrderCriteria; +import com.github.xuejike.query.core.base.MapDao; +import com.github.xuejike.query.core.criteria.*; import com.github.xuejike.query.core.enums.OrderType; -import com.github.xuejike.query.core.po.FieldInfo; import com.github.xuejike.query.core.tool.lambda.FieldFunction; import com.github.xuejike.query.core.tool.lambda.LambdaTool; @@ -15,12 +14,12 @@ * @author xuejike * @date 2020/12/18 */ -public class JkLambdaQuery extends BaseNestedWhereQuery, JkLambdaQuery> implements DaoCriteria , OrderCriteria, JkLambdaQuery> { - private DaoCriteria daoCriteria; +public class JLambdaQuery extends BaseNestedWhereQuery, JLambdaQuery> implements DaoCriteria , OrderCriteria, JLambdaQuery>, MapCriteria { + private BaseDao daoCriteria; - public JkLambdaQuery(DaoCriteria daoCriteria) { + public JLambdaQuery(BaseDao daoCriteria) { this.daoCriteria = daoCriteria; - if (daoCriteria instanceof InjectionBaseQuery){ + if (daoCriteria != null){ ((InjectionBaseQuery) daoCriteria).injectionBaseWhereQuery(this); } } @@ -32,7 +31,7 @@ public DaoCriteria getDao() { @Override - public JkLambdaQuery orderAsc(FieldFunction... fields) { + public JLambdaQuery orderAsc(FieldFunction... fields) { Arrays.stream(fields).map(LambdaTool::getFieldInfo).forEach(it->{ orderMap.put(it, OrderType.asc); }); @@ -41,11 +40,16 @@ public JkLambdaQuery orderAsc(FieldFunction... fields) { } @Override - public JkLambdaQuery orderDesc(FieldFunction... fields) { + public JLambdaQuery orderDesc(FieldFunction... fields) { Arrays.stream(fields).map(LambdaTool::getFieldInfo).forEach(it->{ orderMap.put(it, OrderType.desc); }); return returnObj; } + + @Override + public SelectDaoCriteria map(Class mapCls) { + return new MapDao(daoCriteria,mapCls); + } } diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/JkQuerys.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/JQuerys.java similarity index 67% rename from lambda-query-core/src/main/java/com/github/xuejike/query/core/JkQuerys.java rename to lambda-query-core/src/main/java/com/github/xuejike/query/core/JQuerys.java index 8ddf317..a37d660 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/JkQuerys.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/JQuerys.java @@ -2,27 +2,27 @@ import cn.hutool.core.annotation.AnnotationUtil; import com.github.xuejike.query.core.annotation.DaoSelect; +import com.github.xuejike.query.core.base.BaseDao; import com.github.xuejike.query.core.config.DaoFactory; import com.github.xuejike.query.core.config.JkQueryConfig; -import com.github.xuejike.query.core.criteria.DaoCriteria; import com.github.xuejike.query.core.exception.LambdaQueryException; /** * @author xuejike * @date 2020/12/28 */ -public class JkQuerys { +public class JQuerys { - public static JkLambdaQuery lambdaQuery(Class entityCls){ + public static JLambdaQuery lambdaQuery(Class entityCls){ JkQueryConfig instance = JkQueryConfig.getInstance(); for (DaoFactory factory : instance.getDaoFactoryList()) { DaoSelect annotation = AnnotationUtil.getAnnotation(entityCls, DaoSelect.class); if (factory.getDaoCls() == annotation.daoCls()){ - DaoCriteria daoCriteria = factory.createDao(entityCls); - return new JkLambdaQuery<>(daoCriteria); + BaseDao daoCriteria = factory.createDao(entityCls); + return new JLambdaQuery<>(daoCriteria); } } - throw new LambdaQueryException("not find dao "); + throw new LambdaQueryException("not find dao {}",entityCls.getName()); } } diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/JkQuery.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/JkQuery.java deleted file mode 100644 index 58040f6..0000000 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/JkQuery.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.github.xuejike.query.core; - -import com.github.xuejike.query.core.base.BaseNestedWhereQuery; -import com.github.xuejike.query.core.base.BaseWhereQuery; -import com.github.xuejike.query.core.criteria.DaoCriteria; -import com.github.xuejike.query.core.criteria.InjectionBaseQuery; -import com.github.xuejike.query.core.tool.lambda.FieldFunction; - -/** - * @author xuejike - * @date 2020/12/18 - */ -public class JkQuery extends BaseNestedWhereQuery> implements DaoCriteria { - private DaoCriteria daoCriteria; - - public JkQuery(DaoCriteria daoCriteria) { - this.daoCriteria = daoCriteria; - if (daoCriteria instanceof InjectionBaseQuery){ - ((InjectionBaseQuery) daoCriteria).injectionBaseWhereQuery(this); - } - } - - @Override - public DaoCriteria getDao() { - return daoCriteria; - } - - -} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/annotation/RefValue.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/annotation/RefValue.java new file mode 100644 index 0000000..9a437d1 --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/annotation/RefValue.java @@ -0,0 +1,16 @@ +package com.github.xuejike.query.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface RefValue { + String value(); +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/annotation/SetRefValue.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/annotation/SetRefValue.java new file mode 100644 index 0000000..e5922dc --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/annotation/SetRefValue.java @@ -0,0 +1,16 @@ +package com.github.xuejike.query.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface SetRefValue { + String value(); +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseDao.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseDao.java index 4a14e3f..e17ebe3 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseDao.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseDao.java @@ -1,20 +1,44 @@ package com.github.xuejike.query.core.base; +import cn.hutool.core.collection.CollUtil; import com.github.xuejike.query.core.criteria.DaoCriteria; import com.github.xuejike.query.core.criteria.InjectionBaseQuery; +import com.github.xuejike.query.core.enums.OrderType; +import com.github.xuejike.query.core.po.BaseConditionsVo; +import com.github.xuejike.query.core.po.FieldInfo; +import com.github.xuejike.query.core.po.LoadRefInfo; +import com.github.xuejike.query.core.po.QueryInfo; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * @author xuejike * @date 2020/12/28 */ -public abstract class BaseDao implements DaoCriteria , InjectionBaseQuery { +public abstract class BaseDao implements DaoCriteria , InjectionBaseQuery { protected BaseWhereQuery baseWhereQuery; protected Class entityCls; + protected BaseConditionsVo baseConditionsVo; public BaseDao(Class entityCls) { this.entityCls = entityCls; } + + /** + * 构建查询器 + * @return + */ + public abstract Q buildQuery(); + + public void setBaseConditionsVo(BaseConditionsVo baseConditionsVo) { + this.baseConditionsVo = baseConditionsVo; + } + @Override public DaoCriteria getDao() { return this; @@ -24,4 +48,14 @@ public DaoCriteria getDao() { public void injectionBaseWhereQuery(BaseWhereQuery baseWhereQuery) { this.baseWhereQuery = baseWhereQuery; } + + + public Map> getRefClassMap() { + HashMap> map = new HashMap<>(); + map.putAll(baseWhereQuery.getRefClassMap()); + if (baseConditionsVo!=null && CollUtil.isNotEmpty(baseConditionsVo.getRefClassMap())){ + map.putAll(baseConditionsVo.getRefClassMap()); + } + return map; + } } diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseNestedWhereQuery.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseNestedWhereQuery.java index c329f0e..07d3a2d 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseNestedWhereQuery.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseNestedWhereQuery.java @@ -1,12 +1,22 @@ package com.github.xuejike.query.core.base; +import com.github.xuejike.query.core.criteria.DaoCriteria; +import com.github.xuejike.query.core.criteria.LoadRefCriteria; +import com.github.xuejike.query.core.criteria.MapCriteria; +import com.github.xuejike.query.core.criteria.SelectDaoCriteria; +import com.github.xuejike.query.core.enums.LoadRefMode; +import com.github.xuejike.query.core.po.FieldInfo; +import com.github.xuejike.query.core.po.LoadRefInfo; +import com.github.xuejike.query.core.tool.lambda.FieldFunction; +import com.github.xuejike.query.core.tool.lambda.LambdaTool; + import java.util.function.Consumer; /** * @author xuejike * @date 2020/12/18 */ -public class BaseNestedWhereQuery> extends BaseSimpleWhereQuery{ +public class BaseNestedWhereQuery> extends BaseSimpleWhereQuery implements LoadRefCriteria{ public BaseNestedWhereQuery() { @@ -24,4 +34,16 @@ public > C or(Consumer C loadRef(F refField, Class entityCls, FieldFunction targetField, LoadRefMode mode) { + LoadRefInfo info = new LoadRefInfo<>(); + info.setRefClass(entityCls); + info.setMode(mode); + info.setTargetField(buildFieldInfo(targetField)); + refClassMap.put(buildFieldInfo(refField),info); + return returnObj; + } + + } diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseWhereQuery.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseWhereQuery.java index 4ff18cc..efef203 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseWhereQuery.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/BaseWhereQuery.java @@ -23,11 +23,13 @@ */ public class BaseWhereQuery> implements WhereCriteria,SelectCriteria{ - protected Map> whereMap = new ConcurrentHashMap<>(); + protected Map> whereMap = new ConcurrentHashMap<>(); protected List> orList = new LinkedList<>(); protected List selectList = new LinkedList<>(); protected List excludeList = new LinkedList<>(); protected Map orderMap = new ConcurrentHashMap<>(); + protected Map> refClassMap = new ConcurrentHashMap<>(); + protected C returnObj = (C)this; public BaseWhereQuery() { @@ -234,19 +236,25 @@ protected void doIt(boolean condition,Runnable run){ } protected void putWhere(WhereOperation whereOperation,F field,Object val){ Map fieldMap = null; - if (field instanceof FieldFunction && !(field instanceof CascadeField)){ - FieldInfo fieldInfo = LambdaTool.getFieldInfo(((FieldFunction) field)); - fieldMap = getFieldMap(fieldInfo); - }else{ - fieldMap = getFieldMap(field); - } + fieldMap = getFieldMap(buildFieldInfo(field)); if (fieldMap.containsKey(whereOperation)){ Log.get().warn("请勿重复添加相同条件字段,条件将会被覆盖,{}-{}",field,whereOperation); } fieldMap.put(whereOperation,val); } - protected Map getFieldMap(Object field){ + protected FieldInfo buildFieldInfo(Object field){ + if (field instanceof FieldFunction && !(field instanceof CascadeField)){ + return LambdaTool.getFieldInfo(((FieldFunction) field)); + }else if (field instanceof String){ + return new FieldInfo(((String) field)); + }else if (field instanceof CascadeField){ + return ((CascadeField) field).getFieldInfo(); + }else{ + throw new LambdaQueryException("field type is error"); + } + } + protected Map getFieldMap(FieldInfo field){ Map map = whereMap.getOrDefault(field, new ConcurrentHashMap<>()); if (!whereMap.containsKey(field)){ whereMap.put(field,map); @@ -254,7 +262,7 @@ protected Map getFieldMap(Object field){ return map; } - public Map> getWhereMap() { + public Map> getWhereMap() { return whereMap; } @@ -327,4 +335,8 @@ private FieldInfo parseFieldInfo(Object key) { } return fieldInfo; } + + public Map> getRefClassMap() { + return refClassMap; + } } diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/MapDao.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/MapDao.java new file mode 100644 index 0000000..fa824b1 --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/base/MapDao.java @@ -0,0 +1,128 @@ +package com.github.xuejike.query.core.base; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ReflectUtil; +import com.github.xuejike.query.core.JQuerys; +import com.github.xuejike.query.core.criteria.DaoCriteria; +import com.github.xuejike.query.core.criteria.GetDaoCriteria; +import com.github.xuejike.query.core.criteria.IJPage; +import com.github.xuejike.query.core.criteria.SelectDaoCriteria; +import com.github.xuejike.query.core.po.FieldInfo; +import com.github.xuejike.query.core.po.JPage; +import com.github.xuejike.query.core.po.LoadRefInfo; +import com.github.xuejike.query.core.tool.ELParseTool; +import com.github.xuejike.query.core.tool.lambda.CascadeField; +import lombok.extern.slf4j.Slf4j; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@Slf4j +public class MapDao implements SelectDaoCriteria, GetDaoCriteria { + + private BaseDao daoCriteria; + private Class resultCls; + + public MapDao(BaseDao daoCriteria, Class resultCls) { + this.daoCriteria = daoCriteria; + this.resultCls = resultCls; + } + + @Override + public DaoCriteria getDao() { + return daoCriteria; + } + + @Override + public List list() { + List list = getDao().list(); + List collect = loadRefMap(list); + + return collect; + } + + private List loadRefMap(List list) { + Map> refClassMap = daoCriteria.getRefClassMap(); + log.debug("loadRefMap 耗时统计:加载引用对象{}:",refClassMap.size()); + long begin = System.currentTimeMillis(); + ConcurrentHashMap> refMap = new ConcurrentHashMap<>(refClassMap.size()); + refClassMap.entrySet().parallelStream().forEach(entry -> { + + Set refIdList = list.stream().map(it -> ReflectUtil.getFieldValue(it, entry.getKey().getField())).collect(Collectors.toSet()); + List refList = JQuerys.lambdaQuery(entry.getValue().getRefClass()) + .in(new CascadeField().subFieldName(entry.getValue().getTargetField().getField()), refIdList) + .list(); + Map map = refList.stream().collect(Collectors.toMap(it -> ReflectUtil.getFieldValue(it, entry.getValue().getTargetField().getField()), it -> it)); + log.debug("loadRefMap 耗时统计:关联属性{},加载耗时:{}ms",entry.getKey().getField(),System.currentTimeMillis()-begin); + refMap.put(entry.getKey().getField(),map); + }); + log.debug("loadRefMap 耗时统计:关联属性加载总耗时:{}ms",System.currentTimeMillis()-begin); + long elBegin = System.currentTimeMillis(); + List collect = list.parallelStream().map(item -> { + R r = BeanUtil.copyProperties(item, resultCls); + HashMap varMap = new HashMap<>(); + for (Map.Entry> entry : refMap.entrySet()) { + String varName = ELParseTool.getSetRefValue(resultCls, entry.getKey()); + Object varValue = entry.getValue().get(ReflectUtil.getFieldValue(item, entry.getKey())); + varMap.put(varName,varValue); + } + Map fieldStringMap = ELParseTool.getRefValues(resultCls); + fieldStringMap.entrySet().parallelStream().forEach(entry -> { + ReflectUtil.setFieldValue(r, entry.getKey(), ELParseTool.parseEl(entry.getValue(), varMap, entry.getKey().getType())); + }); + + return r; + }).collect(Collectors.toList()); + log.debug("loadRefMap 耗时统计:合并数据总耗时:{}ms",System.currentTimeMillis()-elBegin); + log.debug("loadRefMap 耗时统计:总耗时:{}ms",System.currentTimeMillis()-begin); + + return collect; + } + + @Override + public R getFirst() { + T first = getDao().getFirst(); + if (first == null){ + return null; + } + List rs = loadRefMap(ListUtil.of(first)); + return rs.get(0); + } + + @Override + public Optional getFirstStream() { + return Optional.ofNullable(getFirst()); + } + + @Override + public IJPage page(IJPage page) { + IJPage rPage = getDao().page(new JPage<>(page.getPageNo(), page.getPageSize(), page.isHaveTotal())); + List rs = loadRefMap(rPage.getData()); + page.setData(rs); + page.setTotal(rPage.getTotal()); + return page; + } + + @Override + public R findById(Serializable id) { + T rs = getDao().findById(id); + if (rs == null){ + return null; + } + List list = loadRefMap(ListUtil.of(rs)); + return list.get(0); + } + + @Override + public Optional findByIdStream(Serializable id) { + return Optional.ofNullable(findById(id)); + } +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/config/DaoFactory.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/config/DaoFactory.java index 1e457ad..18db2c3 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/config/DaoFactory.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/config/DaoFactory.java @@ -1,5 +1,6 @@ package com.github.xuejike.query.core.config; +import com.github.xuejike.query.core.base.BaseDao; import com.github.xuejike.query.core.criteria.DaoCriteria; /** @@ -11,6 +12,10 @@ public abstract class DaoFactory { public DaoFactory(Class daoCls) { this.daoCls = daoCls; + init(); + } + private void init(){ + JkQueryConfig.getInstance().addDaoFactory(this); } public Class getDaoCls() { @@ -23,5 +28,5 @@ public Class getDaoCls() { * @param * @return */ - abstract public DaoCriteria createDao(Class entityCls); + abstract public BaseDao createDao(Class entityCls); } diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/DaoCriteria.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/DaoCriteria.java index 81e89c2..f5a3a7e 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/DaoCriteria.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/DaoCriteria.java @@ -8,19 +8,21 @@ * @author xuejike * @date 2020/12/18 */ -public interface DaoCriteria { - DaoCriteria getDao(); +public interface DaoCriteria extends SelectDaoCriteria, GetDaoCriteria { /** * 列表查询 * @return */ + @Override default List list(){ return getDao().list(); } + @Override default T getFirst(){ return getDao().getFirst(); } + @Override default Optional getFirstStream(){ return Optional.ofNullable(getFirst()); } @@ -32,6 +34,7 @@ default Long count(){ * @param page * @return */ + @Override default IJPage page(IJPage page){ return getDao().page(page); } @@ -41,10 +44,12 @@ default IJPage page(IJPage page){ * @param id * @return */ + @Override default T findById(Serializable id){ return getDao().findById(id); } + @Override default Optional findByIdStream(Serializable id){ return Optional.ofNullable(findById(id)); } diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/GetDaoCriteria.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/GetDaoCriteria.java new file mode 100644 index 0000000..aa02db9 --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/GetDaoCriteria.java @@ -0,0 +1,9 @@ +package com.github.xuejike.query.core.criteria; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public interface GetDaoCriteria { + DaoCriteria getDao(); +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/LoadRefCriteria.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/LoadRefCriteria.java new file mode 100644 index 0000000..c986d9e --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/LoadRefCriteria.java @@ -0,0 +1,16 @@ +package com.github.xuejike.query.core.criteria; + +import com.github.xuejike.query.core.enums.LoadRefMode; +import com.github.xuejike.query.core.tool.lambda.FieldFunction; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public interface LoadRefCriteria{ + R loadRef(F refField, Class entityCls, FieldFunction targetField, LoadRefMode mode); + default R loadRef(F refField, Class entityCls, FieldFunction targetField){ + return loadRef(refField, entityCls,targetField,LoadRefMode.noCache); + } + +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/MapCriteria.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/MapCriteria.java new file mode 100644 index 0000000..fce602a --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/MapCriteria.java @@ -0,0 +1,9 @@ +package com.github.xuejike.query.core.criteria; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public interface MapCriteria { + SelectDaoCriteria map(Class mapCls); +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/SelectDaoCriteria.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/SelectDaoCriteria.java new file mode 100644 index 0000000..aa1418f --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/criteria/SelectDaoCriteria.java @@ -0,0 +1,26 @@ +package com.github.xuejike.query.core.criteria; + +import java.io.Serializable; +import java.util.List; +import java.util.Optional; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public interface SelectDaoCriteria { + + + List list(); + + + T getFirst(); + + Optional getFirstStream(); + + IJPage page(IJPage page); + + T findById(Serializable id); + + Optional findByIdStream(Serializable id); +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/enums/LoadRefMode.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/enums/LoadRefMode.java new file mode 100644 index 0000000..ef83ad4 --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/enums/LoadRefMode.java @@ -0,0 +1,11 @@ +package com.github.xuejike.query.core.enums; + +import cn.hutool.cache.impl.NoCache; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public enum LoadRefMode { + noCache,useCache +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/exception/LambdaQueryException.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/exception/LambdaQueryException.java index 080fa32..8a016cb 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/exception/LambdaQueryException.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/exception/LambdaQueryException.java @@ -1,8 +1,10 @@ package com.github.xuejike.query.core.exception; +import cn.hutool.core.util.StrUtil; + public class LambdaQueryException extends RuntimeException { - public LambdaQueryException(String message) { - super(message); + public LambdaQueryException(String message,Object... args) { + super(StrUtil.format(message,args)); } public LambdaQueryException(String message, Throwable cause) { diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/interceptor/LambdaQueryInterceptor.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/interceptor/LambdaQueryInterceptor.java new file mode 100644 index 0000000..542e8cc --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/interceptor/LambdaQueryInterceptor.java @@ -0,0 +1,18 @@ +package com.github.xuejike.query.core.interceptor; + +import com.github.xuejike.query.core.base.BaseNestedWhereQuery; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public interface LambdaQueryInterceptor { + /** + * 查询拦截器 + * @param query + */ + default void selectInterceptor(BaseNestedWhereQuery query){ + + } + +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/BaseConditionsVo.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/BaseConditionsVo.java new file mode 100644 index 0000000..ef8e0cb --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/BaseConditionsVo.java @@ -0,0 +1,23 @@ +package com.github.xuejike.query.core.po; + +import com.github.xuejike.query.core.enums.OrderType; +import lombok.Data; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@Data +public class BaseConditionsVo { + protected QueryInfo where =new QueryInfo() ; + protected List selectList = new LinkedList<>(); + protected List excludeList = new LinkedList<>(); + protected Map orderMap = new ConcurrentHashMap<>(); + protected Map> refClassMap = new ConcurrentHashMap<>(); + +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/JPage.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/JPage.java index 52dfa83..1f059a5 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/JPage.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/JPage.java @@ -17,5 +17,14 @@ public class JPage implements IJPage { private int pageNo; private boolean haveTotal; - + public JPage() { + } + public JPage(int pageNo,int pageSize) { + this(pageNo,pageSize,true); + } + public JPage(int pageNo,int pageSize, boolean haveTotal) { + this.pageSize = pageSize; + this.pageNo = pageNo; + this.haveTotal = haveTotal; + } } diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/LoadRefInfo.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/LoadRefInfo.java new file mode 100644 index 0000000..f8b0cd2 --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/LoadRefInfo.java @@ -0,0 +1,16 @@ +package com.github.xuejike.query.core.po; + +import com.github.xuejike.query.core.enums.LoadRefMode; +import com.github.xuejike.query.core.tool.lambda.FieldFunction; +import lombok.Data; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@Data +public class LoadRefInfo { + private Class refClass; + private LoadRefMode mode; + private FieldInfo targetField; +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/QueryVo.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/QueryVo.java new file mode 100644 index 0000000..0b6653c --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/po/QueryVo.java @@ -0,0 +1,61 @@ +package com.github.xuejike.query.core.po; + +import com.github.xuejike.query.core.enums.OrderType; +import com.github.xuejike.query.core.enums.WhereOperation; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public class QueryVo { + protected QueryInfo where; + protected List selectList = new LinkedList<>(); + protected List excludeList = new LinkedList<>(); + protected Map orderMap = new ConcurrentHashMap<>(); + protected Map> refClassMap = new ConcurrentHashMap<>(); + + public QueryInfo getWhere() { + return where; + } + + public void setWhere(QueryInfo where) { + this.where = where; + } + + public List getSelectList() { + return selectList; + } + + public void setSelectList(List selectList) { + this.selectList = selectList; + } + + public List getExcludeList() { + return excludeList; + } + + public void setExcludeList(List excludeList) { + this.excludeList = excludeList; + } + + public Map getOrderMap() { + return orderMap; + } + + public void setOrderMap(Map orderMap) { + this.orderMap = orderMap; + } + + public Map> getRefClassMap() { + return refClassMap; + } + + public void setRefClassMap(Map> refClassMap) { + this.refClassMap = refClassMap; + } +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/tool/ELParseTool.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/tool/ELParseTool.java new file mode 100644 index 0000000..4c38f51 --- /dev/null +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/tool/ELParseTool.java @@ -0,0 +1,85 @@ +package com.github.xuejike.query.core.tool; + +import cn.hutool.cache.CacheUtil; +import cn.hutool.cache.impl.LFUCache; +import cn.hutool.core.annotation.AnnotationUtil; +import cn.hutool.core.lang.SimpleCache; +import cn.hutool.core.lang.func.Func0; +import cn.hutool.core.util.ReflectUtil; +import com.github.xuejike.query.core.annotation.RefValue; +import com.github.xuejike.query.core.annotation.SetRefValue; +import com.github.xuejike.query.core.exception.LambdaQueryException; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; + +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public class ELParseTool { + static ExpressionParser spelExpressionParser = new SpelExpressionParser(); + + static LFUCache expCache = CacheUtil.newLFUCache(300); + static SimpleCache setRefValueCache = new SimpleCache<>(); + static SimpleCache,Map> refValueCache = new SimpleCache<>(); + + public static T parseEl(String expStr, Map varMap,Class returnCls){ + EvaluationContext context = new StandardEvaluationContext(); + for (Map.Entry entry : varMap.entrySet()) { + context.setVariable(entry.getKey(),entry.getValue()); + } + + Expression expression = expCache.get(expStr, () -> spelExpressionParser.parseExpression(expStr)); + return expression.getValue(context,returnCls); + } + + + + public static String getSetRefValue(Class voCls,String fieldName){ + return setRefValueCache.get(voCls.getName() + "_" + fieldName, () -> { + Field field = ReflectUtil.getField(voCls, fieldName); + SetRefValue annotation = AnnotationUtil.getAnnotation(field, SetRefValue.class); + if (annotation == null){ + throw new LambdaQueryException("{} -> {} 未设置 @SetRefValue",voCls.getName(),fieldName); + } + return annotation.value(); + }); + } + public static Map getRefValues(Class voCls){ + return refValueCache.get(voCls, () -> { + Field[] fields = ReflectUtil.getFields(voCls); + ConcurrentHashMap map = new ConcurrentHashMap<>(fields.length); + for (Field field : fields) { + RefValue refValue = AnnotationUtil.getAnnotation(field, RefValue.class); + if (refValue != null){ + field.setAccessible(true); + map.put(field,refValue.value()); + } + } + + return map; + }); + } + + public static void parseRefValue(Class voCls){ + Field[] fields = ReflectUtil.getFields(voCls); + Map fieldElMap = new ConcurrentHashMap<>(5); + for (Field field : fields) { + RefValue value = AnnotationUtil.getAnnotation(field, RefValue.class); + if (value != null){ + fieldElMap.put(field.getName(),value.value()); + } + } + } + + +} diff --git a/lambda-query-core/src/main/java/com/github/xuejike/query/core/tool/lambda/LambdaTool.java b/lambda-query-core/src/main/java/com/github/xuejike/query/core/tool/lambda/LambdaTool.java index bb140a4..c24bc01 100644 --- a/lambda-query-core/src/main/java/com/github/xuejike/query/core/tool/lambda/LambdaTool.java +++ b/lambda-query-core/src/main/java/com/github/xuejike/query/core/tool/lambda/LambdaTool.java @@ -31,6 +31,7 @@ public static String methodToProperty(String name) { } protected static Map> cache = new ConcurrentHashMap<>(); + public static FieldInfo getFieldInfo(FieldFunction fieldFun){ Class cls = fieldFun.getClass(); return Optional.ofNullable(cache.get(cls)) diff --git a/lambda-query-core/src/test/java/Test.java b/lambda-query-core/src/test/java/Test.java deleted file mode 100644 index 4f3c0c5..0000000 --- a/lambda-query-core/src/test/java/Test.java +++ /dev/null @@ -1,20 +0,0 @@ -import com.alibaba.fastjson.JSON; -import com.github.xuejike.query.core.po.QueryInfo; -import com.github.xuejike.query.core.tool.lambda.CascadeField; - -/** - * @author xuejike - * @date 2020/12/18 - */ -public class Test { - @org.junit.Test - public void t(){ - - - - } - - public static CascadeField cascadeField(){ - return new CascadeField<>(); - } -} diff --git a/lambda-query-core/src/test/java/TestBean.java b/lambda-query-core/src/test/java/TestBean.java deleted file mode 100644 index 3a3390c..0000000 --- a/lambda-query-core/src/test/java/TestBean.java +++ /dev/null @@ -1,25 +0,0 @@ -import lombok.Data; - -import java.util.List; - -/** - * @author xuejike - * @date 2020/12/18 - */ -@Data -public class TestBean { - private String name; - private SubNameCls sub; - private List subList; - private SubNameCls[] subArray; - - @Data - public static class SubNameCls{ - private String subName; - private Sub1NameCls sub; - } - @Data - public static class Sub1NameCls{ - private String subName; - } -} diff --git a/lambda-query-core/src/test/java/TestMain.java b/lambda-query-core/src/test/java/TestMain.java new file mode 100644 index 0000000..f018f2c --- /dev/null +++ b/lambda-query-core/src/test/java/TestMain.java @@ -0,0 +1,80 @@ +import cn.hutool.core.util.ReflectUtil; +import com.github.xuejike.query.core.tool.ELParseTool; +import net.sf.cglib.beans.BeanCopier; +import net.sf.cglib.beans.BeanGenerator; +import net.sf.cglib.reflect.FastClass; +import org.junit.jupiter.api.Test; +import vo.TestSourceVo; +import vo.TestVo; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public class TestMain { + + private long forLen; + + @Test + public void parseClsTest(){ +// ELParseTool.parseSetRefValue(TestVo.class); +// ELParseTool.parseRefValue(TestVo.class); + Map refValues = ELParseTool.getRefValues(TestVo.class); + String subId = ELParseTool.getSetRefValue(TestVo.class, "subId"); + System.out.println(subId); + } + @Test + public void xnTest() throws Throwable { + + Long begin = System.currentTimeMillis(); + forLen = 1000000000L; + for (long i = 0; i < forLen; i++) { + TestVo testVo = new TestVo(); + testVo.setName("1111111"); + } + System.out.println("-->"+(System.currentTimeMillis()-begin)); + Field nameField = ReflectUtil.getField(TestVo.class, "name"); + nameField.setAccessible(true); + MethodHandles.Lookup lookup=MethodHandles.lookup(); + MethodHandle mh=lookup.findConstructor(TestVo.class, MethodType.methodType(void.class)); + +// System.out.println(p); + Constructor constructor = ReflectUtil.getConstructor(TestVo.class); + begin = System.currentTimeMillis(); + + for (long i = 0; i < forLen; i++) { +// TestVo testVo = new TestVo(); +// TestVo testVo = (TestVo)mh.invokeExact(); +// TestVo testVo = constructor.newInstance(); + TestVo testVo = ReflectUtil.newInstance(TestVo.class); +// ReflectUtil.setFieldValue(testVo,nameField,"1111111"); +// nameField.set(testVo,"1111111"); + } + System.out.println("-->"+(System.currentTimeMillis()-begin)); + + + BeanCopier beanCopier = BeanCopier.create(TestSourceVo.class, TestVo.class,true); + + FastClass fastClass = FastClass.create(TestVo.class); + begin = System.currentTimeMillis(); + for (long i = 0; i < forLen; i++) { +// TestVo testVo = new TestVo(); +// TestVo testVo = (TestVo)mh.invokeExact(); +// TestVo testVo = constructor.newInstance(); + Object o = fastClass.newInstance(); + +// ReflectUtil.setFieldValue(testVo,nameField,"1111111"); +// nameField.set(testVo,"1111111"); + } + System.out.println("-->"+(System.currentTimeMillis()-begin)); + + } +} diff --git a/lambda-query-core/src/test/java/vo/TestSourceVo.java b/lambda-query-core/src/test/java/vo/TestSourceVo.java new file mode 100644 index 0000000..0731435 --- /dev/null +++ b/lambda-query-core/src/test/java/vo/TestSourceVo.java @@ -0,0 +1,19 @@ +package vo; + +import com.github.xuejike.query.core.annotation.RefValue; +import com.github.xuejike.query.core.annotation.SetRefValue; +import lombok.Data; + +/** + * @author xuejike + * @date 2021/1/11 + */ +@Data +public class TestSourceVo { + private Long id; + private String name; + @SetRefValue("sub") + private Long subId; + @RefValue("#sub.name") + private String subName; +} diff --git a/lambda-query-core/src/test/java/vo/TestVo.java b/lambda-query-core/src/test/java/vo/TestVo.java new file mode 100644 index 0000000..8b9f867 --- /dev/null +++ b/lambda-query-core/src/test/java/vo/TestVo.java @@ -0,0 +1,20 @@ +package vo; + + +import com.github.xuejike.query.core.annotation.RefValue; +import com.github.xuejike.query.core.annotation.SetRefValue; +import lombok.Data; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@Data +public class TestVo { + private Long id; + private String name; + @SetRefValue("sub") + private Long subId; + @RefValue("#sub.name") + private String subName; +} diff --git a/lambda-query-http-starter/pom.xml b/lambda-query-http-starter/pom.xml new file mode 100644 index 0000000..14bd98b --- /dev/null +++ b/lambda-query-http-starter/pom.xml @@ -0,0 +1,50 @@ + + + + lambda-query + com.github.xuejike + 1.0.2-SNAPSHOT + + 4.0.0 + + lambda-query-http-starter + + + 8 + 8 + + + + org.springframework.boot + spring-boot-starter-web + 2.2.8.RELEASE + compile + + + org.springframework.boot + spring-boot-configuration-processor + true + compile + 2.2.11.RELEASE + + + org.springframework.cloud + spring-cloud-starter-netflix-ribbon + 2.2.6.RELEASE + compile + + + org.springframework.boot + spring-boot-starter + 2.2.11.RELEASE + compile + + + com.github.xuejike + lambda-query-http + ${query.version} + + + \ No newline at end of file diff --git a/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/AutoConfig.java b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/AutoConfig.java new file mode 100644 index 0000000..ec10ea1 --- /dev/null +++ b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/AutoConfig.java @@ -0,0 +1,36 @@ +package com.github.xuejike.query.http.server.starter; + +import com.github.xuejike.query.http.LambdaQueryHttpConfig; +import com.github.xuejike.query.http.client.HttpClientFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +/** + * @author xuejike + * @date 2021/1/4 + */ +@Configuration +@Import({HttpServiceConfig.class}) +public class AutoConfig { + + @Bean + @ConditionalOnBean(ServiceInstanceChooser.class) + public ServiceSelect serviceSelect(ServiceInstanceChooser loadBalancer){ + return new ServiceSelect(loadBalancer); + } + @Bean + @ConditionalOnBean(ServiceSelect.class) + public LbHttpClient lbHttpClient(ServiceSelect serviceSelect){ + LbHttpClient lbHttpClient = new LbHttpClient(serviceSelect); + LambdaQueryHttpConfig.getInstance().setHttpClient(lbHttpClient); + return lbHttpClient; + } + @Bean + public HttpClientFactory httpClientFactory(){ + return new HttpClientFactory(); + } + +} diff --git a/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/HttpServiceConfig.java b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/HttpServiceConfig.java new file mode 100644 index 0000000..c06dd1f --- /dev/null +++ b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/HttpServiceConfig.java @@ -0,0 +1,92 @@ +package com.github.xuejike.query.http.server.starter; + +import cn.hutool.core.convert.Convert; +import com.alibaba.fastjson.JSON; +import com.github.xuejike.query.core.po.JPage; +import com.github.xuejike.query.http.LambdaQueryHttpConfig; +import com.github.xuejike.query.http.service.HttpServiceParse; +import com.github.xuejike.query.http.vo.HttpBodyVo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.web.servlet.function.RouterFunction; +import org.springframework.web.servlet.function.RouterFunctions; +import org.springframework.web.servlet.function.ServerRequest; +import org.springframework.web.servlet.function.ServerResponse; + +import javax.annotation.PostConstruct; +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.List; + +/** + * @author xuejike + * @date 2021/1/4 + */ +@Configuration +@Slf4j +@Import(JkQueryHttpProperties.class) +public class HttpServiceConfig { + @Autowired + JkQueryHttpProperties properties; + private String lambdaPath; + @PostConstruct + protected void init(){ + LambdaQueryHttpConfig.getInstance().setServerBasePath(properties.getHttpServicePath()); + } + @Bean + public RouterFunction initServer(){ + RouterFunctions.Builder route = RouterFunctions.route(); + lambdaPath = properties.getHttpServicePath(); + route.POST(lambdaPath + "/{service}/list", serverRequest -> { + String serviceName = serverRequest.pathVariable("service"); + HttpBodyVo body = readBody(serverRequest); + HttpServiceParse serviceParse = new HttpServiceParse(serviceName, body); + List list = serviceParse.list(); + return ServerResponse.accepted().body(list); + }); + route.POST(lambdaPath + "/{service}/first", serverRequest -> { + String serviceName = serverRequest.pathVariable("service"); + HttpBodyVo body = readBody(serverRequest); + HttpServiceParse serviceParse = new HttpServiceParse(serviceName, body); + Object list = serviceParse.getFirst(); + return ServerResponse.accepted().body(list); + }); + route.POST(lambdaPath + "/{service}/count", serverRequest -> { + String serviceName = serverRequest.pathVariable("service"); + HttpBodyVo body = readBody(serverRequest); + HttpServiceParse serviceParse = new HttpServiceParse(serviceName, body); + Object list = serviceParse.count(); + return ServerResponse.accepted().body(list); + }); + route.POST(lambdaPath + "/{service}/page", serverRequest -> { + String serviceName = serverRequest.pathVariable("service"); + HttpBodyVo body = readBody(serverRequest); + int pageNo = Convert.toInt(serverRequest.param("pageNo").orElse("0")); + int pageSize = Convert.toInt(serverRequest.param("pageSize").orElse("10")); + Boolean haveTotal = serverRequest.param("haveTotal").map(it->Convert.toBool(it,false)).orElse(false); + + HttpServiceParse serviceParse = new HttpServiceParse(serviceName, body); + Object list = serviceParse.page(new JPage(pageNo,pageSize,haveTotal)); + return ServerResponse.accepted().body(list); + }); + route.POST(lambdaPath + "/{service}/findById", serverRequest -> { + String serviceName = serverRequest.pathVariable("service"); + HttpBodyVo body = readBody(serverRequest); + HttpServiceParse serviceParse = new HttpServiceParse(serviceName, body); + String id = serverRequest.param("id").orElse(null); + Object list = serviceParse.findById(id); + return ServerResponse.accepted().body(list); + }); + return route.build(); + } + + + public static HttpBodyVo readBody(ServerRequest request) throws ServletException, IOException { + String body = request.body(String.class); + HttpBodyVo httpBodyVo = JSON.parseObject(body, HttpBodyVo.class); + return httpBodyVo; + } +} diff --git a/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/JkQueryHttpProperties.java b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/JkQueryHttpProperties.java new file mode 100644 index 0000000..1062207 --- /dev/null +++ b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/JkQueryHttpProperties.java @@ -0,0 +1,15 @@ +package com.github.xuejike.query.http.server.starter; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author xuejike + * @date 2021/1/4 + */ +@ConfigurationProperties("jk-query.http") +@Data +public class JkQueryHttpProperties { + private String httpServicePath = "/lambda"; + +} diff --git a/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/LbHttpClient.java b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/LbHttpClient.java new file mode 100644 index 0000000..5953f97 --- /dev/null +++ b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/LbHttpClient.java @@ -0,0 +1,32 @@ +package com.github.xuejike.query.http.server.starter; + +import cn.hutool.core.collection.CollUtil; +import com.github.xuejike.query.http.client.HuToolHttpClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.net.URI; +import java.util.Map; +import java.util.Optional; + +/** + * @author xuejike + * @date 2021/1/4 + */ + +public class LbHttpClient extends HuToolHttpClient { + ServiceSelect serviceSelect; + + public LbHttpClient(ServiceSelect serviceSelect) { + this.serviceSelect = serviceSelect; + } + + @Override + public String post(String url, Map param, String body) { + + + URI uri = serviceSelect.selectUrl(url); + return super.post(uri.toString(), param, body); + } +} diff --git a/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/ServiceSelect.java b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/ServiceSelect.java new file mode 100644 index 0000000..c9e5b0b --- /dev/null +++ b/lambda-query-http-starter/src/main/java/com/github/xuejike/query/http/server/starter/ServiceSelect.java @@ -0,0 +1,42 @@ +package com.github.xuejike.query.http.server.starter; + +import cn.hutool.core.util.URLUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; +import org.springframework.stereotype.Component; +import org.springframework.web.util.UriComponentsBuilder; + +import java.net.URI; + +/** + * @author xuejike + * @date 2020/12/25 + */ +@Slf4j +public class ServiceSelect { + + ServiceInstanceChooser loadBalancer; + + public ServiceSelect(ServiceInstanceChooser loadBalancer) { + this.loadBalancer = loadBalancer; + } + + public URI selectUrl(String authUrl) { + URI uri = URLUtil.toURI(authUrl); + if ("lb".equals(uri.getScheme())){ + ServiceInstance choose = loadBalancer.choose(uri.getHost()); + if (choose == null){ + log.error(""); + return null; + }else{ + uri = UriComponentsBuilder.fromUri(uri) + .scheme("http") + .host(choose.getHost()) + .port(choose.getPort()).build().toUri(); + } + } + return uri; + } +} diff --git a/lambda-query-http-starter/src/main/resources/META-INF/spring.factories b/lambda-query-http-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..e992592 --- /dev/null +++ b/lambda-query-http-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.github.xuejike.query.http.server.starter.AutoConfig \ No newline at end of file diff --git a/lambda-query-http/pom.xml b/lambda-query-http/pom.xml new file mode 100644 index 0000000..68e5761 --- /dev/null +++ b/lambda-query-http/pom.xml @@ -0,0 +1,31 @@ + + + + lambda-query + com.github.xuejike + 1.0.2-SNAPSHOT + + 4.0.0 + + lambda-query-http + + + 8 + 8 + + + + com.github.xuejike + lambda-query-core + ${query.version} + + + cn.hutool + hutool-http + ${hutool.version} + + + + \ No newline at end of file diff --git a/lambda-query-http/src/main/java/com/github/xuejike/query/http/LambdaQueryHttpConfig.java b/lambda-query-http/src/main/java/com/github/xuejike/query/http/LambdaQueryHttpConfig.java new file mode 100644 index 0000000..b11e2b7 --- /dev/null +++ b/lambda-query-http/src/main/java/com/github/xuejike/query/http/LambdaQueryHttpConfig.java @@ -0,0 +1,46 @@ +package com.github.xuejike.query.http; + +import com.github.xuejike.query.http.client.HttpClient; +import com.github.xuejike.query.http.client.HuToolHttpClient; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public class LambdaQueryHttpConfig { + private String serverBasePath="/lambda/"; + + private Map> serviceMap = new ConcurrentHashMap<>(); + private HttpClient httpClient = new HuToolHttpClient(); + public static LambdaQueryHttpConfig instance = new LambdaQueryHttpConfig(); + + public static LambdaQueryHttpConfig getInstance() { + return instance; + } + public LambdaQueryHttpConfig registerService(String serviceName,Class entityCls){ + serviceMap.put(serviceName,entityCls); + return this; + } + public Class getServiceEntityCls(String serviceName){ + return serviceMap.get(serviceName); + } + + public HttpClient getHttpClient() { + return httpClient; + } + + public void setHttpClient(HttpClient httpClient) { + this.httpClient = httpClient; + } + + public String getServerBasePath() { + return serverBasePath; + } + + public void setServerBasePath(String serverBasePath) { + this.serverBasePath = serverBasePath; + } +} diff --git a/lambda-query-http/src/main/java/com/github/xuejike/query/http/annotation/HttpDaoSelect.java b/lambda-query-http/src/main/java/com/github/xuejike/query/http/annotation/HttpDaoSelect.java new file mode 100644 index 0000000..21d04e2 --- /dev/null +++ b/lambda-query-http/src/main/java/com/github/xuejike/query/http/annotation/HttpDaoSelect.java @@ -0,0 +1,22 @@ +package com.github.xuejike.query.http.annotation; + +import com.github.xuejike.query.core.annotation.DaoSelect; +import com.github.xuejike.query.http.client.HttpClientDao; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@DaoSelect(daoCls = HttpClientDao.class) +public @interface HttpDaoSelect { + String path() default ""; + String serverAddress() default ""; + +} diff --git a/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HttpClient.java b/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HttpClient.java new file mode 100644 index 0000000..e45d9f3 --- /dev/null +++ b/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HttpClient.java @@ -0,0 +1,11 @@ +package com.github.xuejike.query.http.client; + +import java.util.Map; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public interface HttpClient { + String post(String url, Map param, String body); +} diff --git a/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HttpClientDao.java b/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HttpClientDao.java new file mode 100644 index 0000000..fbec916 --- /dev/null +++ b/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HttpClientDao.java @@ -0,0 +1,124 @@ +package com.github.xuejike.query.http.client; + +import cn.hutool.core.annotation.AnnotationUtil; +import cn.hutool.core.convert.Convert; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.github.xuejike.query.core.base.BaseDao; +import com.github.xuejike.query.core.criteria.IJPage; +import com.github.xuejike.query.core.exception.LambdaQueryException; +import com.github.xuejike.query.http.LambdaQueryHttpConfig; +import com.github.xuejike.query.http.annotation.HttpDaoSelect; +import com.github.xuejike.query.http.vo.HttpBodyVo; + + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public class HttpClientDao extends BaseDao { + + private final String server; + + public HttpClientDao(Class entityCls) { + super(entityCls); + HttpDaoSelect daoSelect = AnnotationUtil.getAnnotation(entityCls, HttpDaoSelect.class); + server = daoSelect.serverAddress()+"/"+daoSelect.path(); + + } + + @Override + public HttpBodyVo buildQuery() { + return buildHttpBody(); + } + + + protected String httpPost(String method, Map param){ + HttpClient httpClient = LambdaQueryHttpConfig.getInstance().getHttpClient(); + String post = httpClient.post(server + "/" + method, param, JSON.toJSONString(buildHttpBody())); + return post; + } + + protected HttpBodyVo buildHttpBody(){ + HttpBodyVo bodyVo = new HttpBodyVo(); + bodyVo.setExcludeList(baseWhereQuery.getExcludeList()); + bodyVo.setSelectList(baseWhereQuery.getSelectList()); + bodyVo.setOrderMap(baseWhereQuery.getOrderMap()); + bodyVo.setWhere(baseWhereQuery.buildQueryInfo()); + + return bodyVo; + } + + @Override + public List list() { + + String list = httpPost("list", new HashMap<>(0)); + return JSON.parseArray(list,entityCls); + } + + @Override + public T getFirst() { + String list = httpPost("first", new HashMap<>(0)); + return JSON.parseObject(list,entityCls); + } + + + @Override + public Long count() { + String list = httpPost("count", new HashMap<>(0)); + return Convert.toLong(list); + } + + @Override + public IJPage page(IJPage page) { + HashMap map = new HashMap<>(3); + map.put("pageNo",page.getPageNo()); + map.put("pageSize",page.getPageSize()); + map.put("haveTotal",page.isHaveTotal()); + String list = httpPost("page",map); + + return JSON.parseObject(list,new TypeReference>(){}); + } + + @Override + public T findById(Serializable id) { + HashMap map = new HashMap<>(3); + map.put("id",id); + + + String list = httpPost("findById",map); + + return JSON.parseObject(list,entityCls); + } + + + @Override + public boolean updateById(T entity) { + throw new LambdaQueryException("http 不支持 updateById"); + } + + @Override + public T insert(T entity) { + throw new LambdaQueryException("http 不支持 insert"); + } + + @Override + public Long updateFindAll() { + throw new LambdaQueryException("http 不支持 updateFindAll"); + } + + @Override + public boolean removeById(Serializable id) { + throw new LambdaQueryException("http 不支持 removeById"); + } + + @Override + public long removeQueryAll() { + throw new LambdaQueryException("http 不支持 removeQueryAll"); + } +} diff --git a/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HttpClientFactory.java b/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HttpClientFactory.java new file mode 100644 index 0000000..bba7ce1 --- /dev/null +++ b/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HttpClientFactory.java @@ -0,0 +1,19 @@ +package com.github.xuejike.query.http.client; + +import com.github.xuejike.query.core.base.BaseDao; +import com.github.xuejike.query.core.config.DaoFactory; + +/** + * @author xuejike + * @date 2020/12/31 + */ +public class HttpClientFactory extends DaoFactory { + public HttpClientFactory() { + super(HttpClientDao.class); + } + + @Override + public BaseDao createDao(Class entityCls) { + return new HttpClientDao<>(entityCls); + } +} diff --git a/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HuToolHttpClient.java b/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HuToolHttpClient.java new file mode 100644 index 0000000..b8cea8a --- /dev/null +++ b/lambda-query-http/src/main/java/com/github/xuejike/query/http/client/HuToolHttpClient.java @@ -0,0 +1,34 @@ +package com.github.xuejike.query.http.client; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.URLUtil; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; + +import java.net.URI; +import java.util.Map; +import java.util.Optional; + +/** + * @author xuejike + * @date 2020/12/31 + */ + +@Slf4j +public class HuToolHttpClient implements HttpClient{ + @Override + public String post(String url, Map param, String body) { + StringBuilder urlBuilder = new StringBuilder(url).append("?"); + Optional.ofNullable(param).filter(CollUtil::isNotEmpty).flatMap(it->{ + it.forEach((key, value) -> urlBuilder.append(key).append("=").append(value)); + return Optional.empty(); + }); + URI uri = URLUtil.toURI(urlBuilder.toString()); + String newUrl = uri.normalize().toString(); + log.info("http POST -> {} ", newUrl); + log.info(" body->{} ",body); + String post = HttpUtil.post(newUrl, body); + return post; + } +} diff --git a/lambda-query-http/src/main/java/com/github/xuejike/query/http/service/HttpServiceParse.java b/lambda-query-http/src/main/java/com/github/xuejike/query/http/service/HttpServiceParse.java new file mode 100644 index 0000000..a9e5900 --- /dev/null +++ b/lambda-query-http/src/main/java/com/github/xuejike/query/http/service/HttpServiceParse.java @@ -0,0 +1,41 @@ +package com.github.xuejike.query.http.service; + +import cn.hutool.core.lang.Assert; +import com.github.xuejike.query.core.JLambdaQuery; +import com.github.xuejike.query.core.JQuerys; +import com.github.xuejike.query.core.base.BaseDao; +import com.github.xuejike.query.core.criteria.DaoCriteria; +import com.github.xuejike.query.http.LambdaQueryHttpConfig; +import com.github.xuejike.query.http.vo.HttpBodyVo; + +/** + * @author xuejike + * @date 2021/1/4 + */ +public class HttpServiceParse implements DaoCriteria { + private String serviceName; + private HttpBodyVo httpBodyVo; + private JLambdaQuery lambdaQuery; + + + public HttpServiceParse(String serviceName, HttpBodyVo httpBodyVo) { + this.serviceName = serviceName; + this.httpBodyVo = httpBodyVo; + init(); + } + private void init(){ + Class serviceEntityCls = LambdaQueryHttpConfig.getInstance().getServiceEntityCls(serviceName); + Assert.notNull(serviceEntityCls,"未发现服务"); + lambdaQuery = JQuerys.lambdaQuery(serviceEntityCls); + BaseDao baseDao = (BaseDao) lambdaQuery.getDao(); + baseDao.setBaseConditionsVo(httpBodyVo); + + + } + + + @Override + public DaoCriteria getDao() { + return (DaoCriteria) lambdaQuery.getDao(); + } +} diff --git a/lambda-query-http/src/main/java/com/github/xuejike/query/http/vo/HttpBodyVo.java b/lambda-query-http/src/main/java/com/github/xuejike/query/http/vo/HttpBodyVo.java new file mode 100644 index 0000000..2b9b528 --- /dev/null +++ b/lambda-query-http/src/main/java/com/github/xuejike/query/http/vo/HttpBodyVo.java @@ -0,0 +1,24 @@ +package com.github.xuejike.query.http.vo; + +import com.github.xuejike.query.core.enums.OrderType; +import com.github.xuejike.query.core.enums.WhereOperation; +import com.github.xuejike.query.core.po.BaseConditionsVo; +import com.github.xuejike.query.core.po.FieldInfo; +import com.github.xuejike.query.core.po.LoadRefInfo; +import com.github.xuejike.query.core.po.QueryInfo; +import lombok.Data; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@Data +public class HttpBodyVo extends BaseConditionsVo { + + +} diff --git a/lambda-query-mongo-starter/pom.xml b/lambda-query-mongo-starter/pom.xml index 4745fb8..3225d97 100644 --- a/lambda-query-mongo-starter/pom.xml +++ b/lambda-query-mongo-starter/pom.xml @@ -5,7 +5,7 @@ lambda-query com.github.xuejike - 1.0.1 + 1.0.2-SNAPSHOT 4.0.0 diff --git a/lambda-query-mongo/pom.xml b/lambda-query-mongo/pom.xml index 6cac8be..7599056 100644 --- a/lambda-query-mongo/pom.xml +++ b/lambda-query-mongo/pom.xml @@ -5,12 +5,12 @@ lambda-query com.github.xuejike - 1.0.1 + 1.0.2-SNAPSHOT lambda-query-mongo lambda-query-mongo Demo project for Spring Boot - 1.0.1 + 1.0.2-SNAPSHOT @@ -25,6 +25,7 @@ 2.2.11.RELEASE compile + diff --git a/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoDao.java b/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoDao.java index 49bf06f..6f2155a 100644 --- a/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoDao.java +++ b/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoDao.java @@ -26,7 +26,7 @@ * @author xuejike * @date 2020/12/18 */ -public class MongoDao extends BaseDao { +public class MongoDao extends BaseDao { MongoTemplate mongoTemplate; @@ -38,37 +38,69 @@ public MongoDao(MongoTemplate mongoTemplate, Class entityCls) { } - private Query buildQuery(){ - Query builder = MongoQueryBuilder.builder(baseWhereQuery.buildQueryInfo()); + @Override + public Query buildQuery(){ + Query builder = new Query(); + if (baseConditionsVo != null){ + MongoQueryBuilder.builder(builder,baseConditionsVo.getWhere()); + if (CollUtil.isNotEmpty(baseConditionsVo.getSelectList())){ + List list = baseConditionsVo.getSelectList(); + builderSelectedField(builder, list); + } + if (CollUtil.isNotEmpty(baseConditionsVo.getExcludeList())){ + List list = baseConditionsVo.getExcludeList(); + builderExclude(builder, list); + } + if (CollUtil.isNotEmpty(baseConditionsVo.getOrderMap())){ + Map orderMap = baseConditionsVo.getOrderMap(); + builderOrder(builder, orderMap); + } + } + MongoQueryBuilder.builder(builder,baseWhereQuery.buildQueryInfo()); + + if (CollUtil.isNotEmpty(baseWhereQuery.getSelectList())){ - Field fields = builder.fields(); List list = baseWhereQuery.getSelectList(); - for (FieldInfo info : list) { - fields.include(MongoQueryBuilder.buildField(info)); - } + builderSelectedField(builder,list); } if (CollUtil.isNotEmpty(baseWhereQuery.getExcludeList())){ - Field fields = builder.fields(); List list = baseWhereQuery.getExcludeList(); - for (FieldInfo info : list) { - fields.exclude(MongoQueryBuilder.buildField(info)); - } + builderExclude(builder, list); } if (CollUtil.isNotEmpty(baseWhereQuery.getOrderMap())){ Map orderMap = baseWhereQuery.getOrderMap(); - List orderList = orderMap.entrySet().stream().map(it -> { - if (it.getValue() == OrderType.desc) { - return Sort.Order.desc(MongoQueryBuilder.buildField(it.getKey())); - } else { - return Sort.Order.asc(MongoQueryBuilder.buildField(it.getKey())); - } - }).collect(Collectors.toList()); - builder.with(Sort.by(orderList)); + builderOrder(builder, orderMap); } return builder; } + private void builderOrder(Query builder, Map orderMap) { + List orderList = orderMap.entrySet().stream().map(it -> { + if (it.getValue() == OrderType.desc) { + return Sort.Order.desc(MongoQueryBuilder.buildField(it.getKey())); + } else { + return Sort.Order.asc(MongoQueryBuilder.buildField(it.getKey())); + } + }).collect(Collectors.toList()); + builder.with(Sort.by(orderList)); + } + + private void builderExclude(Query builder, List list) { + Field fields = builder.fields(); + for (FieldInfo info : list) { + fields.exclude(MongoQueryBuilder.buildField(info)); + } + } + + private void builderSelectedField(Query builder, List list) { + Field fields = builder.fields(); + + for (FieldInfo info : list) { + fields.include(MongoQueryBuilder.buildField(info)); + } + } + @Override public DaoCriteria getDao() { return this; @@ -90,11 +122,8 @@ public T getFirst() { @Override public List list() { - if (baseWhereQuery.isEmpty()){ - return mongoTemplate.findAll(entityCls); - }else{ - return mongoTemplate.find(buildQuery(),entityCls); - } + return mongoTemplate.find(buildQuery(),entityCls); + } @Override diff --git a/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoDaoFactory.java b/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoDaoFactory.java index 29ad234..0550879 100644 --- a/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoDaoFactory.java +++ b/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoDaoFactory.java @@ -1,5 +1,6 @@ package com.github.xuejike.query.mongo; +import com.github.xuejike.query.core.base.BaseDao; import com.github.xuejike.query.core.config.DaoFactory; import com.github.xuejike.query.core.config.JkQueryConfig; import com.github.xuejike.query.core.criteria.DaoCriteria; @@ -19,15 +20,12 @@ public class MongoDaoFactory extends DaoFactory { public MongoDaoFactory(MongoTemplate mongoTemplate) { super(MongoDao.class); this.mongoTemplate = mongoTemplate; - init(); - } - public void init(){ - JkQueryConfig.getInstance().addDaoFactory(this); + } @Override - public DaoCriteria createDao(Class entityCls) { + public BaseDao createDao(Class entityCls) { return new MongoDao<>(mongoTemplate,entityCls); } } diff --git a/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoQueryBuilder.java b/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoQueryBuilder.java index 14010f7..5f243ec 100644 --- a/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoQueryBuilder.java +++ b/lambda-query-mongo/src/main/java/com/github/xuejike/query/mongo/MongoQueryBuilder.java @@ -23,6 +23,12 @@ public class MongoQueryBuilder { public static Query builder(QueryInfo queryInfo) { Query query = new Query(); + builder(query,queryInfo); + + return query; + } + + public static void builder( Query query,QueryInfo queryInfo) { List and = queryInfo.getAnd(); for (QueryItem item : and) { Criteria where = Criteria.where(buildField(item.getField())); @@ -35,8 +41,6 @@ public static Query builder(QueryInfo queryInfo) { query.addCriteria(criteria.orOperator(criteriaArray)); } - - return query; } diff --git a/lambda-query-mybatis-plus-starter/pom.xml b/lambda-query-mybatis-plus-starter/pom.xml index 49e5db5..7b5f913 100644 --- a/lambda-query-mybatis-plus-starter/pom.xml +++ b/lambda-query-mybatis-plus-starter/pom.xml @@ -5,7 +5,7 @@ lambda-query com.github.xuejike - 1.0.1 + 1.0.2-SNAPSHOT 4.0.0 diff --git a/lambda-query-mybatis-plus/pom.xml b/lambda-query-mybatis-plus/pom.xml index 73157cc..8c99bd7 100644 --- a/lambda-query-mybatis-plus/pom.xml +++ b/lambda-query-mybatis-plus/pom.xml @@ -5,7 +5,7 @@ lambda-query com.github.xuejike - 1.0.1 + 1.0.2-SNAPSHOT 4.0.0 @@ -37,7 +37,8 @@ cn.hutool hutool-extra - 5.5.2 + ${hutool.version} + \ No newline at end of file diff --git a/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusBuilder.java b/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusBuilder.java index f15f9ba..180bcf1 100644 --- a/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusBuilder.java +++ b/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusBuilder.java @@ -1,71 +1,85 @@ package com.github.xuejike.query.mybatisplus; +import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.lang.SimpleCache; +import cn.hutool.core.util.EnumUtil; +import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.github.xuejike.query.core.enums.WhereOperation; import com.github.xuejike.query.core.exception.LambdaQueryException; import com.github.xuejike.query.core.po.*; +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; +import java.util.stream.Collectors; /** * @author xuejike * @date 2020/12/28 */ public class MyBatisPlusBuilder { - public static QueryWrapper build(QueryInfo queryInfo ){ + static SimpleCache,Map> entityMap = new SimpleCache,Map>(); + + public static QueryWrapper build(Class entityCls,QueryInfo queryInfo ){ QueryWrapper queryWrapper = new QueryWrapper<>(); - buildOrQuery(queryWrapper,queryInfo); + build(entityCls,queryWrapper,queryInfo); return queryWrapper; } - private static void buildOrQuery(QueryWrapper queryWrapper,QueryInfo info){ + public static void build(Class entityCls,QueryWrapper queryWrapper,QueryInfo info){ for (QueryItem item : info.getAnd()) { - buildField(queryWrapper,item); + buildField(entityCls,queryWrapper,item); } if (CollUtil.isNotEmpty(info.getOr())){ for (QueryInfo queryInfo : info.getOr()) { if (CollUtil.isNotEmpty(queryInfo.getOr()) || CollUtil.isNotEmpty(queryInfo.getAnd())){ queryWrapper.or(or->{ - buildOrQuery(or,queryInfo); + build(entityCls,or,queryInfo); }); } } } } - private static void buildField(QueryWrapper queryWrapper, QueryItem item) { - String field = buildField(item.getField()); + private static void buildField(Class entityCls,QueryWrapper queryWrapper, QueryItem item) { + String field = buildField(entityCls,item.getField()); for (Map.Entry entry : item.getVal().entrySet()) { Object value = entry.getValue(); switch (entry.getKey()){ case eq:{ - queryWrapper.eq(field, value); + queryWrapper.eq(field, getValue(entityCls,item.getField(),value)); break; } case lt: - queryWrapper.lt(field, value); + queryWrapper.lt(field, getValue(entityCls,item.getField(),value)); break; case lte: - queryWrapper.le(field, value); + queryWrapper.le(field, getValue(entityCls,item.getField(),value)); break; case gt: - queryWrapper.gt(field,value); + queryWrapper.gt(field,getValue(entityCls,item.getField(),value)); break; case gte: - queryWrapper.ge(field,value); + queryWrapper.ge(field,getValue(entityCls,item.getField(),value)); break; case between: BetweenObj betweenObj = (BetweenObj) value; - queryWrapper.between(field,betweenObj.getFirst(),betweenObj.getSecond()); + queryWrapper.between(field,getValue(entityCls,item.getField(),betweenObj.getFirst()), + getValue(entityCls,item.getField(),betweenObj.getSecond())); break; case ne: - queryWrapper.ne(field,value); + queryWrapper.ne(field,getValue(entityCls,item.getField(),value)); break; case isNull: queryWrapper.isNull(field); @@ -74,13 +88,22 @@ private static void buildField(QueryWrapper queryWrapper, QueryItem item) queryWrapper.isNotNull(field); break; case notIn: - queryWrapper.notIn(field,value); - break; + if (value instanceof Collection){ + queryWrapper.notIn(field,getValue(entityCls,item.getField(),getValue(entityCls,item.getField(),(Collection) value))); + }else{ + queryWrapper.notIn(field,getValue(entityCls,item.getField(),value)); + } + break; case in: - queryWrapper.in(field,value); + if (value instanceof Collection){ + queryWrapper.in(field,getValue(entityCls,item.getField(),(Collection) value)); + }else{ + queryWrapper.in(field,getValue(entityCls,item.getField(),value)); + } + break; case like: - queryWrapper.like(field,likeValue(value)); + queryWrapper.like(field,likeValue(getValue(entityCls,item.getField(),value))); break; default: break; @@ -88,15 +111,51 @@ private static void buildField(QueryWrapper queryWrapper, QueryItem item) } } - public static String buildField(FieldInfo fieldInfo){ - // TODO: 2020/12/30 对注解自定义列处理 - StringBuilder builder = new StringBuilder(fieldInfo.getField()); + public static String buildField(Class entityCls,FieldInfo fieldInfo){ + Map map = entityMap.get(entityCls); + if (map == null){ + map = new ConcurrentHashMap<>(); + entityMap.put(entityCls,map); + Field[] fields = ReflectUtil.getFields(entityCls); + for (Field field : fields) { + TableField tableField = AnnotationUtil.getAnnotation(field, TableField.class); + if (tableField != null && StrUtil.isNotBlank(tableField.value())){ + map.put(field.getName(),tableField.value()); + }else{ + map.put(field.getName(),StrUtil.toUnderlineCase(field.getName())); + } + } + } + + + StringBuilder builder = new StringBuilder(map.getOrDefault(fieldInfo.getField(),StrUtil.toUnderlineCase(fieldInfo.getField()))); if (fieldInfo.getSubList().size()>0){ throw new LambdaQueryException("mybatis 暂不支持 二级数据查询"); } return builder.toString(); } + + public static Object getValue(Class entityCls,FieldInfo fieldInfo,Object val){ + Field field = ReflectUtil.getField(entityCls, fieldInfo.getField()); + try { + return Convert.convert(field.getType(),val); + }catch (Exception ex){ + return val; + } + + } + public static Object getValue(Class entityCls,FieldInfo fieldInfo,Collection val){ + Field field = ReflectUtil.getField(entityCls, fieldInfo.getField()); + + return val.stream().map(it-> { + try { + return Convert.convert(field.getType(),it); + }catch (Exception ex){ + return it; + } + }).collect(Collectors.toList()); + } private static String likeValue(Object val){ if (val instanceof LikeValObj){ LikeValObj likeValObj = (LikeValObj) val; diff --git a/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusDao.java b/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusDao.java index dba8a6e..76545df 100644 --- a/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusDao.java +++ b/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusDao.java @@ -20,7 +20,7 @@ * @author xuejike * @date 2020/12/28 */ -public class MyBatisPlusDao extends BaseDao { +public class MyBatisPlusDao extends BaseDao> { BaseMapper baseMapper; @@ -29,12 +29,34 @@ public MyBatisPlusDao(BaseMapper baseMapper, Class entityCls) { this.baseMapper = baseMapper; } - protected QueryWrapper buildQuery(){ + @Override + public QueryWrapper buildQuery(){ + QueryWrapper build = new QueryWrapper(); + build.setEntityClass(entityCls); + + if (baseConditionsVo != null){ + MyBatisPlusBuilder.build(entityCls,build,baseConditionsVo.getWhere()); + if (CollUtil.isNotEmpty(baseConditionsVo.getSelectList())){ + List selectList = baseConditionsVo.getSelectList(); + build.select(selectList.stream().map(it->MyBatisPlusBuilder.buildField(entityCls,it)).toArray(String[]::new)); + } + if (CollUtil.isNotEmpty(baseConditionsVo.getOrderMap())){ + Map orderMap = baseConditionsVo.getOrderMap(); + orderMap.entrySet().forEach(it->{ + if (it.getValue() == OrderType.desc){ + build.orderByDesc(MyBatisPlusBuilder.buildField(entityCls,it.getKey())); + }else{ + build.orderByAsc(MyBatisPlusBuilder.buildField(entityCls,it.getKey())); + } + }); + } + } + QueryInfo queryInfo = baseWhereQuery.buildQueryInfo(); - QueryWrapper build = MyBatisPlusBuilder.build(queryInfo); + MyBatisPlusBuilder.build(entityCls,build,queryInfo); if (CollUtil.isNotEmpty(baseWhereQuery.getSelectList())){ List selectList = baseWhereQuery.getSelectList(); - build.select(selectList.stream().map(MyBatisPlusBuilder::buildField).toArray(String[]::new)); + build.select(selectList.stream().map(it->MyBatisPlusBuilder.buildField(entityCls,it)).toArray(String[]::new)); } if (CollUtil.isNotEmpty(baseWhereQuery.getExcludeList())){ List excludeList = baseWhereQuery.getExcludeList(); @@ -42,11 +64,11 @@ protected QueryWrapper buildQuery(){ } if (CollUtil.isNotEmpty(baseWhereQuery.getOrderMap())){ Map orderMap = baseWhereQuery.getOrderMap(); - orderMap.entrySet().stream().forEach(it->{ + orderMap.entrySet().forEach(it->{ if (it.getValue() == OrderType.desc){ - build.orderByDesc(MyBatisPlusBuilder.buildField(it.getKey())); + build.orderByDesc(MyBatisPlusBuilder.buildField(entityCls,it.getKey())); }else{ - build.orderByAsc(MyBatisPlusBuilder.buildField(it.getKey())); + build.orderByAsc(MyBatisPlusBuilder.buildField(entityCls,it.getKey())); } }); } diff --git a/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusDaoFactory.java b/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusDaoFactory.java index c111598..4648d86 100644 --- a/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusDaoFactory.java +++ b/lambda-query-mybatis-plus/src/main/java/com/github/xuejike/query/mybatisplus/MyBatisPlusDaoFactory.java @@ -3,6 +3,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.TypeUtil; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.github.xuejike.query.core.base.BaseDao; import com.github.xuejike.query.core.config.DaoFactory; import com.github.xuejike.query.core.config.JkQueryConfig; import com.github.xuejike.query.core.criteria.DaoCriteria; @@ -24,16 +25,12 @@ public class MyBatisPlusDaoFactory extends DaoFactory { public MyBatisPlusDaoFactory(Collection mapperList) { super(MyBatisPlusDao.class); this.mapperList = CollUtil.newArrayList(mapperList); - init(); - } - public void init(){ - JkQueryConfig.getInstance().addDaoFactory(this); - } + } @Override - public DaoCriteria createDao(Class entityCls) { + public BaseDao createDao(Class entityCls) { if (!mapperMap.containsKey(entityCls)){ for (BaseMapper mapper : mapperList) { Type[] genericInterfaces = mapper.getClass().getGenericInterfaces(); diff --git a/mongo-demo/pom.xml b/mongo-demo/pom.xml index c435823..14dffaf 100644 --- a/mongo-demo/pom.xml +++ b/mongo-demo/pom.xml @@ -5,13 +5,17 @@ lambda-query com.github.xuejike - 1.0.1 + 1.0.2-SNAPSHOT 4.0.0 mongo-demo + + 2.2.1.RELEASE + Hoxton.SR8 + @@ -53,11 +57,33 @@ spring-boot-starter-test test + + com.github.xuejike + lambda-query-mybatis-plus-starter + ${query.version} + com.github.xuejike lambda-query-mybatis-plus ${query.version} + + com.github.xuejike + lambda-query-http + ${query.version} + + + com.github.xuejike + lambda-query-http-starter + ${query.version} + + + jsr305 + com.google.code.findbugs + + + + @@ -68,6 +94,25 @@ pom import + + org.springframework.cloud + spring-cloud-starter + ${spring-cloud-alibaba.version} + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + diff --git a/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/App.java b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/App.java index dc30025..c9731ac 100644 --- a/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/App.java +++ b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/App.java @@ -11,7 +11,7 @@ */ @SpringBootApplication @MapperScan("com.github.xuejike.query.mongo.demo.mybatis.mapper") -@ComponentScan(basePackages={"cn.hutool.extra.spring"}) +@ComponentScan(basePackages={"cn.hutool.extra.spring","com.github.xuejike.query.mongo.demo"}) public class App { public static void main(String[] args) { diff --git a/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/controller/HttpTestController.java b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/controller/HttpTestController.java new file mode 100644 index 0000000..0db6454 --- /dev/null +++ b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/controller/HttpTestController.java @@ -0,0 +1,40 @@ +package com.github.xuejike.query.mongo.demo.controller; + +import com.github.xuejike.query.core.JLambdaQuery; +import com.github.xuejike.query.core.JQuerys; +import com.github.xuejike.query.http.LambdaQueryHttpConfig; +import com.github.xuejike.query.http.client.HttpClientFactory; +import com.github.xuejike.query.mongo.demo.http.HttpEntity; +import com.github.xuejike.query.mongo.demo.mybatis.entity.U1; +import com.github.xuejike.query.mongo.demo.mybatis.entity.U2; +import com.github.xuejike.query.mongo.demo.vo.U1Vo; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.PostConstruct; + +/** + * @author xuejike + * @date 2021/1/4 + */ +@RestController +@RequestMapping("/") +public class HttpTestController { + static { + + } + @PostConstruct + public void init(){ + LambdaQueryHttpConfig.getInstance().registerService("u1", U1.class); + HttpClientFactory httpClientFactory = new HttpClientFactory(); + } + @GetMapping("list") + public Object testList(){ + JLambdaQuery query = JQuerys.lambdaQuery(HttpEntity.class); + Object list = query.or().eq(HttpEntity::getName,"name1").or() + .eq(HttpEntity::getName,"name2") + .loadRef(HttpEntity::getU2Id, U2.class,U2::getId).map(U1Vo.class).list(); + return list; + } +} diff --git a/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/enums/U1Status.java b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/enums/U1Status.java new file mode 100644 index 0000000..717f489 --- /dev/null +++ b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/enums/U1Status.java @@ -0,0 +1,16 @@ +package com.github.xuejike.query.mongo.demo.enums; + +import com.baomidou.mybatisplus.annotation.IEnum; + +/** + * @author xuejike + * @date 2021/1/4 + */ +public enum U1Status implements IEnum { + T1,T2; + + @Override + public Long getValue() { + return Long.valueOf(this.ordinal()); + } +} diff --git a/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/http/HttpEntity.java b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/http/HttpEntity.java new file mode 100644 index 0000000..ae3df76 --- /dev/null +++ b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/http/HttpEntity.java @@ -0,0 +1,17 @@ +package com.github.xuejike.query.mongo.demo.http; + +import com.github.xuejike.query.http.annotation.HttpDaoSelect; +import lombok.Data; + +/** + * @author xuejike + * @date 2021/1/4 + */ +@HttpDaoSelect( serverAddress = "http://127.0.0.1:7000",path = "/lambda/u1/") +@Data +public class HttpEntity { + private Long id; + private String name; + private String type; + private Long u2Id; +} diff --git a/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/mybatis/entity/U1.java b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/mybatis/entity/U1.java index fc6816c..929b409 100644 --- a/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/mybatis/entity/U1.java +++ b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/mybatis/entity/U1.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.github.xuejike.query.mongo.demo.enums.U1Status; import com.github.xuejike.query.mybatisplus.annotation.MyBatisPlusDaoSelect; import lombok.Data; @@ -18,5 +19,7 @@ public class U1 { private Long id; private String name; private String type; - + private Long u2Id; + + private U1Status status; } diff --git a/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/vo/U1Vo.java b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/vo/U1Vo.java new file mode 100644 index 0000000..aca6fe7 --- /dev/null +++ b/mongo-demo/src/main/java/com/github/xuejike/query/mongo/demo/vo/U1Vo.java @@ -0,0 +1,21 @@ +package com.github.xuejike.query.mongo.demo.vo; + + +import com.github.xuejike.query.core.annotation.RefValue; +import com.github.xuejike.query.core.annotation.SetRefValue; +import lombok.Data; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@Data +public class U1Vo { + private Long id; + private String name; + private String type; + @SetRefValue("u2") + private Long u2Id; + @RefValue("#u2.name") + private String u2Name; +} diff --git a/mongo-demo/src/main/resources/application.yaml b/mongo-demo/src/main/resources/application.yaml index ffa1ad3..a64b6d6 100644 --- a/mongo-demo/src/main/resources/application.yaml +++ b/mongo-demo/src/main/resources/application.yaml @@ -16,5 +16,8 @@ logging: com.github.xuejike.query.mongo.demo.mybatis.mapper: debug pattern: console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(-%5p) %clr(${PID:- }){magenta} --- %clr([%15.15t]){faint} %highlight(%-80.80logger{300}){cyan} %clr(:) %m %n%wEx" - - +server: + port: 7000 +debug: true +mybatis-plus: + type-enums-package: com.github.xuejike.query.mongo.demo.enums \ No newline at end of file diff --git a/mongo-demo/src/test/java/HttpClientTest.java b/mongo-demo/src/test/java/HttpClientTest.java new file mode 100644 index 0000000..12ad365 --- /dev/null +++ b/mongo-demo/src/test/java/HttpClientTest.java @@ -0,0 +1,32 @@ +import com.github.xuejike.query.core.JQuerys; +import com.github.xuejike.query.http.client.HttpClientFactory; +import com.github.xuejike.query.mongo.demo.App; +import http.HttpRequest; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@SpringBootTest(classes = App.class) +@ContextConfiguration +@Slf4j +@Rollback(value = false) +public class HttpClientTest { + + @BeforeEach + public void before(){ + new HttpClientFactory(); + + } + + @Test + public void list(){ + JQuerys.lambdaQuery(HttpRequest.class).eq(HttpRequest::getName,"xxx").eq(HttpRequest::getUserName,"un").list(); + } +} diff --git a/mongo-demo/src/test/java/MyBatisTest.java b/mongo-demo/src/test/java/MyBatisTest.java new file mode 100644 index 0000000..492cbd5 --- /dev/null +++ b/mongo-demo/src/test/java/MyBatisTest.java @@ -0,0 +1,44 @@ +import cn.hutool.extra.spring.SpringUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.github.xuejike.query.core.JQuerys; +import com.github.xuejike.query.mongo.demo.App; +import com.github.xuejike.query.mongo.demo.enums.U1Status; +import com.github.xuejike.query.mongo.demo.mybatis.entity.U1; +import com.github.xuejike.query.mongo.demo.mybatis.entity.U2; +import com.github.xuejike.query.mongo.demo.vo.U1Vo; +import com.github.xuejike.query.mybatisplus.MyBatisPlusDaoFactory; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; + +import java.util.List; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@SpringBootTest(classes = App.class) +@ContextConfiguration +@Slf4j +@Rollback(value = false) +public class MyBatisTest { + + @BeforeEach + public void before(){ + new MyBatisPlusDaoFactory(SpringUtil.getBeansOfType(BaseMapper.class).values()); + + } + + @Test + public void list(){ + List list = JQuerys.lambdaQuery(U1.class) + .eq(U1::getStatus, U1Status.T1) + .loadRef(U1::getU2Id, U2.class, U2::getId) + .map(U1Vo.class).list(); + System.out.println(JSON.toJSONString(list)); + } +} diff --git a/mongo-demo/src/test/java/TestMain.java b/mongo-demo/src/test/java/TestMain.java index 4aa9bbb..5522a5a 100644 --- a/mongo-demo/src/test/java/TestMain.java +++ b/mongo-demo/src/test/java/TestMain.java @@ -1,39 +1,29 @@ -import cn.hutool.core.util.NumberUtil; -import cn.hutool.core.util.TypeUtil; import cn.hutool.extra.spring.SpringUtil; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.github.xuejike.query.core.JkLambdaQuery; +import com.github.xuejike.query.core.JLambdaQuery; -import com.github.xuejike.query.core.JkQuerys; +import com.github.xuejike.query.core.JQuerys; import com.github.xuejike.query.core.tool.lambda.CascadeField; -import com.github.xuejike.query.mongo.MongoDao; import com.github.xuejike.query.mongo.MongoDaoFactory; import com.github.xuejike.query.mongo.demo.App; import com.github.xuejike.query.mongo.demo.data.TestDoc; import com.github.xuejike.query.mongo.demo.mybatis.entity.U1; -import com.github.xuejike.query.mongo.demo.mybatis.mapper.U1Mapper; import com.github.xuejike.query.mybatisplus.MyBatisPlusDaoFactory; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; 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.test.annotation.Rollback; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; -import java.lang.reflect.Type; import java.util.LinkedList; import java.util.List; -import java.util.Map; /** * @author xuejike @@ -47,8 +37,7 @@ public class TestMain { @Autowired MongoTemplate mongoTemplate; - @Autowired - U1Mapper u1Mapper; + @BeforeEach public void before(){ new MyBatisPlusDaoFactory(SpringUtil.getBeansOfType(BaseMapper.class).values()); @@ -78,7 +67,7 @@ public void Test(){ - JkLambdaQuery lambda = JkQuerys.lambdaQuery(TestDoc.class); + JLambdaQuery lambda = JQuerys.lambdaQuery(TestDoc.class); // Query query = new Query(); // query.addCriteria(new Criteria().orOperator(Criteria.where("name").is("999")) @@ -98,7 +87,7 @@ public void Test(){ */ @Test public void testEq(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).eq(TestDoc::getName, "name_1").list(); + List list = JQuerys.lambdaQuery(TestDoc.class).eq(TestDoc::getName, "name_1").list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_1"); @@ -110,7 +99,7 @@ public void testEq(){ */ @Test public void testGt(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).gt(TestDoc::getNum,3 ).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).gt(TestDoc::getNum,3 ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_4"); @@ -121,7 +110,7 @@ public void testGt(){ */ @Test public void testGte(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).gte(TestDoc::getNum,4 ).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).gte(TestDoc::getNum,4 ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_4"); @@ -132,7 +121,7 @@ public void testGte(){ */ @Test public void testLt(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).lt(TestDoc::getNum,1 ).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).lt(TestDoc::getNum,1 ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_0"); @@ -143,7 +132,7 @@ public void testLt(){ */ @Test public void testLte(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).lte(TestDoc::getNum,0 ).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).lte(TestDoc::getNum,0 ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); Assertions.assertEquals(testDoc.getTitle(),"title_0"); @@ -154,7 +143,7 @@ public void testLte(){ */ @Test public void testIn(){ - List list = JkQuerys.lambdaQuery(TestDoc.class) + List list = JQuerys.lambdaQuery(TestDoc.class) .in(TestDoc::getTitle,"title_0" ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); @@ -166,7 +155,7 @@ public void testIn(){ */ @Test public void testNotIn(){ - List list = JkQuerys.lambdaQuery(TestDoc.class) + List list = JQuerys.lambdaQuery(TestDoc.class) .notIn(TestDoc::getTitle,"title_0","title_1","title_2","title_3" ).list(); Assertions.assertEquals(list.size(),1); TestDoc testDoc = list.get(0); @@ -178,10 +167,10 @@ public void testNotIn(){ */ @Test public void testOr(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).or().eq(TestDoc::getNum, 0).or().eq(TestDoc::getNum, 1).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).or().eq(TestDoc::getNum, 0).or().eq(TestDoc::getNum, 1).list(); Assertions.assertEquals(list.size(),2); - list = JkQuerys.lambdaQuery(TestDoc.class).or(it->{ + list = JQuerys.lambdaQuery(TestDoc.class).or(it->{ it.eq(TestDoc::getNum,0).eq(TestDoc::getName,"name_0"); }).or(it->{ it.eq(TestDoc::getNum,1).eq(TestDoc::getName,"name_1"); @@ -196,12 +185,12 @@ public void testOr(){ */ @Test public void testOrder(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).in(TestDoc::getNum, 1, 2).orderAsc(TestDoc::getNum).list(); + List list = JQuerys.lambdaQuery(TestDoc.class).in(TestDoc::getNum, 1, 2).orderAsc(TestDoc::getNum).list(); Assertions.assertEquals(list.size(),2); Assertions.assertEquals(list.get(0).getNum(),1); Assertions.assertEquals(list.get(1).getNum(),2); - list = JkQuerys.lambdaQuery(TestDoc.class).in(TestDoc::getNum, 1, 2).orderDesc(TestDoc::getNum).list(); + list = JQuerys.lambdaQuery(TestDoc.class).in(TestDoc::getNum, 1, 2).orderDesc(TestDoc::getNum).list(); Assertions.assertEquals(list.size(),2); Assertions.assertEquals(list.get(0).getNum(),2); Assertions.assertEquals(list.get(1).getNum(),1); @@ -212,7 +201,7 @@ public void testOrder(){ */ @Test public void testSubField(){ - List list = JkQuerys.lambdaQuery(TestDoc.class).eq(of().subList(TestDoc::getToc).sub(TestDoc.Title::getTitle), "sub_title_0_0").list(); + List list = JQuerys.lambdaQuery(TestDoc.class).eq(of().subList(TestDoc::getToc).sub(TestDoc.Title::getTitle), "sub_title_0_0").list(); Assertions.assertEquals(list.size(),1); Assertions.assertEquals(list.get(0).getNum(),0); } @@ -226,12 +215,12 @@ public void testAddU1(){ U1 u1 = new U1(); u1.setType("555"); u1.setName("name2"); - u1Mapper.insert(u1); + } @Test public void queryU1(){ - List list = JkQuerys.lambdaQuery(U1.class) + List list = JQuerys.lambdaQuery(U1.class) .eq(U1::getId, 1) .or().eq(U1::getId,2) .or(or-> diff --git a/mongo-demo/src/test/java/TestNoSpring.java b/mongo-demo/src/test/java/TestNoSpring.java index c617969..4c9babc 100644 --- a/mongo-demo/src/test/java/TestNoSpring.java +++ b/mongo-demo/src/test/java/TestNoSpring.java @@ -1,12 +1,7 @@ -import com.github.xuejike.query.core.JkLambdaQuery; -import com.github.xuejike.query.core.JkQuerys; -import com.github.xuejike.query.core.config.JkQueryConfig; -import com.github.xuejike.query.mongo.MongoDaoFactory; +import com.github.xuejike.query.core.JLambdaQuery; +import com.github.xuejike.query.core.JQuerys; import com.github.xuejike.query.mongo.demo.data.TestDoc; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.mongodb.core.MongoTemplate; import java.util.List; @@ -18,7 +13,7 @@ public class TestNoSpring { @Test public void test(){ - JkLambdaQuery query = JkQuerys.lambdaQuery(TestDoc.class); + JLambdaQuery query = JQuerys.lambdaQuery(TestDoc.class); List list = query.eq(TestDoc::getId, "666").list(); } diff --git a/mongo-demo/src/test/java/http/HttpRequest.java b/mongo-demo/src/test/java/http/HttpRequest.java new file mode 100644 index 0000000..4469d32 --- /dev/null +++ b/mongo-demo/src/test/java/http/HttpRequest.java @@ -0,0 +1,17 @@ +package http; + +import com.github.xuejike.query.http.annotation.HttpDaoSelect; +import lombok.Data; + +/** + * @author xuejike + * @date 2020/12/31 + */ +@HttpDaoSelect +@Data +public class HttpRequest { + private Long id; + private String name; + private String type; + private String userName; +} diff --git a/pom.xml b/pom.xml index 4b483dc..65efa32 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.xuejike lambda-query - 1.0.1 + 1.0.2-SNAPSHOT lambda-query https://gitee.com/xuejike/lambda-query.git @@ -40,19 +40,32 @@ mongo-demo lambda-query-mongo-starter lambda-query-mybatis-plus-starter + lambda-query-http + lambda-query-http-starter 1.8 1.8 1.8 - 1.0.1 + 1.0.2-SNAPSHOT UTF-8 - + 5.5.2 - + + org.slf4j + slf4j-api + 1.7.30 + compile + + + org.projectlombok + lombok + 1.18.16 + provided + diff --git a/update-version.sh b/update-version.sh index 297005c..eab0d39 100644 --- a/update-version.sh +++ b/update-version.sh @@ -1,3 +1,4 @@ #!/usr/bin/env bash -mvn versions:set -DnewVersion=1.0.1 +mvn versions:set -DnewVersion=1.0.2-SNAPSHOT +#mvn versions:set -DnewVersion=1.0.1 mvn versions:commit \ No newline at end of file