Browse Source

增加文档、以及功能的优化

liukx@elab 5 years ago
parent
commit
24e09b3be1
32 changed files with 1575 additions and 225 deletions
  1. 9 33
      README.md
  2. 0 0
      elab-cache/README.md
  3. 24 1
      elab-core/src/test/java/com/elab/test/utils/GuavaUtilsCase.java
  4. 31 4
      elab-db/REDEME.md
  5. 6 0
      elab-db/pom.xml
  6. 10 0
      elab-db/src/main/java/com/elab/core/aop/annotations/FieldParam.java
  7. 54 4
      elab-db/src/main/java/com/elab/core/dao/BasicBaseDao.java
  8. 31 0
      elab-db/src/main/java/com/elab/core/dao/IBaseDaoSupport.java
  9. 1 2
      elab-db/src/main/java/com/elab/core/dao/TimeRowMapperResultSetExtractor.java
  10. 91 0
      elab-db/src/main/java/com/elab/core/dao/model/DataRangeSearch.java
  11. 72 0
      elab-db/src/main/java/com/elab/core/dao/model/InSearch.java
  12. 62 0
      elab-db/src/main/java/com/elab/core/dao/model/LikeSearch.java
  13. 154 0
      elab-db/src/main/java/com/elab/core/dao/model/ListDynamicSearch.java
  14. 39 0
      elab-db/src/main/java/com/elab/core/dao/model/OrderBySearch.java
  15. 91 0
      elab-db/src/main/java/com/elab/core/dao/params/NamedParameterUtils2.java
  16. 15 2
      elab-db/src/main/java/com/elab/core/spring/binding/DaoMethod.java
  17. 14 0
      elab-db/src/main/java/com/elab/core/spring/common/TypeGroupModel.java
  18. 21 2
      elab-db/src/main/java/com/elab/core/spring/common/utils/DataUtils.java
  19. 15 1
      elab-db/src/main/java/com/elab/core/spring/method/DefaultSQLBuilderSupport.java
  20. 7 0
      elab-db/src/test/java/com.db.service/dao/ITestDao.java
  21. 15 166
      elab-db/src/test/java/com.db.service/main/BasicBaseDaoCase.java
  22. 296 0
      elab-db/src/test/java/com.db.service/main/BasicBaseDaoProxyCase.java
  23. 1 1
      elab-db/src/test/java/com.db.service/model/TTest.java
  24. 1 1
      elab-db/src/test/resources/applicationContext-datasource.xml
  25. 25 0
      elab-db/src/test/resources/logback.xml
  26. 15 6
      elab-db/src/test/resources/sql/test-sql.xml
  27. 12 0
      elab-db/src/test/resources/test.sql
  28. 135 0
      elab-log/README.md
  29. 169 0
      elab-mongodb/src/REDEME.md
  30. 66 1
      elab-mq/README.md
  31. 47 0
      elab-mq/mq.sql
  32. 46 1
      elab-mq/src/main/java/com/elab/mq/listener/MessageListenerWrapper.java

+ 9 - 33
README.md

@@ -1,34 +1,10 @@
-命令行指令
+# Elab 技术核心框架介绍
+- [elab-cache](./elab-cache/README.md) : 用于Redis缓存,目前集成的是搜狐的CacheCloud客户端.
+- elab-core : 用于一些常用的工具类
+- [elab-db](./elab-db/README.md)    : DB持久层映射,基于JdbcTemplate开发,实现使用思路参考Mybatis。
+- [elab-es](./elab-es/README.md) : 用于ElasticSearch客户端简单封装。
+- [elab-log](./elab-log/README.md) : 日志服务框架,基于携程的CAT客户端开发。用于收集每个服务请求的日志信息。
+- [elab-mongodb](./elab-mongodb/README.md) : 基于mongodb客户端封装。
+- [elab-mq](./elab-mq/README.md) : 基于阿里云的商用版RocketMQ开发,为每个请求植入了CAT日志监控。
+- elab-spring : 对Spring的一些拓展封装
 
-Git 全局设置
-
-git config --global user.name "liuhx@elab"
-
-git config --global user.email "liuhx@elab-plus.com"
-
-创建新版本库
-
-git clone git@code.aliyun.com:elabFrameworkCore/elab-parent.git
-
-cd test
-
-touch README.md
-
-git add README.md
-
-git commit -m "add README"
-
-git push -u origin master
-
-已存在的文件夹或 Git 仓库
-
-cd existing_folder
-
-git init
-
-git remote add origin git@code.aliyun.com:adminRm/test.git
-git add .
-
-git commit
-
-git push -u origin master

elab-cache/src/main/resources/ELAB-CACHE.md → elab-cache/README.md


+ 24 - 1
elab-core/src/test/java/com/elab/test/utils/GuavaUtilsCase.java

@@ -7,6 +7,7 @@ import com.google.common.collect.*;
 import org.junit.Test;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -26,11 +27,33 @@ public class GuavaUtilsCase {
         // 数据分片
         List<List<Object>> partition = Lists.partition(objects, 2);
         System.out.println("");
-
+        // 取交集
+//        Sets.intersection(objects,objects)
         String str = "1-2-3-4-5-6";
         List<String> list = Splitter.on("-").splitToList(str);
     }
 
+    /**
+     * 当我们在统计一个字符串中每个单词出现的次数时,通常的做法是分割字符串,
+     * 遍历字符串,然后放到一个map里面,来进行统计,Guava中提供了类似功能的集合,Multiset
+     */
+    @Test
+    public void strCount() {
+        String strWorld = "wer dffd ddsa dfd dreg de dr ce ghrt cf gt ser tg ghrt cf gt " +
+                "ser tg gt kldf dfg vcd fg gt ls lser dfr wer dffd ddsa dfd dreg de dr " +
+                "ce ghrt cf gt ser tg gt kldf dfg vcd fg gt ls lser dfr";
+        List<String> stringList = Splitter.on(" ")
+                .trimResults()
+                .splitToList(strWorld);//把字符串转换为集合
+        HashMultiset<String> multisets = HashMultiset.create();//创建一个Multiset集合
+        multisets.addAll(stringList);
+        Iterator<String> iterator = multisets.iterator();
+        while (iterator.hasNext()) {
+            String next = iterator.next();
+            System.out.println(next + " count: " + multisets.count(next));
+        }
+    }
+
     @Test
     public void MapTest() {
         /**

+ 31 - 4
elab-db/REDEME.md

@@ -2,7 +2,23 @@
 
 ## 更新介绍:
 
-版本号: 2.0.4.10
+#### 版本号: 2.0.4.12
+- 通用接口类IBaseDaoSupport新增方法`selectByObjectToCount`方法,用于单表查询总数
+- 新增动态处理参数`ListDynamicSearch`,用于处理sort、limit、>=、<=、in函数处理
+    ```java
+    List<String> list = new ArrayList<>();
+    list.add("1");
+    list.add("2");
+    list.add("3");
+    ListDynamicSearch listDynamicSearch = ListDynamicSearch.newBuilder().addInSearches("id", list).build();
+    List<TTest> tTests = testDao.getTestList2(test, listDynamicSearch);
+    ```
+- 每个方法新增`@FieldParam注`解,用于传递普通非Model对象处理
+    ```java
+    public TTest selectByName(@FieldParam("id") String id, @FieldParam("username") String username);
+    ```
+- 新增`@EnableElabDB`注解,适用于SpringBoot启用DB配置
+#### 版本号: 2.0.4.10
 
 - 新增批量新增功能
 - 批量修改,参考`IBaseDaoSupport`
@@ -118,7 +134,7 @@ public interface ITestDao extends IBaseDaoSupport<TTest> {
 
    public List getTestList(TTest id);
 
-}
+   public TTest selectByName(@FieldParam("id") String id, @FieldParam("username") String username);
 
 ```
 2. SQL文件通常放在resources/sql下面
@@ -204,7 +220,6 @@ public void testInserCase() throws Exception {
 ```
 2. 修改
 ```java
-
 @Test
 public void testUpdateCase() throws Exception {
 	TTest test = new TTest();
@@ -234,6 +249,17 @@ public void testUpdateCase() throws Exception {
 
 ```
 
+4. 单表特殊操作
+```java
+ListDynamicSearch.newBuilder().addInSearches("id", list)            // in 操作
+                .limit(1)                                           // 大小
+                .addLikeSearches("","")                             // like操作
+                .dataRangeSearches("time",new Date(),new Date())    // 范围操作
+                .orderBy("id",OrderBySearch.DESC);                  // 排序
+// 普通方法追加动态参数
+List<TTest> tTests = testDao.getTestList2(test, listDynamicSearch);
+
+```
 
 
 ## 特殊操作
@@ -250,7 +276,8 @@ public void testUpdateCase() throws Exception {
 ## bean对象手动设置
 1. 实现RowMapper接口
 ```
-// 该类已经是最底层的赋值方法了,可以根据具体业务去实现不同的处理
+// 该类已经是最底层的赋值方法了,可以根据具体业务去实现不同的处理,
+// 如果对数据库的字段有特殊处理的,可以在这个转换成去实现,比如type转换、日期转换等等。
 public class TestRowMapper implements RowMapper {
 
     @Override

+ 6 - 0
elab-db/pom.xml

@@ -24,6 +24,12 @@
 
     <dependencies>
         <!-- https://mvnrepository.com/artifact/ma.glasnost.orika/orika-core -->
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+             <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>ma.glasnost.orika</groupId>
             <artifactId>orika-core</artifactId>

+ 10 - 0
elab-db/src/main/java/com/elab/core/aop/annotations/FieldParam.java

@@ -0,0 +1,10 @@
+package com.elab.core.aop.annotations;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface FieldParam {
+    String value();
+}

+ 54 - 4
elab-db/src/main/java/com/elab/core/dao/BasicBaseDao.java

@@ -2,6 +2,7 @@ package com.elab.core.dao;
 
 import com.elab.core.bean.PageModel;
 import com.elab.core.dao.model.JdbcParamsModel;
+import com.elab.core.dao.model.ListDynamicSearch;
 import com.elab.core.dao.params.BeanSqlParameterSource;
 import com.elab.core.dao.params.MapDataSqlParameterSource;
 import com.elab.core.dao.params.NamedParameterUtils2;
@@ -134,6 +135,10 @@ public class BasicBaseDao {
      * @return
      */
     private JdbcParamsModel commonParseSql(String sql, Object param) throws Exception {
+        return this.commonParseSql(sql, param, null);
+    }
+
+    private JdbcParamsModel commonParseSql(String sql, Object param, ListDynamicSearch search) throws Exception {
         long start = System.currentTimeMillis();
         JdbcParamsModel model = new JdbcParamsModel();
         if (param instanceof String) {
@@ -148,7 +153,10 @@ public class BasicBaseDao {
         // 解析参数类型 , 这里会根据Map和Object对象做装换
         SqlParameterSource sqlParameterSource = getSqlParameterSource(param);
         // 获取有效的参数,将为null和""的参数给替换掉
+        long k = System.currentTimeMillis();
         Object[] data = NamedParameterUtils2.buildValueArray(parsedSql, sqlParameterSource, null);
+        long k1 = System.currentTimeMillis() - k;
+        logger.debug("--------------------" + k1 + "-----------------------");
         // 正常解析sql为jdbc与参数对应
         String s = NamedParameterUtils2.substituteNamedParameters(parsedSql, sqlParameterSource);
         // 校验第一个参数为空的情况下
@@ -156,11 +164,15 @@ public class BasicBaseDao {
         // 替换动态表名存在的情况下
         s = NamedParameterUtils2.replaceDynamic(s, sqlParameterSource);
 
-        logger.debug(" 转换后的sql - " + s);
-        logger.debug(" 对应参数    -  " + Arrays.toString(data));
+        if (search != null) {
+            model = NamedParameterUtils2.appendSQLContent(s, data, search);
+        } else {
+            model.setSql(s);
+            model.setObjects(data);
+        }
 
-        model.setSql(s);
-        model.setObjects(data);
+        logger.debug(" 转换后的sql - " + model.getSql());
+        logger.debug(" 对应参数    -  " + Arrays.toString(model.getObjects()));
 
         // 校验SQL是否符合规范
         checkSqlProcess.checkProcess(model, param);
@@ -187,6 +199,25 @@ public class BasicBaseDao {
         return ts;
     }
 
+    /**
+     * @param sql
+     * @param o
+     * @param search
+     * @param elementType
+     * @param <T>
+     * @return
+     * @throws Exception
+     */
+    public <T> List<T> executeQueryList(String sql, Object obj, ListDynamicSearch search, Class<T> elementType) throws
+            Exception {
+        JdbcParamsModel jdbcParamsModel = commonParseSql(sql, obj, search);
+        long start = System.currentTimeMillis();
+        List<T> ts = (List<T>) this.jdbcTemplate.query(jdbcParamsModel.getSql(), jdbcParamsModel.getObjects(), new TimeRowMapperResultSetExtractor(new ThirdRowMapper<T>(elementType)));
+        long time = System.currentTimeMillis() - start;
+        logger.debug(" SQL 执行耗时 : " + time);
+        return ts;
+    }
+
     /**
      * 查询一个分页对象
      *
@@ -305,6 +336,25 @@ public class BasicBaseDao {
         return ts;
     }
 
+    /**
+     * 获取总数信息
+     *
+     * @param sql         SQL语句
+     * @param o           参数类型
+     * @param elementType 返回参数类型
+     * @param <T>
+     * @return
+     * @throws Exception
+     */
+    public <T> T executeQueryCount(String sql, Object o, ListDynamicSearch search, Class<T> elementType) throws Exception {
+        JdbcParamsModel jdbcParamsModel = commonParseSql(sql, o, search);
+        long start = System.currentTimeMillis();
+        T ts = this.jdbcTemplate.queryForObject(jdbcParamsModel.getSql(), jdbcParamsModel.getObjects(), elementType);
+        long time = System.currentTimeMillis() - start;
+        logger.debug(" SQL 执行耗时 : " + time);
+        return ts;
+    }
+
 
     /**
      * 查询一个数据集合对象,根据自定义的数据转换器返回

+ 31 - 0
elab-db/src/main/java/com/elab/core/dao/IBaseDaoSupport.java

@@ -3,6 +3,7 @@ package com.elab.core.dao;/**
  */
 
 import com.elab.core.bean.PageModel;
+import com.elab.core.dao.model.ListDynamicSearch;
 import org.springframework.jdbc.core.RowMapper;
 
 import java.util.List;
@@ -71,6 +72,36 @@ public interface IBaseDaoSupport<T> {
      */
     public List<T> selectByList(T obj) throws Exception;
 
+    /**
+     * 查询一个集合,
+     *
+     * @param obj    相等的参数
+     * @param search 其他查询操作
+     * @return
+     * @throws Exception
+     */
+    public List<T> selectByList(T obj, ListDynamicSearch search) throws Exception;
+
+    /**
+     * 根据查询对象获取总数信息
+     *
+     * @param obj
+     * @param search
+     * @return
+     * @throws Exception
+     */
+    public Integer selectByObjectToCount(T obj, ListDynamicSearch search) throws Exception;
+
+    /**
+     * 根据查询对象获取总数信息
+     *
+     * @param obj
+     * @return
+     * @throws Exception
+     */
+    public Integer selectByObjectToCount(T obj) throws Exception;
+
+
     /**
      * 查询一个分页集合
      *

+ 1 - 2
elab-db/src/main/java/com/elab/core/dao/TimeRowMapperResultSetExtractor.java

@@ -33,8 +33,7 @@ public class TimeRowMapperResultSetExtractor<T> extends RowMapperResultSetExtrac
         long start = System.currentTimeMillis();
         List<T> list = super.extractData(rs);
         long time = System.currentTimeMillis() - start;
-        logger.info(" 反射耗时 : " + time);
-        System.out.println(list.size() + " 反射耗时 : " + time);
+        logger.debug(" 反射耗时 : " + time);
         return list;
     }
 }

+ 91 - 0
elab-db/src/main/java/com/elab/core/dao/model/DataRangeSearch.java

@@ -0,0 +1,91 @@
+package com.elab.core.dao.model;
+
+
+
+/**
+ * 日期范围查询
+ * 这里需要注意的是 startData 和 endData 必填其中一个
+ *
+ * @author : liukx
+ * @time : 2020/4/16 - 16:32
+ */
+public class DataRangeSearch {
+    /**
+     * 字段名称
+     */
+    private String filed;
+    /**
+     * 开始对象
+     */
+    private Object startData;
+    /**
+     * 结束对象
+     */
+    private Object endData;
+
+    public DataRangeSearch() {
+    }
+
+    private DataRangeSearch(Builder builder) {
+        setFiled(builder.filed);
+        setStartData(builder.startData);
+        setEndData(builder.endData);
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    public String getFiled() {
+        return filed;
+    }
+
+    public void setFiled(String filed) {
+        this.filed = filed;
+    }
+
+    public Object getStartData() {
+        return startData;
+    }
+
+    public void setStartData(Object startData) {
+        this.startData = startData;
+    }
+
+    public Object getEndData() {
+        return endData;
+    }
+
+    public void setEndData(Object endData) {
+        this.endData = endData;
+    }
+
+
+    public static final class Builder {
+        private String filed;
+        private Object startData;
+        private Object endData;
+
+        private Builder() {
+        }
+
+        public Builder filed(String val) {
+            filed = val;
+            return this;
+        }
+
+        public Builder startData(Object val) {
+            startData = val;
+            return this;
+        }
+
+        public Builder endData(Object val) {
+            endData = val;
+            return this;
+        }
+
+        public DataRangeSearch build() {
+            return new DataRangeSearch(this);
+        }
+    }
+}

+ 72 - 0
elab-db/src/main/java/com/elab/core/dao/model/InSearch.java

@@ -0,0 +1,72 @@
+package com.elab.core.dao.model;
+
+import java.util.List;
+
+/**
+ * in字段查询
+ *
+ * @author : liukx
+ * @time : 2020/4/16 - 16:33
+ */
+public class InSearch {
+
+    /**
+     * 字段名称
+     */
+    private String filed;
+    /**
+     * 数据集合
+     */
+    private List dataList;
+
+    public InSearch() {
+    }
+
+    private InSearch(Builder builder) {
+        setFiled(builder.filed);
+        setDataList(builder.dataList);
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    public String getFiled() {
+        return filed;
+    }
+
+    public void setFiled(String filed) {
+        this.filed = filed;
+    }
+
+    public List getDataList() {
+        return dataList;
+    }
+
+    public void setDataList(List dataList) {
+        this.dataList = dataList;
+    }
+
+
+    public static final class Builder {
+        private String filed;
+        private List dataList;
+
+        private Builder() {
+        }
+
+        public Builder filed(String val) {
+            filed = val;
+            return this;
+        }
+
+        public Builder dataList(List val) {
+            dataList = val;
+            return this;
+        }
+
+        public InSearch build() {
+            return new InSearch(this);
+        }
+    }
+}

+ 62 - 0
elab-db/src/main/java/com/elab/core/dao/model/LikeSearch.java

@@ -0,0 +1,62 @@
+package com.elab.core.dao.model;
+
+/**
+ * 模糊匹配关键字
+ *
+ * @author : liukx
+ * @time : 2020/4/20 - 16:22
+ */
+public class LikeSearch {
+
+    private String field;
+
+    private String value;
+
+    private LikeSearch(Builder builder) {
+        setField(builder.field);
+        setValue(builder.value);
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    public String getField() {
+        return field;
+    }
+
+    public void setField(String field) {
+        this.field = field;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+
+    public static final class Builder {
+        private String field;
+        private String value;
+
+        private Builder() {
+        }
+
+        public Builder field(String val) {
+            field = val;
+            return this;
+        }
+
+        public Builder value(String val) {
+            value = val;
+            return this;
+        }
+
+        public LikeSearch build() {
+            return new LikeSearch(this);
+        }
+    }
+}

+ 154 - 0
elab-db/src/main/java/com/elab/core/dao/model/ListDynamicSearch.java

@@ -0,0 +1,154 @@
+package com.elab.core.dao.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 列表动态查询对象
+ *
+ * @author : liukx
+ * @time : 2020/4/16 - 16:29
+ */
+public class ListDynamicSearch {
+    /**
+     * 字段排序
+     */
+    private OrderBySearch orderBy;
+    /**
+     * 集合大小
+     */
+    private Integer limit;
+    /**
+     * 日期范围查询
+     */
+    private List<DataRangeSearch> dataRangeSearches;
+
+    /**
+     * in查询
+     */
+    private List<InSearch> inSearches;
+    /**
+     * like 查询
+     */
+    private List<LikeSearch> likeSearches;
+
+    public ListDynamicSearch() {
+    }
+
+
+    private ListDynamicSearch(Builder builder) {
+        setLikeSearches(builder.likeSearches);
+        setOrderBy(builder.orderBy);
+        setLimit(builder.limit);
+        setDataRangeSearches(builder.dataRangeSearches);
+        setInSearches(builder.inSearches);
+    }
+
+
+    public List<LikeSearch> getLikeSearches() {
+        return likeSearches;
+    }
+
+    public void setLikeSearches(List<LikeSearch> likeSearches) {
+        this.likeSearches = likeSearches;
+    }
+
+    public OrderBySearch getOrderBy() {
+        return orderBy;
+    }
+
+    public void setOrderBy(OrderBySearch orderBy) {
+        this.orderBy = orderBy;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+
+    public Integer getLimit() {
+        return limit;
+    }
+
+    public void setLimit(Integer limit) {
+        this.limit = limit;
+    }
+
+    public List<DataRangeSearch> getDataRangeSearches() {
+        return dataRangeSearches;
+    }
+
+    public void setDataRangeSearches(List<DataRangeSearch> dataRangeSearches) {
+        this.dataRangeSearches = dataRangeSearches;
+    }
+
+    public List<InSearch> getInSearches() {
+        return inSearches;
+    }
+
+    public void setInSearches(List<InSearch> inSearches) {
+        this.inSearches = inSearches;
+    }
+
+
+    public static final class Builder {
+        private OrderBySearch orderBy = new OrderBySearch();
+        private Integer limit;
+        private List<DataRangeSearch> dataRangeSearches = new ArrayList<>();
+        private List<InSearch> inSearches = new ArrayList<>();
+        private List<LikeSearch> likeSearches = new ArrayList<>();
+
+        private Builder() {
+        }
+
+
+        /**
+         * 根据指定字段排序
+         *
+         * @param field     字段名称
+         * @param orderType 字段类型  {@link OrderBySearch}
+         * @return
+         */
+        public Builder orderBy(String field, String orderType) {
+            orderBy.setField(field);
+            orderBy.setSortType(orderType);
+            return this;
+        }
+
+        /**
+         * 根据某字段排序,默认是DESC
+         *
+         * @param field 数据库字段名称
+         * @return
+         */
+        public Builder orderBy(String field) {
+            orderBy.setField(field);
+            return this;
+        }
+
+        public Builder limit(Integer val) {
+            limit = val;
+            return this;
+        }
+
+        public Builder dataRangeSearches(String filed, Object startData, Object endData) {
+            dataRangeSearches.add(DataRangeSearch.newBuilder().filed(filed).startData(startData).endData(endData)
+                    .build());
+            return this;
+        }
+
+        public Builder addInSearches(String field, List dataList) {
+            inSearches.add(InSearch.newBuilder().filed(field).dataList(dataList).build());
+            return this;
+        }
+
+        public ListDynamicSearch build() {
+            return new ListDynamicSearch(this);
+        }
+
+        public Builder addLikeSearches(String field, String value) {
+            likeSearches.add(LikeSearch.newBuilder().field(field).value(value).build());
+            return this;
+        }
+    }
+}

+ 39 - 0
elab-db/src/main/java/com/elab/core/dao/model/OrderBySearch.java

@@ -0,0 +1,39 @@
+package com.elab.core.dao.model;
+
+/**
+ * 排序
+ *
+ * @author : liukx
+ * @time : 2020/4/20 - 16:12
+ */
+public class OrderBySearch {
+
+    public static String DESC = "desc";
+
+    public static String ASC = "asc";
+
+    private String field;
+
+    private String sortType = DESC;
+
+    public OrderBySearch() {
+    }
+
+    public String getField() {
+        return field;
+    }
+
+    public void setField(String field) {
+        this.field = field;
+    }
+
+    public String getSortType() {
+        return sortType;
+    }
+
+    public void setSortType(String sortType) {
+        this.sortType = sortType;
+    }
+
+
+}

+ 91 - 0
elab-db/src/main/java/com/elab/core/dao/params/NamedParameterUtils2.java

@@ -16,8 +16,10 @@
 
 package com.elab.core.dao.params;
 
+import com.elab.core.dao.model.*;
 import com.elab.core.sql.config.SqlCommandType;
 import com.elab.core.utils.ObjectUtils;
+import com.elab.core.utils.StringUtils;
 import org.springframework.dao.InvalidDataAccessApiUsageException;
 import org.springframework.jdbc.core.SqlParameter;
 import org.springframework.jdbc.core.SqlParameterValue;
@@ -612,6 +614,95 @@ public abstract class NamedParameterUtils2 {
         return buildValueArray(parsedSql, new MapSqlParameterSource(paramMap), null);
     }
 
+    public static JdbcParamsModel appendSQLContent(String sql, Object[] data, ListDynamicSearch search) {
+        JdbcParamsModel model = new JdbcParamsModel();
+        StringBuffer sb = new StringBuffer(sql);
+        List<Object> datas = new ArrayList<Object>(Arrays.asList(data));
+        List<DataRangeSearch> dataRangeSearches = search.getDataRangeSearches();
+        if (dataRangeSearches != null) {
+            for (int i = 0; i < dataRangeSearches.size(); i++) {
+                DataRangeSearch dataRangeSearch = dataRangeSearches.get(i);
+                String filed = dataRangeSearch.getFiled();
+                Object startData = dataRangeSearch.getStartData();
+                Object endData = dataRangeSearch.getEndData();
+                if (StringUtils.isEmpty(filed)) {
+                    continue;
+//                    throw new ParamsException("对象DataRangeSearch中的field字段必填");
+                }
+
+                if (ObjectUtils.isNotEmpty(startData) && ObjectUtils.isNotEmpty(endData)) {
+                    continue;
+//                    throw new ParamsException("对象DataRangeSearch中的startData或endData字段必填一项");
+                }
+
+                if (ObjectUtils.isNotEmpty(startData)) {
+                    sb.append(" and " + filed + " >= ?");
+                    datas.add(startData);
+                }
+
+                if (ObjectUtils.isNotEmpty(endData)) {
+                    sb.append(" and " + filed + " <= ?");
+                    datas.add(endData);
+                }
+
+            }
+        }
+
+        List<InSearch> inSearches = search.getInSearches();
+
+        if (inSearches != null && inSearches.size() > 0) {
+            for (int i = 0; i < inSearches.size(); i++) {
+                InSearch inSearch = inSearches.get(i);
+                String filed = inSearch.getFiled();
+                List<Object> dataList = inSearch.getDataList();
+                if (StringUtils.isEmpty(filed)) {
+                    continue;
+                }
+
+                if (dataList == null) {
+                    continue;
+                }
+                if (dataList.size() > 0) {
+                    sb.append(" and " + filed + " in (");
+
+                    for (int j = 0; j < dataList.size(); j++) {
+                        if (j == 0) {
+                            sb.append("?");
+                        } else {
+                            sb.append(",?");
+                        }
+                    }
+
+                    sb.append(") ");
+                    datas.addAll(dataList);
+                }
+            }
+        }
+
+        OrderBySearch orderBy = search.getOrderBy();
+        if (StringUtils.isNotEmpty(orderBy.getField())) {
+            sb.append(" order by " + orderBy.getField() + " " + orderBy.getSortType());
+        }
+
+        Integer limit = search.getLimit();
+        if (limit != null) {
+            sb.append(" limit " + limit);
+        }
+
+        List<LikeSearch> likeSearches = search.getLikeSearches();
+        if (likeSearches.size() > 0) {
+            for (int i = 0; i < likeSearches.size(); i++) {
+                LikeSearch likeSearch = likeSearches.get(i);
+                sb.append(" and " + likeSearch.getField() + " like '" + likeSearch.getValue() + "'");
+            }
+        }
+
+        data = datas.toArray();
+        model.setSql(sb.toString());
+        model.setObjects(data);
+        return model;
+    }
+
 
     private static class ParameterHolder {
 

+ 15 - 2
elab-db/src/main/java/com/elab/core/spring/binding/DaoMethod.java

@@ -5,6 +5,7 @@ import com.elab.core.bean.PageModel;
 import com.elab.core.dao.BasicBaseDao;
 import com.elab.core.dao.IBaseDaoSupport;
 import com.elab.core.dao.IExampleDaoSupport;
+import com.elab.core.dao.model.ListDynamicSearch;
 import com.elab.core.dao.row.JoinRowMapper;
 import com.elab.core.spring.base.EntityOperation;
 import com.elab.core.spring.common.TypeGroupModel;
@@ -313,8 +314,18 @@ public class DaoMethod {
         boolean returnsMany = (returnType == List.class);
         boolean returnsMap = (returnType == Map.class);
         boolean returnPage = (returnType == PageModel.class);
-        TypeGroupModel paramsByType = DataUtils.getParamsByType(args);
+        TypeGroupModel paramsByType = DataUtils.getParamsByType(this.method, args);
         Object arg = args[0];
+        // 确定最终要执行的入参对象
+        // 这里的处理方式就是要么就是Map、要么就是Object、要么就是普通数组
+        if (paramsByType.getMap() != null && paramsByType.getMap().size() > 0) {
+            arg = paramsByType.getMap();
+        } else if (paramsByType.getObj() != null && paramsByType.getObj().length > 0) {
+            arg = paramsByType.getObj()[0];
+        }
+        // 如果需要追加动态参数对象处理
+        ListDynamicSearch listDynamicSearch = paramsByType.getListDynamicSearch();
+
         // 是否是返回多个对象,例如List
         if (returnsMany) {
             Class typeClass = getCacheMethodReturnClass();
@@ -323,7 +334,7 @@ public class DaoMethod {
             } else {
                 RowMapper rowMapper = paramsByType.getRowMapper();
                 if (rowMapper == null) {
-                    return this.basicBaseDao.executeQueryList(sql, arg, typeClass);
+                    return this.basicBaseDao.executeQueryList(sql, arg, listDynamicSearch, typeClass);
                 } else {
                     return this.basicBaseDao.executeQueryMapper(sql, arg, rowMapper);
                 }
@@ -355,6 +366,8 @@ public class DaoMethod {
             }
             pageModel.setResultSet(list);
             return pageModel;
+        } else if (returnType == Integer.class || returnType == Long.class) {
+            return this.basicBaseDao.executeQueryCount(sql, arg, listDynamicSearch, returnType);
         }
         // 返回是对象的
         else {

+ 14 - 0
elab-db/src/main/java/com/elab/core/spring/common/TypeGroupModel.java

@@ -1,6 +1,7 @@
 package com.elab.core.spring.common;
 
 import com.elab.core.bean.PageModel;
+import com.elab.core.dao.model.ListDynamicSearch;
 import org.springframework.jdbc.core.RowMapper;
 
 import java.util.Map;
@@ -25,6 +26,19 @@ public class TypeGroupModel {
 
     private Map map;
 
+    /**
+     * 集合列表动态查询参数
+     */
+    private ListDynamicSearch listDynamicSearch;
+
+    public ListDynamicSearch getListDynamicSearch() {
+        return listDynamicSearch;
+    }
+
+    public void setListDynamicSearch(ListDynamicSearch listDynamicSearch) {
+        this.listDynamicSearch = listDynamicSearch;
+    }
+
     public Map getMap() {
         return map;
     }

+ 21 - 2
elab-db/src/main/java/com/elab/core/spring/common/utils/DataUtils.java

@@ -1,11 +1,14 @@
 package com.elab.core.spring.common.utils;
 
 import com.elab.core.bean.PageModel;
+import com.elab.core.dao.model.ListDynamicSearch;
 import com.elab.core.spring.common.TypeGroupModel;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.jdbc.core.RowMapper;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.text.DecimalFormat;
@@ -516,15 +519,17 @@ public class DataUtils {
     /**
      * 将未知的方法属性归类到具体的model属性中,有特殊作用的按照特殊的处理
      *
+     * @param method
      * @param obj
      * @return
      */
-    public static TypeGroupModel getParamsByType(Object[] obj) {
+    public static TypeGroupModel getParamsByType(Method method, Object[] obj) {
         if (obj == null || obj.length == 0) {
             return null;
         }
         TypeGroupModel model = new TypeGroupModel();
         List<Object> dataList = new ArrayList<>();
+        Map<String, Object> dataMap = new LinkedHashMap<>();
         for (int i = 0; i < obj.length; i++) {
             Object o = obj[i];
             if (o instanceof RowMapper) {
@@ -533,10 +538,24 @@ public class DataUtils {
                 model.setPageModel((PageModel) o);
             } else if (o instanceof Map) {
                 model.setMap((Map) o);
+            } else if (o instanceof ListDynamicSearch) {
+                if (o != null) {
+                    model.setListDynamicSearch((ListDynamicSearch) o);
+                }
             } else {
-                dataList.add(o);
+                // 这里如果配置上了@FiledPram注解的话,默认将普通参数构建成Map
+                Annotation[] annotations = method.getParameterAnnotations()[i];
+                if (annotations.length > 0) {
+                    Object value = AnnotationUtils.getValue(annotations[0]);
+                    if (value != null) {
+                        dataMap.put(value.toString(), o);
+                    }
+                } else {
+                    dataList.add(o);
+                }
             }
         }
+        model.setMap(dataMap);
         model.setObj(dataList.toArray());
         return model;
     }

+ 15 - 1
elab-db/src/main/java/com/elab/core/spring/method/DefaultSQLBuilderSupport.java

@@ -31,6 +31,7 @@ public class DefaultSQLBuilderSupport implements ISQLBuliderSupport {
     public final String batchInsertByMap = "batchInsertByMap";
     public final String batchUpdateByObject = "batchUpdateByObject";
     public final String batchUpdateByMap = "batchUpdateByMap";
+    public final String selectByObjectToCount = "selectByObjectToCount";
 
 
     /**
@@ -54,6 +55,8 @@ public class DefaultSQLBuilderSupport implements ISQLBuliderSupport {
             sql = selectSql(entityOperation);
         } else if (selectById.equals(name)) {
             sql = selectByIdSql(entityOperation);
+        } else if (selectByObjectToCount.equals(name)) {
+            sql = getSelectByObjectToCount(entityOperation);
         }
         // 上层给做掉的了
         else if (findMethodName.equals(name)) {
@@ -79,7 +82,6 @@ public class DefaultSQLBuilderSupport implements ISQLBuliderSupport {
         return sb.toString();
     }
 
-
     /**
      * 创建删除语句流程
      *
@@ -200,4 +202,16 @@ public class DefaultSQLBuilderSupport implements ISQLBuliderSupport {
         return sb.toString();
     }
 
+    public String getSelectByObjectToCount(EntityOperation entityOperation) {
+        String allColumn = entityOperation.allColumn;
+        String tableName = entityOperation.tableName;
+        Map<String, String> allProperty = entityOperation.allProperty;
+        String id = entityOperation.pkField.getName();
+        StringBuffer sb = new StringBuffer();
+        // 这里默认会将主键放在第一位
+        sb.append(" select  count(1) from " + tableName + " where " + id + " =:" + id + " and ");
+        mappingToString(allProperty, sb, " and ", "=:");
+        return sb.toString();
+    }
+
 }

+ 7 - 0
elab-db/src/test/java/com.db.service/dao/ITestDao.java

@@ -2,8 +2,10 @@ package com.db.service.dao;
 
 import com.db.service.model.TTest;
 import com.db.service.model.TTest2;
+import com.elab.core.aop.annotations.FieldParam;
 import com.elab.core.aop.annotations.XmlGroupName;
 import com.elab.core.dao.IBaseDaoSupport;
+import com.elab.core.dao.model.ListDynamicSearch;
 import org.springframework.jdbc.core.RowMapper;
 
 import java.util.List;
@@ -19,8 +21,13 @@ public interface ITestDao extends IBaseDaoSupport<TTest> {
 
     public TTest getTestObject(String id);
 
+    public TTest selectByName(@FieldParam("id") String id, @FieldParam("username") String username);
+
     public List<TTest2> getTestList(TTest id);
 
+    public List<TTest> getTestList2(TTest id, ListDynamicSearch search);
+
+
     public List<TTest> getTestList(Map<String, Object> objectMap, RowMapper rowMapper);
 
     public int[] batchInsert(Object list);

+ 15 - 166
elab-db/src/test/java/com.db.service/main/BasicBaseDaoCase.java

@@ -1,23 +1,14 @@
 package com.db.service.main;
 
-import com.alibaba.fastjson.JSON;
-import com.db.service.dao.IHelloDao;
-import com.db.service.dao.ITestDao;
-import com.db.service.dao.ITestDao2;
-import com.db.service.mapper.TestRowMapper;
 import com.db.service.model.TTest;
-import com.db.service.model.TTest2;
-import com.db.service.model.TTestExample;
-import com.elab.core.bean.PageModel;
 import com.elab.core.dao.BasicBaseDao;
+import com.elab.core.sql.ConfigurableFactory;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import java.util.*;
-
 /**
  * 基于拓展的测试用例
  *
@@ -27,20 +18,17 @@ import java.util.*;
  **/
 @RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试
 @ContextConfiguration
-        ({"classpath:applicationContext-*.xml",})
+        ({"classpath:applicationContext-datasource.xml",})
 public class BasicBaseDaoCase {
 
     @Autowired
-    private BasicBaseDao basicBaseDao;
-
-    @Autowired
-    private ITestDao testDao;
+    private ConfigurableFactory configurableFactory;
 
     @Autowired
-    private ITestDao2 testDao2;
+    private BasicBaseDao basicBaseDao;
 
-    @Autowired
-    private IHelloDao helloDao;
+//    @Autowired
+//    private IHelloDao helloDao;
 
 //    @Test
 //    public void executeQueryforListMap() {
@@ -86,158 +74,19 @@ public class BasicBaseDaoCase {
 //        System.out.println(i);
 //    }
 
-    ////////////////////////////代理测试/////////////////////////////////////////
-
-    @Test
-    public void testInsertCase() throws Exception {
-        TTest test = new TTest();
-        test.setStatus("1");
-        test.setUsername("某某某xx111");
-//        test.setTestId("123123");
-        test.setSex("Man");
-        int insert = testDao.insert(test);
-        System.out.println(insert);
-    }
-
-    @Test
-    public void testUpdateCase() throws Exception {
-        TTest test = new TTest();
-        test.setId(1);
-        test.setStatus("1");
-        test.setUsername("某某某xx33333333");
-        int insert = testDao.updateById(test);
-        System.out.println(insert);
-    }
-
-    @Test
-    public void testQueryCase() throws Exception {
-        TTest test = new TTest();
-//        test.setId(1123);
-        test.setStatus("1");
-//        test.setTestId("21");
-//        test.setUsername("某某某xx2121212");
-        List<TTest> tTests = testDao.selectByList(test);
-//        test.setId(1);
-//        TTest test1 = testDao.selectByObject(test);
-//        System.out.println(test1.toString());
-//        System.out.println(tTests.size());
-    }
-
-    @Test
-    public void testExampleQueryCase() throws Exception {
-        TTest test = new TTest();
-//        test.setId(1);
-        test.setStatus("1");
-//        test.setUsername("某某某xx2121212");
-        TTestExample example = new TTestExample();
-        TTestExample.Criteria criteria = example.createCriteria();
-//        criteria.andIdEqualTo(1);
-        List<Integer> list = new ArrayList<>();
-        list.add(1);
-        list.add(3);
-        list.add(4);
-        criteria.andIdIn(list);
-
-//        criteria.andUsernameLike("某某某xx333%");
-
-        List<TTest> tTests = testDao2.find(example);
-        System.out.println(tTests);
-    }
-
     @Test
-    public void testProxyDao() {
+    public void executeQueryList() throws Exception {
+//        String sql = configurableFactory.getSqlConfigurableFactory().getSql("test.selectByObjectToCount");
+        String sql = "select  count(1) from test.t_test where id =:id and love_name =:loveName  and  created " +
+                "=:created  and  sex =:sex  and  name =:name  and  id =:id  and  time =:time  and  username =:username  and  status =:status  and  test_id =:testId";
         TTest test = new TTest();
         test.setStatus("1");
-        List<TTest2> testList = testDao.getTestList(test);
-        System.out.println();
-
-//        LinkedHashMap<String, Object> map = new LinkedHashMap();
-//        map.put("id", "1");
-//        List<CustomerDTO> customerDTOs = helloDao.getListForObject(map);
-//        System.out.println(testList.size() + "\t" + customerDTOs.size());
-    }
-
-    @Test
-    public void testPageDao() throws Exception {
-        TTest test = new TTest();
-        test.setStatus("1");
-
-        PageModel pageModel = new PageModel(0, 3, 10);
-        pageModel.setOrderby("order by id desc");
-        PageModel<TTest> tTestPageModel = testDao.selectByPage(pageModel, test);
-        System.out.println(JSON.toJSONString(tTestPageModel));
-    }
-
-    @Test
-    public void testSelectByIdDao() throws Exception {
-        TTest test = testDao.selectById("1");
-        System.out.println(test.toString());
-    }
-
-    @Test
-    public void testSelectByMapper() throws Exception {
-        TTest test = new TTest();
-        test.setStatus("1");
-        TestRowMapper mapper = new TestRowMapper();
-        List<TTest> tTests1 = testDao.selectByList(test);
-        List<TTest> tTests = testDao.selectByMapper(test, mapper);
-        System.out.println(tTests.toString());
-    }
-
-    @Test
-    public void testSelectByMapper2() throws Exception {
-        Map<String, Object> map = new HashMap<>();
-        map.put("status", "1");
-        TestRowMapper mapper = new TestRowMapper();
-        List<TTest> tTests = testDao.getTestList(map, mapper);
-        System.out.println(tTests.toString());
-    }
-
-    ///////////////////////////////////// service //////////////////////////////////
-    @Test
-    public void testService() {
-
-    }
-
-    @Test
-    public void testBatchBeanInsert() {
-        List<TTest> list = new ArrayList<>();
-        for (int i = 0; i < 100; i++) {
-            TTest test = new TTest();
-            test.setStatus("1");
-            test.setUsername("batchTest_" + i);
-            test.setSex("Man");
-            test.setTestId("bbbb");
-            list.add(test);
-        }
-
-        int[] ints = testDao.batchInsert(list);
-        System.out.println(Arrays.toString(ints));
-    }
-
-    @Test
-    public void testBatchMapInsert() {
-        List<Map> maps = new ArrayList<>();
-
-        for (int i = 0; i < 10; i++) {
-            Map<String, String> map = new HashMap<>();
-            map.put("status", "1");
-            map.put("username", "batchMap_" + i);
-            map.put("sex", "Man");
-            maps.add(map);
-        }
-        int[] ints = testDao.batchInsert(maps);
-        System.out.println(ints.length);
+        Long integer = basicBaseDao.executeQueryCount(sql,
+                test, null, Long.class);
+//        Long integer1 = basicBaseDao.getJdbcTemplate().queryForObject("select  count(1) from test.t_test where 1=1   and  status =?",
+//                new Object[]{1}, Long.class);
+        System.out.println(integer);
     }
 
-//    public static void main(String[] args) {
-//        BasicBaseDaoCase basicBaseDaoCase = new BasicBaseDaoCase();
-//        basicBaseDaoCase.executeQueryforListMap();
-//        basicBaseDaoCase.executeQueryList();
-//        basicBaseDaoCase.executeQueryBigDataList();
-//        basicBaseDaoCase.executeInsert();
-//        basicBaseDaoCase.executeUpdate();
-//    }
-
 
 }

+ 296 - 0
elab-db/src/test/java/com.db.service/main/BasicBaseDaoProxyCase.java

@@ -0,0 +1,296 @@
+package com.db.service.main;
+
+import com.alibaba.fastjson.JSON;
+import com.db.service.dao.ITestDao;
+import com.db.service.dao.ITestDao2;
+import com.db.service.mapper.TestRowMapper;
+import com.db.service.model.TTest;
+import com.db.service.model.TTest2;
+import com.db.service.model.TTestExample;
+import com.elab.core.bean.PageModel;
+import com.elab.core.dao.model.DataRangeSearch;
+import com.elab.core.dao.model.ListDynamicSearch;
+import com.elab.core.dao.model.OrderBySearch;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.*;
+
+/**
+ * 基于拓展的测试用例
+ *
+ * @author Liukx
+ * @create 2018-04-20 15:57
+ * @email liukx@elab-plus.com
+ **/
+@RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试
+@ContextConfiguration
+        ({"classpath:applicationContext-datasource.xml",})
+public class BasicBaseDaoProxyCase {
+
+    @Autowired
+    private ITestDao testDao;
+
+    @Autowired
+    private ITestDao2 testDao2;
+
+    ////////////////////////////代理测试/////////////////////////////////////////
+
+    @Test
+    public void testInsertCase() throws Exception {
+        TTest test = new TTest();
+        test.setStatus("1");
+        test.setUsername("某某某xx111");
+//        test.setTestId("123123");
+        test.setSex("Man");
+        int insert = testDao.insert(test);
+        System.out.println(insert);
+        Assert.assertTrue(insert > 0);
+
+    }
+
+    @Test
+    public void testUpdateCase() throws Exception {
+        TTest test = new TTest();
+        test.setId(1);
+        test.setStatus("1");
+        test.setUsername("某某某xx33333333");
+        int insert = testDao.updateById(test);
+        System.out.println(insert);
+        Assert.assertTrue(insert > 0);
+    }
+
+    @Test
+    public void testQueryCase() throws Exception {
+        TTest test = new TTest();
+//        test.setId(1123);
+        test.setStatus("1");
+//        test.setTestId("21");
+//        test.setUsername("某某某xx2121212");
+        List<TTest> tTests = testDao.selectByList(test);
+        Assert.assertTrue(tTests.size() > 0);
+
+//        test.setId(1);
+//        TTest test1 = testDao.selectByObject(test);
+//        System.out.println(test1.toString());
+//        System.out.println(tTests.size());
+    }
+
+    @Test
+    public void testSelectByListDynamic() throws Exception {
+        TTest test = new TTest();
+//        test.setId(1123);
+        test.setStatus("1");
+//        test.setTestId("21");
+//        test.setUsername("某某某xx2121212");
+//        List<TTest> tTests = testDao.selectByList(test);
+//        ListDynamicSearch search = new ListDynamicSearch();
+////        search.setLimit(10);
+////        search.setOrderBy("id");
+//        InSearch inSearch = new InSearch();
+//        inSearch.setFiled("id");
+//        inSearch.setDataList(Arrays.asList(1, 2));
+//        search.setInSearches(Arrays.asList(inSearch));
+//        DataRangeSearch search1 = new DataRangeSearch();
+//        search1.setFiled("time");
+//        search1.setStartData(new Date());
+//        search.setDataRangeSearches(Arrays.asList(search1));
+
+        ListDynamicSearch id_desc = ListDynamicSearch.newBuilder().orderBy("id", OrderBySearch.ASC).build();
+
+        List<TTest> tTests = testDao.selectByList(test, id_desc);
+
+
+        Assert.assertTrue(tTests.size() > 0);
+    }
+
+    @Test
+    public void testExampleQueryCase() throws Exception {
+        TTest test = new TTest();
+//        test.setId(1);
+        test.setStatus("1");
+//        test.setUsername("某某某xx2121212");
+        TTestExample example = new TTestExample();
+        TTestExample.Criteria criteria = example.createCriteria();
+//        criteria.andIdEqualTo(1);
+        List<Integer> list = new ArrayList<>();
+        list.add(1);
+        list.add(3);
+        list.add(4);
+        criteria.andIdIn(list);
+
+//        criteria.andUsernameLike("某某某xx333%");
+
+        List<TTest> tTests = testDao2.find(example);
+        System.out.println(tTests);
+        Assert.assertTrue(tTests.size() > 0);
+
+    }
+
+    @Test
+    public void testProxyDao() {
+        TTest test = new TTest();
+        test.setStatus("1");
+        List<TTest2> testList = testDao.getTestList(test);
+        System.out.println();
+        Assert.assertTrue(testList.size() > 0);
+//        LinkedHashMap<String, Object> map = new LinkedHashMap();
+//        map.put("id", "1");
+
+
+//        List<CustomerDTO> customerDTOs = helloDao.getListForObject(map);
+//        System.out.println(testList.size() + "\t" + customerDTOs.size());
+    }
+
+    @Test
+    public void testPageDao() throws Exception {
+        TTest test = new TTest();
+        test.setStatus("1");
+
+        PageModel pageModel = new PageModel(0, 3, 10);
+        pageModel.setOrderby("order by id desc");
+        PageModel<TTest> tTestPageModel = testDao.selectByPage(pageModel, test);
+        System.out.println(JSON.toJSONString(tTestPageModel));
+        Assert.assertNotNull(tTestPageModel);
+    }
+
+    @Test
+    public void testSelectByIdDao() throws Exception {
+        TTest test = testDao.selectById("1");
+        System.out.println(test.toString());
+        Assert.assertNotNull(test);
+    }
+
+    @Test
+    public void testSelectByObjectToCount() throws Exception {
+        TTest test = new TTest();
+        test.setStatus("1");
+
+
+        Integer count = testDao.selectByObjectToCount(test);
+
+
+        ListDynamicSearch search = getListDynamicSearch();
+        Integer count1 = testDao.selectByObjectToCount(test, search);
+        System.out.println(count + "\t" + count1);
+        Assert.assertNotNull(count);
+        Assert.assertNotNull(count1);
+    }
+
+    private ListDynamicSearch getListDynamicSearch() {
+        ListDynamicSearch search = new ListDynamicSearch();
+        DataRangeSearch dataRangeSearch = new DataRangeSearch();
+        dataRangeSearch.setFiled("time");
+        dataRangeSearch.setStartData(new Date());
+        search.setDataRangeSearches(Arrays.asList(dataRangeSearch));
+        return search;
+    }
+
+    @Test
+    public void testSelectByName() throws Exception {
+        TTest bbb = testDao.selectByName("1", "某某某xx33333333");
+        System.out.println(bbb.toString());
+        Assert.assertTrue(bbb != null);
+    }
+
+    @Test
+    public void testSelectByMapper() throws Exception {
+        TTest test = new TTest();
+        test.setStatus("1");
+        TestRowMapper mapper = new TestRowMapper();
+        List<TTest> tTests1 = testDao.selectByList(test);
+        List<TTest> tTests = testDao.selectByMapper(test, mapper);
+        System.out.println(tTests.toString());
+        Assert.assertTrue(tTests1.size() > 0);
+        Assert.assertTrue(tTests.size() > 0);
+    }
+
+    @Test
+    public void testSelectByMapper2() throws Exception {
+        Map<String, Object> map = new HashMap<>();
+        map.put("status", "1");
+        TestRowMapper mapper = new TestRowMapper();
+        List<TTest> tTests = testDao.getTestList(map, mapper);
+        System.out.println(tTests.toString());
+        Assert.assertTrue(tTests.size() > 0);
+
+    }
+
+    @Test
+    public void testgetTestList2() throws Exception {
+        TTest test = new TTest();
+        test.setStatus("1");
+        List<String> list = new ArrayList<>();
+        list.add("1");
+        list.add("2");
+        list.add("3");
+        ListDynamicSearch listDynamicSearch = ListDynamicSearch.newBuilder().addInSearches("id", list).build();
+//        ListDynamicSearch listDynamicSearch = ListDynamicSearch.newBuilder().addLikeSearches("username", "b%")
+//                .build();
+        ListDynamicSearch.newBuilder().addInSearches("id", list)
+                .limit(1)
+                .addLikeSearches("","")
+                .dataRangeSearches("time",new Date(),new Date())
+                .orderBy("id",OrderBySearch.DESC);
+        // 普通方法追加动态参数
+//        ListDynamicSearch listDynamicSearch = getListDynamicSearch();
+        List<TTest> tTests = testDao.getTestList2(test, listDynamicSearch);
+        System.out.println(tTests.toString());
+        Assert.assertTrue(tTests.size() > 0);
+
+    }
+
+    ///////////////////////////////////// service //////////////////////////////////
+
+    @Test
+    public void testBatchBeanInsert() {
+        List<TTest> list = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            TTest test = new TTest();
+            test.setStatus("1");
+            test.setUsername("batchTest_" + i);
+            test.setSex("Man");
+            test.setTestId("bbbb");
+            test.setTime(new Date());
+            test.setCreated(new Date());
+            test.setName("batchTest_name_" + i);
+            list.add(test);
+        }
+
+        int[] ints = testDao.batchInsert(list);
+        System.out.println(Arrays.toString(ints));
+        Assert.assertTrue(ints.length > 0);
+
+    }
+
+    @Test
+    public void testBatchMapInsert() {
+        List<Map> maps = new ArrayList<>();
+
+        for (int i = 0; i < 10; i++) {
+            Map<String, String> map = new HashMap<>();
+            map.put("status", "1");
+            map.put("username", "batchMap_" + i);
+            map.put("sex", "Man");
+            maps.add(map);
+        }
+        int[] ints = testDao.batchInsert(maps);
+        System.out.println(ints.length);
+        Assert.assertTrue(ints.length > 0);
+    }
+
+//    public static void main(String[] args) {
+//        BasicBaseDaoCase basicBaseDaoCase = new BasicBaseDaoCase();
+//        basicBaseDaoCase.executeQueryforListMap();
+//        basicBaseDaoCase.executeQueryList();
+//        basicBaseDaoCase.executeQueryBigDataList();
+//        basicBaseDaoCase.executeInsert();
+//        basicBaseDaoCase.executeUpdate();
+//    }
+
+
+}

+ 1 - 1
elab-db/src/test/java/com.db.service/model/TTest.java

@@ -11,7 +11,7 @@ import java.util.List;
 
 //import javax.persistence.Table;
 //implements ColumnMapping
-@Table(name = "t_test",catalog = "xiong")
+@Table(name = "t_test",catalog = "test")
 public class TTest implements ColumnMapping {
     //
     // 表字段 : t_test.id

+ 1 - 1
elab-db/src/test/resources/applicationContext-datasource.xml

@@ -14,7 +14,7 @@
 
     <bean id="mysqlDataSource" class="com.alibaba.druid.pool.DruidDataSource">
         <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
-        <property name="url" value="jdbc:mysql://localhost:3306/xiong?characterEncoding=utf-8"/>
+        <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8"/>
         <property name="username" value="root"/>
         <property name="password" value="1234"/>
         <property name="initialSize" value="50"/>

+ 25 - 0
elab-db/src/test/resources/logback.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <include resource="org/springframework/boot/logging/logback/base.xml"/>
+    <jmxConfigurator/>
+    <property name="LOG_PATH" value="logs"/>
+    <property name="APPLICATION" value="elab-marketing-user" />
+
+    <appender name="elab-marketing-info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <File>${LOG_PATH}/${APPLICATION}.log</File>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <fileNamePattern>${LOG_PATH}/%d{yyyyMMdd}/${APPLICATION}-%d{yyyyMMdd}-%i.log</fileNamePattern>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>30GB</totalSizeCap>
+            <maxFileSize>100MB</maxFileSize>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - [%file:%line] - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="elab-marketing-info"/>
+    </root>
+    <logger name="com.elab" level="DEBUG"/>
+</configuration>

+ 15 - 6
elab-db/src/test/resources/sql/test-sql.xml

@@ -25,12 +25,12 @@
     </sql>
 
     <!--<sql id="selectById">-->
-        <!--select-->
-        <!--id-->
-        <!--,username,name,sex,status,created,time,test_id,love_name-->
-        <!--from t_test-->
-        <!--where-->
-        <!--id = :id-->
+    <!--select-->
+    <!--id-->
+    <!--,username,name,sex,status,created,time,test_id,love_name-->
+    <!--from t_test-->
+    <!--where-->
+    <!--id = :id-->
     <!--</sql>-->
     <sql id="selectByName">
         select
@@ -85,4 +85,13 @@
         where
         status = :status
     </sql>
+
+    <sql id="getTestList2">
+        select
+        id
+        ,username,name,sex,status,created,time,test_id,love_name
+        from t_test
+        where
+        status = :status
+    </sql>
 </sqlGroup>

+ 12 - 0
elab-db/src/test/resources/test.sql

@@ -0,0 +1,12 @@
+CREATE TABLE `t_test` (
+`id` int(11) NOT NULL AUTO_INCREMENT,
+`username` varchar(255) DEFAULT NULL,
+`name` varchar(255) DEFAULT NULL,
+`sex` varchar(255) DEFAULT NULL,
+`status` varchar(255) DEFAULT NULL,
+`time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+`created` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+`test_id` varchar(222) DEFAULT NULL,
+`love_name` varchar(255) DEFAULT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

+ 135 - 0
elab-log/README.md

@@ -0,0 +1,135 @@
+## CAT日志使用介绍
+
+[cat-github](https://github.com/dianping/cat)
+
+### 配置环境
+1. 加载CAT配置
+  `在resource目录下创建文件夹META-INF`
+  然后创建一个`app.properties`文件里面定义`app.name=cat-demo`,后面是应用的名称
+
+如果是SpringBoot可以在yml配置中加入
+```yml
+app.name: 项目名 # 针对CAT各个环境的项目名标识
+```
+
+2. 加载配置 [xml]
+
+```xml
+<dependency>
+    <groupId>com.elab.log</groupId>
+    <artifactId>elab-log</artifactId>
+    <version>1.0</version>
+</dependency>
+```
+  2.1 spring配置
+```xml
+<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
+
+<!-- 定义一个bean -->
+<bean id="catAspect" class="com.elab.log.asepct.CatAspect">
+</bean>
+
+<!-- 加载一个切入点 -->
+<aop:config>
+   <aop:aspect id="myAspect" ref="myInterceptor">
+            <aop:pointcut  id="catPoint"  expression="execution(* com.elab.cat.catdemo.service..*(..))" />
+            <aop:around pointcut-ref="catPoint" method="aroundMethod" />
+   </aop:aspect>
+</aop:config>
+```
+2.1 加载配置[configuration]
+AOP配置 :
+Dao层 : CatDaoAscept
+Service层 : CatAspect
+
+应用中加入:
+```java
+
+import com.elab.log.asepct.CatDaoAscept;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+/**
+ * dao层AOP拦截器定义
+ *
+ * @author Liuhx
+ * @create 2018-06-14 11:28
+ * @email liuhx@elab-plus.com
+ **/
+@Aspect
+@EnableAspectJAutoProxy
+@Configuration
+public class DaoAspectBean {
+    @Bean
+    public CatDaoAscept getDaoAspect() {
+        CatDaoAscept daoAspect = new CatDaoAscept();
+        return daoAspect;
+    }
+
+    @Around(value = "execution(* com.elab.marketing.auth.dao..*(..))")
+    public Object around(ProceedingJoinPoint pjp) throws Throwable {
+        return getDaoAspect().around(pjp);
+    }
+}
+```
+
+2.2 log4j配置
+```tex
+log4j.rootLogger=info, Console ,cat
+## 控制台
+log4j.appender.Console=org.apache.log4j.ConsoleAppender
+log4j.appender.Console.layout=org.apache.log4j.PatternLayout
+log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
+## 这个配置很重要,集成了CAT的日志
+log4j.appender.cat=com.elab.log.log4j.CatExtLog
+log4j.appender.cat.Threshold = INFO
+log4j.appender.cat.layout=org.apache.log4j.PatternLayout
+log4j.appender.cat.layout.ConversionPattern=%p: [%d{yy/MM/dd HH:mm:ss}][%C-%M] -%m%n
+## sql语句
+log4j.logger.java.sql.Connection=DEBUG
+log4j.logger.java.sql.Statement=DEBUG
+## 包下面的类的打印级别
+log4j.logger.org=ERROR
+log4j.logger.org.springframework=ERROR
+log4j.logger.com.x.jdbc=DEBUG
+```
+2.3 logback配置
+```xml
+<appender name="cat" class="com.elab.log.log4j.CatLogbackLog"></appender>
+<root level="INFO">
+    <appender-ref ref="cat"/>
+</root>
+```
+
+3. 应用中植入CAT日志
+```java
+// 建议在方法上加入 controller、service
+//username 为作者名称
+@ExceptionHandle(username = "liukx",ModuleName=TestServiceImpl.class)
+
+protected final Log logger = LogFactory.getLog(this.getClass());
+
+// 下面两种日志会输出到Event模块下
+// 打印info日志
+logger.info("xxx");
+// 打印debug日志
+logger.info("ggg");
+// 打印错误日志 => 错误日志会出现在Problem
+logger.error("lll");
+```
+
+
+
+4. **需要注意**
+   1. 应用中需要根据自己的需求将对应的`logger.info`打印出来
+   2. **如何查看对应的CAT在当前的哪个环境下?**
+      1. 到你当前项目的文件夹的根目录下,比如我:E:\data\appdatas\cat\client.xml
+      2. 里面有对应的路径地址,表明当前项目的日志会上传到这个对应的CAT下面
+   3. **如何查看对应的错误?**
+      1. 登录CAT的web查询页面
+      2. 选择对应的项目
+      3. 点击Problem页面查看

+ 169 - 0
elab-mongodb/src/REDEME.md

@@ -0,0 +1,169 @@
+# Elab-mongodb 使用介绍
+## pom.xml
+```xml
+<dependency>
+	<groupId>com.elab.core</groupId>
+	<artifactId>elab-mongodb</artifactId>
+	<!-- 这里根据实际情况定义版本号 -->
+	 <version>2.0.4.4</version>
+</dependency>
+```
+
+## 配置类
+```java
+@Configuration
+public class MongoBeanConfig {
+
+    @Value("${mongodb.host}")
+    private String mongodbHost;
+  @Value("${mongodb.port}")
+    private int mongdbPort;
+  @Value("${mongodb.database.name}")
+    private String mongodbDataBaseName;
+
+  @Bean
+  public MongoTemplate MongoTemplate() throws UnknownHostException {
+        MongoTemplate mongoTemplate = new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(mongodbHost, mongdbPort),
+  mongodbDataBaseName));
+ return mongoTemplate;
+  }
+
+}
+
+```
+
+## 配置文件中需要制定mongodb的数据源
+```tex
+mongodb.host=
+mongodb.port=
+mongodb.database.name=
+```
+
+## 代码层的使用:
+
+### dao层
+```java
+/**
+ * * @author Liukx
+ * @create 2018-05-03 15:41
+ * @email liukx@elab-plus.com
+ **/public class UserMongoDB extends BaseMongodb<具体实体对象> {
+
+    @Override
+  public Class getEntity() {
+        return User.class;
+  }
+
+  // 如果是针对名称操作的,重写collectionNamed的方法 针对对应的库名做映射,如果一开始就是对象操作的,则不用重写
+  @Override
+  protected String getCollectionName() {
+	  return "collectionName";
+  }
+
+  @Autowired
+  private MongoTemplate mongoTemplate;
+
+  @Override
+  public MongoTemplate getMongoTemplate() {
+        return mongoTemplate;
+  }
+}
+```
+
+### service层:
+```java
+
+@Autowired
+UserMongoDB mongoDB;
+
+
+User user = new User("uuu", "123", "7");
+User user1 = new User("jjj", "123", "8");
+User user2 = new User("kkkk", "123", "9");
+List list = new ArrayList<>();
+list.add(user);
+list.add(user1);
+list.add(user2);
+mongoDB.batchSave(list);
+
+```
+
+# 拓展
+### 针对GEO操作
+
+
+- 针对box操作
+- ![imagepng](http://oub49vfnw.bkt.clouddn.com//file/2018/05/dc11eaa388e1427baa2d48247f45644a_image.png)
+
+```java
+
+  // 传入两个坐标
+  Point point = new Point(121.591528, 21.591528);
+  Point point1 = new Point(121.572344, 21.572344);
+  Box box = new Box(point,point1);
+  // 指定字段查询
+  Criteria coordinate = Criteria.where("字段名").within(box);
+  Query query = Query.query(coordinate);
+  List list = getMongoTemplate().find(query, getEntity(), getCollectionName());
+
+```
+- 针对圆角范围查询
+
+![imagepng](http://oub49vfnw.bkt.clouddn.com//file/2018/05/71861c2bc6e746c1ae2124704f68fc21_image.png)
+
+
+
+```java
+Point point = new Point(121.591528, 21.591528);
+double radius = 6378137 / 3000;
+Sphere sphere = new Sphere(point, radius);
+Criteria coordinate = Criteria.where("字段名").within(sphere);
+Query query = Query.query(coordinate);
+List list = getMongoTemplate().find(query, getEntity(), getCollectionName());
+
+```
+
+- 针对中心范围查询
+
+![imagepng](http://oub49vfnw.bkt.clouddn.com//file/2018/05/c29b3f894c8b4ef0ba112ecf403669d1_image.png)
+
+
+```java
+
+Point point = new Point(121.591528, 21.591528);
+double radius = 6378137 / 3000;
+Circle sphere = new Circle(point, radius);
+Criteria coordinate = Criteria.where("字段名").within(sphere);
+Query query = Query.query(coordinate);
+List list = getMongoTemplate().find(query, getEntity(), getCollectionName());
+System.out.println(list.size());
+
+```
+
+
+- 针对多个坐标点查询
+
+![imagepng](http://oub49vfnw.bkt.clouddn.com//file/2018/05/3e479431da0f470c93b4beb5f6c2fe7f_image.png)
+
+
+
+```java
+Point point = new Point(121.591528, 21.591528);
+Point point1 = new Point(121.591528, 21.591528);
+Point point2 = new Point(121.591528, 21.591528);
+
+List addressList = new ArrayList<>();
+addressList.add(point);
+addressList.add(point1);
+addressList.add(point2);
+
+
+Polygon sphere = new Polygon(addressList);
+Criteria coordinate = Criteria.where("coordinate").within(sphere);
+Query query = Query.query(coordinate);
+List list = getMongoTemplate().find(query, getEntity(), getCollectionName());
+System.out.println(list.size());
+```
+
+
+

+ 66 - 1
elab-mq/README.md

@@ -12,6 +12,9 @@
 </dependency>
 ```
 
+注意: 当你引用这个包的时候,功能已经开启。但是下面的配置也必须填写.
+
+
 ## 属性配置
 
 ```properties
@@ -70,7 +73,9 @@ public class ConsumerServiceImpl extends AbstractMessageListener {
     @Override
     public String topic() {
         return "T-consumer1";
-    } 
+    }
+
+    // todo 另外强烈建议重写tag方法,一个项目对应一个topic,该项目下的业务用tag区分。
 
     @Override
     public Action consume0(Message message, ConsumeContext consumeContext) {
@@ -80,3 +85,63 @@ public class ConsumerServiceImpl extends AbstractMessageListener {
 }
 ```
 
+## 幂等
+- 生产者生产消息的时候,会去往表【mq_producer】中插入一条数据,字段中包含是否发送成功状态,发送的监控编号【cat_id】等等.
+但是如果你要处理这种重复发送同一条消息的时候,没有做区分。正常来讲应该通过key字段去做唯一校验,但是并不是所有业务都会传这个东西。
+
+- 消费者消费消息的时候会记录表【mq_consumer】,包括重试几次、消费状态、监控编号等等。
+
+目前是强耦合了CAT[elab-log]监控系统、如果你有其他需求可能需要改源码。
+
+如果出现消息发送失败或者消费失败可以去这两张表中找对应的数据,确保数据不会丢失。
+```sql
+-- ----------------------------
+-- Table structure for mq_consumer
+-- ----------------------------
+DROP TABLE IF EXISTS `mq_consumer`;
+CREATE TABLE `mq_consumer` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `producer_id` int(11) DEFAULT NULL COMMENT '生产者消息id',
+  `msg_id` varchar(100) DEFAULT NULL COMMENT 'MQ的消息编号',
+  `module_name` varchar(300) DEFAULT NULL COMMENT '模块名称',
+  `module_method` varchar(200) DEFAULT NULL COMMENT '模块的方法名,用来处理一个项目里面同一个topic和tag被多个消费处理',
+  `house_id` int(11) DEFAULT NULL COMMENT '项目id',
+  `topic_id` varchar(300) DEFAULT NULL COMMENT 'topic的id',
+  `tag` varchar(100) DEFAULT NULL COMMENT '标签名',
+  `content` varchar(4000) DEFAULT NULL COMMENT '消费内容',
+  `consumer_status` int(11) DEFAULT NULL COMMENT '消费者状态1成功-1失败0消费中',
+  `retry_count` int(11) DEFAULT NULL COMMENT '重试次数',
+  `cat_id` varchar(100) DEFAULT NULL COMMENT '消息编号',
+  `status` int(11) DEFAULT NULL COMMENT '状态1有效-1无效',
+  `created` datetime DEFAULT NULL COMMENT '创建时间',
+  `creator` varchar(100) DEFAULT NULL COMMENT '创建人',
+  `updated` datetime DEFAULT NULL COMMENT '修改时间',
+  `updator` varchar(100) DEFAULT NULL COMMENT '修改人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1052 DEFAULT CHARSET=utf8mb4 COMMENT='消费者消息应用状态表';
+
+-- ----------------------------
+-- Table structure for mq_producer
+-- ----------------------------
+DROP TABLE IF EXISTS `mq_producer`;
+CREATE TABLE `mq_producer` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `module_name` varchar(300) DEFAULT NULL COMMENT '模块名称',
+  `house_id` int(11) DEFAULT NULL COMMENT '项目id',
+  `producer_status` int(11) DEFAULT NULL COMMENT '生产者状态1成功-1失败',
+  `group_id` varchar(300) DEFAULT NULL COMMENT 'group的id',
+  `tag` varchar(100) DEFAULT NULL COMMENT '标签名称',
+  `cat_id` varchar(100) DEFAULT NULL COMMENT '链路编号',
+  `topic_id` varchar(300) DEFAULT NULL COMMENT 'topic的id',
+  `content` varchar(4000) DEFAULT NULL COMMENT '发送内容',
+  `result_content` varchar(1000) DEFAULT NULL COMMENT 'MQ结果参数',
+  `status` int(11) DEFAULT NULL COMMENT '状态1有效-1无效',
+  `created` datetime DEFAULT NULL COMMENT '创建时间',
+  `creator` varchar(100) DEFAULT NULL COMMENT '创建人',
+  `updated` datetime DEFAULT NULL COMMENT '修改时间',
+  `updator` varchar(100) DEFAULT NULL COMMENT '修改人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1050 DEFAULT CHARSET=utf8mb4 COMMENT='生产者消息应用状态表';
+
+
+```

+ 47 - 0
elab-mq/mq.sql

@@ -0,0 +1,47 @@
+-- ----------------------------
+-- Table structure for mq_consumer
+-- ----------------------------
+DROP TABLE IF EXISTS `mq_consumer`;
+CREATE TABLE `mq_consumer` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `producer_id` int(11) DEFAULT NULL COMMENT '生产者消息id',
+  `msg_id` varchar(100) DEFAULT NULL COMMENT 'MQ的消息编号',
+  `module_name` varchar(300) DEFAULT NULL COMMENT '模块名称',
+  `module_method` varchar(200) DEFAULT NULL COMMENT '模块的方法名,用来处理一个项目里面同一个topic和tag被多个消费处理',
+  `house_id` int(11) DEFAULT NULL COMMENT '项目id',
+  `topic_id` varchar(300) DEFAULT NULL COMMENT 'topic的id',
+  `tag` varchar(100) DEFAULT NULL COMMENT '标签名',
+  `content` varchar(4000) DEFAULT NULL COMMENT '消费内容',
+  `consumer_status` int(11) DEFAULT NULL COMMENT '消费者状态1成功-1失败0消费中',
+  `retry_count` int(11) DEFAULT NULL COMMENT '重试次数',
+  `cat_id` varchar(100) DEFAULT NULL COMMENT '消息编号',
+  `status` int(11) DEFAULT NULL COMMENT '状态1有效-1无效',
+  `created` datetime DEFAULT NULL COMMENT '创建时间',
+  `creator` varchar(100) DEFAULT NULL COMMENT '创建人',
+  `updated` datetime DEFAULT NULL COMMENT '修改时间',
+  `updator` varchar(100) DEFAULT NULL COMMENT '修改人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1052 DEFAULT CHARSET=utf8mb4 COMMENT='消费者消息应用状态表';
+
+-- ----------------------------
+-- Table structure for mq_producer
+-- ----------------------------
+DROP TABLE IF EXISTS `mq_producer`;
+CREATE TABLE `mq_producer` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `module_name` varchar(300) DEFAULT NULL COMMENT '模块名称',
+  `house_id` int(11) DEFAULT NULL COMMENT '项目id',
+  `producer_status` int(11) DEFAULT NULL COMMENT '生产者状态1成功-1失败',
+  `group_id` varchar(300) DEFAULT NULL COMMENT 'group的id',
+  `tag` varchar(100) DEFAULT NULL COMMENT '标签名称',
+  `cat_id` varchar(100) DEFAULT NULL COMMENT '链路编号',
+  `topic_id` varchar(300) DEFAULT NULL COMMENT 'topic的id',
+  `content` varchar(4000) DEFAULT NULL COMMENT '发送内容',
+  `result_content` varchar(1000) DEFAULT NULL COMMENT 'MQ结果参数',
+  `status` int(11) DEFAULT NULL COMMENT '状态1有效-1无效',
+  `created` datetime DEFAULT NULL COMMENT '创建时间',
+  `creator` varchar(100) DEFAULT NULL COMMENT '创建人',
+  `updated` datetime DEFAULT NULL COMMENT '修改时间',
+  `updator` varchar(100) DEFAULT NULL COMMENT '修改人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1050 DEFAULT CHARSET=utf8mb4 COMMENT='生产者消息应用状态表';

+ 46 - 1
elab-mq/src/main/java/com/elab/mq/listener/MessageListenerWrapper.java

@@ -4,6 +4,7 @@ import com.aliyun.openservices.ons.api.Action;
 import com.aliyun.openservices.ons.api.ConsumeContext;
 import com.aliyun.openservices.ons.api.Message;
 import com.aliyun.openservices.ons.api.MessageListener;
+import com.google.common.base.Splitter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,8 +34,11 @@ public class MessageListenerWrapper implements MessageListener {
                 for (int i = 0; i < messageListeners.size(); i++) {
                     AbstractMessageListener abstractMessageListener = messageListeners.get(i);
                     String currentTopic = message.getTopic();
+                    String currentTag = message.getTag();
                     String topic = abstractMessageListener.topic();
-                    if (topic.equals(currentTopic)) {
+                    String tag = abstractMessageListener.tag();
+                    if (topic.equals(currentTopic) && ("*".equals(tag) || isContainsTags(tag, currentTag)
+                    )) {
                         Action actionResult = abstractMessageListener.consume(message, consumeContext);
                         if (actionResult == null || Action.ReconsumeLater == actionResult) {
                             logger.warn(" MQ 消费失败 : " + abstractMessageListener);
@@ -49,4 +53,45 @@ public class MessageListenerWrapper implements MessageListener {
         }
         return result;
     }
+
+    /**
+     * 触发客户端发送的tag是多个的情况
+     *
+     * @param tags       消费者订阅的tag列表
+     * @param currentTag 当前消息携带的tag标签 可能是多个
+     * @return
+     */
+    public static boolean isContainsTags(String tags, String currentTag) {
+        // 消费者订阅的tag
+        List<String> tagList = Splitter.on("||").trimResults().omitEmptyStrings().splitToList(tags);
+        // 消息发送的过来的tag
+        List<String> currentTagList = Splitter.on("||").trimResults().omitEmptyStrings().splitToList(currentTag);
+        boolean flag = false;
+        for (int i = 0; i < currentTagList.size(); i++) {
+            String s = currentTagList.get(i);
+            if (tagList.contains(s)) {
+                flag = true;
+                break;
+            }
+        }
+        return flag;
+    }
+
+    public static void main(String[] args) {
+        String text = "LOGIN || AUTHORIZATION_MOBILE || SHARE_XCX || BAOBEI || BAOBEI_SHOUDONG || GZXM || IM_VIDEO ||" +
+                " SPKF || QIANYUE || DAOFANG || LIUDIAN || RENGOU";
+        String tag = "Test";
+        List<String> tagList = Splitter.on("||").trimResults().omitEmptyStrings().splitToList(text);
+        List<String> tags = Splitter.on("||").trimResults().omitEmptyStrings().splitToList(tag);
+
+        if (isContainsTags(text, tag)) {
+            System.out.println("yes");
+        } else {
+            System.out.println("no");
+        }
+
+        System.out.println(tagList);
+
+
+    }
 }