Просмотр исходного кода

新增orm中对枚举字典的支持

zhou-hao 7 лет назад
Родитель
Сommit
b84a81b24e
18 измененных файлов с 540 добавлено и 22 удалено
  1. 32 2
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/pom.xml
  2. 1 1
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/EnumDictHandlerRegister.java
  3. 31 8
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java
  4. 9 1
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/jpa/JpaAnnotationParser.java
  5. 94 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/EnumDicInTermTypeMapper.java
  6. 81 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/EnumDicTermTypeMapper.java
  7. 22 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/h2/H2EnumDicInTermTypeMapper.java
  8. 24 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/mysql/MysqlEnumDicInTermTypeMapper.java
  9. 23 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/oracle/OracleEnumDicInTermTypeMapper.java
  10. 17 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/DataType.java
  11. 12 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestApplication.java
  12. 62 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestCrud.java
  13. 6 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestDao.java
  14. 46 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestEntity.java
  15. 25 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/resources/application.yml
  16. 35 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/resources/org/hswebframework/web/dao/test/TestDao.xml
  17. 17 8
      hsweb-core/src/main/java/org/hswebframework/web/dict/EnumDict.java
  18. 3 2
      hsweb-core/src/test/java/org/hswebframework/web/dict/DictDefineTest.java

+ 32 - 2
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/pom.xml

@@ -52,10 +52,40 @@
         </dependency>
         <dependency>
             <groupId>org.hibernate.javax.persistence</groupId>
-            <artifactId>hibernate-jpa-2.0-api</artifactId>
-            <version>1.0.1.Final</version>
+            <artifactId>hibernate-jpa-2.1-api</artifactId>
+            <version>1.0.0.Final</version>
             <optional>true</optional>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.0.26</version>
+            <scope>test</scope>
+        </dependency>
+        <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-starter-data-jpa</artifactId>-->
+            <!--<scope>test</scope>-->
+        <!--</dependency>-->
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.el</groupId>
+            <artifactId>el-api</artifactId>
+            <version>2.2</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>

+ 1 - 1
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/EnumDictHandlerRegister.java

@@ -89,7 +89,7 @@ public class EnumDictHandlerRegister {
         @Override
         public void setParameter(PreparedStatement ps, int i, Object[] parameter, JdbcType jdbcType) throws SQLException {
             T[] ts = ((T[]) parameter);
-            ps.setLong(i, EnumDict.toBit(type, ts));
+            ps.setLong(i, EnumDict.toBit(ts));
         }
 
         @Override

+ 31 - 8
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/EasyOrmSqlBuilder.java

@@ -23,10 +23,7 @@ import org.apache.commons.beanutils.PropertyUtilsBean;
 import org.apache.ibatis.mapping.ResultMap;
 import org.apache.ibatis.mapping.ResultMapping;
 import org.hswebframework.ezorm.core.ValueConverter;
-import org.hswebframework.ezorm.core.param.InsertParam;
-import org.hswebframework.ezorm.core.param.QueryParam;
-import org.hswebframework.ezorm.core.param.Term;
-import org.hswebframework.ezorm.core.param.UpdateParam;
+import org.hswebframework.ezorm.core.param.*;
 import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
 import org.hswebframework.ezorm.rdb.meta.RDBDatabaseMetaData;
 import org.hswebframework.ezorm.rdb.meta.RDBTableMetaData;
@@ -39,11 +36,16 @@ import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
 import org.hswebframework.ezorm.rdb.render.dialect.H2RDBDatabaseMetaData;
 import org.hswebframework.ezorm.rdb.render.dialect.MysqlRDBDatabaseMetaData;
 import org.hswebframework.ezorm.rdb.render.dialect.OracleRDBDatabaseMetaData;
+import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
 import org.hswebframework.ezorm.rdb.render.support.simple.CommonSqlRender;
 import org.hswebframework.ezorm.rdb.render.support.simple.SimpleWhereSqlBuilder;
 import org.hswebframework.web.BusinessException;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
 import org.hswebframework.web.dao.mybatis.builder.jpa.JpaAnnotationParser;
+import org.hswebframework.web.dao.mybatis.mapper.EnumDicTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.h2.H2EnumDicInTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.mysql.MysqlEnumDicInTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.oracle.OracleEnumDicInTermTypeMapper;
 import org.hswebframework.web.dao.mybatis.plgins.pager.Pager;
 import org.hswebframework.web.dao.mybatis.MybatisUtils;
 import org.hswebframework.utils.StringUtils;
@@ -55,6 +57,9 @@ import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import static org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper.notSupportArray;
+import static org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper.supportArray;
+
 /**
  * 使用easyorm 动态构建 sql
  *
@@ -67,7 +72,7 @@ public class EasyOrmSqlBuilder {
 
     public EntityFactory entityFactory;
 
-    private static final   EasyOrmSqlBuilder  instance   = new EasyOrmSqlBuilder();
+    private static final EasyOrmSqlBuilder instance = new EasyOrmSqlBuilder();
     protected static final Map<Class, String> simpleName = new HashMap<>();
 
     protected PropertyUtilsBean propertyUtils = BeanUtilsBean.getInstance().getPropertyUtils();
@@ -97,6 +102,24 @@ public class EasyOrmSqlBuilder {
         simpleName.put(short.class, "short");
         simpleName.put(char.class, "char");
         simpleName.put(byte.class, "byte");
+
+        Dialect.MYSQL.setTermTypeMapper(TermType.eq, supportArray(new EnumDicTermTypeMapper(Dialect.MYSQL, false)));
+        Dialect.MYSQL.setTermTypeMapper(TermType.in, supportArray(new MysqlEnumDicInTermTypeMapper(false)));
+        Dialect.MYSQL.setTermTypeMapper(TermType.not, supportArray(new EnumDicTermTypeMapper(Dialect.MYSQL, true)));
+        Dialect.MYSQL.setTermTypeMapper(TermType.nin, supportArray(new MysqlEnumDicInTermTypeMapper(true)));
+
+
+        Dialect.H2.setTermTypeMapper(TermType.eq, supportArray(new EnumDicTermTypeMapper(Dialect.H2, false)));
+        Dialect.H2.setTermTypeMapper(TermType.in, supportArray(new H2EnumDicInTermTypeMapper(false)));
+        Dialect.H2.setTermTypeMapper(TermType.not, supportArray(new EnumDicTermTypeMapper(Dialect.H2, true)));
+        Dialect.H2.setTermTypeMapper(TermType.nin, supportArray(new H2EnumDicInTermTypeMapper(true)));
+
+
+        Dialect.ORACLE.setTermTypeMapper(TermType.eq, supportArray(new EnumDicTermTypeMapper(Dialect.ORACLE, false)));
+        Dialect.ORACLE.setTermTypeMapper(TermType.in, supportArray(new OracleEnumDicInTermTypeMapper(false)));
+        Dialect.ORACLE.setTermTypeMapper(TermType.not, supportArray(new EnumDicTermTypeMapper(Dialect.ORACLE, true)));
+        Dialect.ORACLE.setTermTypeMapper(TermType.nin, supportArray(new OracleEnumDicInTermTypeMapper(true)));
+
     }
 
     public static String getJavaType(Class type) {
@@ -107,9 +130,9 @@ public class EasyOrmSqlBuilder {
         return javaType;
     }
 
-    private final RDBDatabaseMetaData mysql  = new MysqlMeta();
+    private final RDBDatabaseMetaData mysql = new MysqlMeta();
     private final RDBDatabaseMetaData oracle = new OracleMeta();
-    private final RDBDatabaseMetaData h2     = new H2Meta();
+    private final RDBDatabaseMetaData h2 = new H2Meta();
 
     private final ConcurrentMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>> metaCache = new ConcurrentHashMap<RDBDatabaseMetaData, Map<String, RDBTableMetaData>>() {
         @Override
@@ -190,7 +213,7 @@ public class EasyOrmSqlBuilder {
         });
         cache.put(cacheKey, rdbTableMetaData);
         if (useJpa) {
-            Class type = entityFactory.getInstanceType(resultMaps.getType());
+            Class type = entityFactory == null ? resultMaps.getType() : entityFactory.getInstanceType(resultMaps.getType());
             RDBTableMetaData parseResult = JpaAnnotationParser.parseMetaDataFromEntity(type);
             if (parseResult != null) {
                 for (RDBColumnMetaData columnMetaData : parseResult.getColumns()) {

+ 9 - 1
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/jpa/JpaAnnotationParser.java

@@ -73,9 +73,17 @@ public class JpaAnnotationParser {
         });
 
         jdbcTypeConvert.add((type, property) -> {
+            boolean isArray = type.isArray();
+            if (isArray) {
+                type = type.getComponentType();
+
+            }
             if (type.isEnum() && EnumDict.class.isAssignableFrom(type)) {
                 Class genType = ClassUtils.getGenericType(type);
-                return jdbcTypeMapping.getOrDefault(genType, JDBCType.OTHER);
+                if (isArray) {
+                    return JDBCType.BIGINT;
+                }
+                return jdbcTypeMapping.getOrDefault(genType, JDBCType.VARCHAR);
             }
             return null;
         });

+ 94 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/EnumDicInTermTypeMapper.java

@@ -0,0 +1,94 @@
+package org.hswebframework.web.dao.mybatis.mapper;
+
+import lombok.AllArgsConstructor;
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hswebframework.ezorm.rdb.render.Sql;
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
+import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
+import org.hswebframework.ezorm.rdb.render.dialect.Dialect.TermTypeMapper;
+import org.hswebframework.web.dict.EnumDict;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@AllArgsConstructor
+@SuppressWarnings("all")
+public class EnumDicInTermTypeMapper implements TermTypeMapper {
+
+    protected Dialect dialect;
+
+    protected boolean not;
+
+    protected boolean support(RDBColumnMetaData column) {
+        Class type = column.getJavaType();
+        if (type.isArray()) {
+            type = type.getComponentType();
+        }
+        return type.isEnum() && EnumDict.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        Class type = column.getJavaType();
+        Object value = term.getValue();
+        if (type.isArray()) {
+            Class componentType = type.getComponentType();
+            if (support(column)) {
+                EnumDict[] newValue = param2list(value)
+                        .stream().map(v -> EnumDict.find(componentType, v).orElse(null))
+                        .filter(Objects::nonNull)
+                        .toArray(EnumDict[]::new);
+                long bit = EnumDict.toBit(newValue);
+                term.setValue(bit);
+            } else {
+                return buildNotSupport(wherePrefix, term, column, tableAlias);
+
+            }
+        } else {
+//            if (support(column)) {
+//                if (value instanceof Collection) {
+//                    value = ((Collection) value).iterator().next();
+//                }
+//                EnumDict dict = value instanceof EnumDict ? (EnumDict) value : (EnumDict) EnumDict.find(type, value).orElse(null);
+//                if (null != dict) {
+//                    term.setValue(dict.getValue());
+//                }
+//            } else {
+            return buildNotSupport(wherePrefix, term, column, tableAlias);
+//            }
+        }
+        return build(wherePrefix, term, column, tableAlias);
+    }
+
+    protected SqlAppender buildNotSupport(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        List<Object> values = param2list(term.getValue());
+        term.setValue(values);
+        SqlAppender appender = new SqlAppender();
+        appender.add(dialect.buildColumnName(tableAlias, column.getAlias()), not ? " NOT" : " ").add("IN(");
+        for (int i = 0; i < values.size(); i++) {
+            appender.add("#{", wherePrefix, ".value[", i, "]}", ",");
+        }
+        appender.removeLast();
+        appender.add(")");
+        return appender;
+    }
+
+    protected SqlAppender build(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        return new SqlAppender()
+                .add(dialect.buildColumnName(tableAlias, column.getName()), not ? "!=" : "=", "#{", wherePrefix, ".value}");
+    }
+
+
+    protected List<Object> param2list(Object value) {
+        if (value == null) return new ArrayList<>();
+        if (value instanceof List) return (List) value;
+        if (value instanceof Collection) return new ArrayList<>(((Collection) value));
+        if (value.getClass().isArray()) {
+            return new ArrayList<>(Arrays.asList(((Object[]) value)));
+        } else {
+            return new ArrayList<>(Collections.singletonList(value));
+        }
+    }
+
+}

+ 81 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/EnumDicTermTypeMapper.java

@@ -0,0 +1,81 @@
+package org.hswebframework.web.dao.mybatis.mapper;
+
+import lombok.AllArgsConstructor;
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
+import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
+import org.hswebframework.ezorm.rdb.render.dialect.Dialect.TermTypeMapper;
+import org.hswebframework.web.dict.EnumDict;
+
+import java.util.*;
+
+@AllArgsConstructor
+@SuppressWarnings("all")
+public class EnumDicTermTypeMapper implements TermTypeMapper {
+
+    protected Dialect dialect;
+
+    protected boolean not;
+
+
+    protected boolean support(RDBColumnMetaData column) {
+        Class type = column.getJavaType();
+        if (type.isArray()) {
+            type = type.getComponentType();
+        }
+        return type.isEnum() && EnumDict.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        Class type = column.getJavaType();
+        Object value = term.getValue();
+        if (type.isArray()) {
+            Class componentType = type.getComponentType();
+            if (support(column)) {
+                EnumDict[] newValue = param2list(value)
+                        .stream().map(v -> EnumDict.find(componentType, v).orElse(null))
+                        .filter(Objects::nonNull)
+                        .toArray(EnumDict[]::new);
+                long bit = EnumDict.toBit(newValue);
+                term.setValue(bit);
+            }
+        } else {
+            if (support(column)) {
+                if (value instanceof Collection) {
+                    value = ((Collection) value).iterator().next();
+                }
+                EnumDict dict = (EnumDict) EnumDict.find(type, value).orElse(null);
+                if (null != dict) {
+                    term.setValue(dict.getValue());
+                }
+            }
+        }
+        return build(wherePrefix, term, column, tableAlias);
+    }
+
+
+    protected SqlAppender build(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        Object value = term.getValue();
+        if (value instanceof Collection) {
+            value = ((Collection) value).iterator().next();
+            term.setValue(value);
+        }
+        return new SqlAppender()
+                .add(dialect.buildColumnName(tableAlias, column.getName()), not ? "!=" : "=", "#{", wherePrefix, ".value}");
+    }
+
+
+    protected List<Object> param2list(Object value) {
+        if (value == null) return new ArrayList<>();
+        if (value instanceof List) return (List) value;
+        if (value instanceof Collection) return new ArrayList<>(((Collection) value));
+        if (value.getClass().isArray()) {
+            return new ArrayList<>(Arrays.asList(((Object[]) value)));
+        } else {
+            return new ArrayList<>(Collections.singletonList(value));
+        }
+    }
+
+}

+ 22 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/h2/H2EnumDicInTermTypeMapper.java

@@ -0,0 +1,22 @@
+package org.hswebframework.web.dao.mybatis.mapper.h2;
+
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
+import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
+import org.hswebframework.web.dao.mybatis.mapper.EnumDicInTermTypeMapper;
+
+public class H2EnumDicInTermTypeMapper extends EnumDicInTermTypeMapper {
+
+    public H2EnumDicInTermTypeMapper(boolean not) {
+        super(Dialect.H2, not);
+    }
+
+    @Override
+    protected SqlAppender build(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        String columnName = dialect.buildColumnName(tableAlias, column.getName());
+        String where = "#{" + wherePrefix + ".value}";
+        return new SqlAppender()
+                .add("BITAND(", columnName, ",", where, ")", not ? "!=" : "=", where);
+    }
+}

+ 24 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/mysql/MysqlEnumDicInTermTypeMapper.java

@@ -0,0 +1,24 @@
+package org.hswebframework.web.dao.mybatis.mapper.mysql;
+
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
+import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
+import org.hswebframework.web.dao.mybatis.mapper.EnumDicInTermTypeMapper;
+
+public class MysqlEnumDicInTermTypeMapper extends EnumDicInTermTypeMapper {
+
+    public MysqlEnumDicInTermTypeMapper(boolean not) {
+        super(Dialect.MYSQL, not);
+    }
+
+    @Override
+    protected SqlAppender build(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        String columnName = dialect.buildColumnName(tableAlias, column.getName());
+        String where = "#{" + wherePrefix + ".value}";
+        return new SqlAppender()
+                .add(columnName, " & ", where, not ? " != " : " = ", where);
+    }
+
+
+}

+ 23 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/oracle/OracleEnumDicInTermTypeMapper.java

@@ -0,0 +1,23 @@
+package org.hswebframework.web.dao.mybatis.mapper.oracle;
+
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
+import org.hswebframework.ezorm.rdb.render.SqlAppender;
+import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
+import org.hswebframework.web.dao.mybatis.mapper.EnumDicInTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.EnumDicTermTypeMapper;
+
+public class OracleEnumDicInTermTypeMapper extends EnumDicInTermTypeMapper {
+
+    public OracleEnumDicInTermTypeMapper(boolean not) {
+        super(Dialect.ORACLE, not);
+    }
+
+    @Override
+    protected SqlAppender build(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        String columnName = dialect.buildColumnName(tableAlias, column.getName());
+        String where = "#{" + wherePrefix + ".value}";
+        return new SqlAppender()
+                .add("BITAND(", columnName, ",", where, ")", not ? "!=" : "=", where);
+    }
+}

+ 17 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/DataType.java

@@ -0,0 +1,17 @@
+package org.hswebframework.web.dao.crud;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.hswebframework.web.dict.EnumDict;
+
+@Getter
+@AllArgsConstructor
+public enum DataType implements EnumDict<Byte> {
+    TYPE1((byte) 1, "类型1"),
+    TYPE2((byte) 2, "类型2"),
+    TYPE3((byte) 3, "类型3");
+
+    private Byte value;
+
+    private String text;
+}

+ 12 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestApplication.java

@@ -0,0 +1,12 @@
+package org.hswebframework.web.dao.crud;
+
+import org.hswebframework.web.dao.Dao;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+//@EntityScan("org.hswebframework.web.dao")
+public class TestApplication {
+}

+ 62 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestCrud.java

@@ -0,0 +1,62 @@
+package org.hswebframework.web.dao.crud;
+
+import org.hswebframework.ezorm.core.param.QueryParam;
+import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
+import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = TestApplication.class)
+public class TestCrud extends AbstractTransactionalJUnit4SpringContextTests {
+
+    @Autowired
+    private TestDao testDao;
+
+    @Autowired
+    private SqlExecutor sqlExecutor;
+
+
+    @Before
+    public void init() throws SQLException {
+        sqlExecutor.exec("\n" +
+                "create table h_test(\n" +
+                "  id BIGINT AUTO_INCREMENT PRIMARY KEY,\n" +
+                "  name VARCHAR(32) ,\n" +
+                "  create_time DATETIME,\n" +
+                "  data_type SMALLINT,\n" +
+                "  data_types BIGINT\n" +
+                ")");
+    }
+
+    @Test
+    public void testInsert() {
+
+        TestEntity entity = new TestEntity();
+        entity.setName("测试");
+        entity.setDataType(DataType.TYPE1);
+        entity.setDataTypes(new DataType[]{DataType.TYPE1, DataType.TYPE3});
+        testDao.insert(entity);
+        Assert.assertNotNull(entity.getId());
+
+        QueryParamEntity query = new QueryParamEntity();
+
+        query.where("dataTypes", "in",Arrays.asList(DataType.TYPE3, DataType.TYPE3))
+        .or("name","123").or("name" ,"in","123");
+
+        List<TestEntity> entities = testDao.query(query);
+
+        System.out.println(entities);
+    }
+
+}

+ 6 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestDao.java

@@ -0,0 +1,6 @@
+package org.hswebframework.web.dao.crud;
+
+import org.hswebframework.web.dao.CrudDao;
+
+public interface TestDao extends CrudDao<TestEntity, Long> {
+}

+ 46 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/crud/TestEntity.java

@@ -0,0 +1,46 @@
+package org.hswebframework.web.dao.crud;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "h_test")
+@Getter
+@Setter
+@ToString
+public class TestEntity {
+
+    @Id
+    @GeneratedValue(
+            strategy = GenerationType.IDENTITY
+    )
+    private Long id;
+
+    @Column(
+            name = "name",
+            columnDefinition = "varchar COMMENT '创建时间'"
+    )
+    private String name;
+
+    @Column(
+            name = "create_time",
+            columnDefinition = "timestamp COMMENT '创建时间'"
+    )
+    private Date createTime;
+
+    @Column(
+            name = "data_type",
+            columnDefinition = "bigint COMMENT '类型'"
+    )
+    private DataType dataType;
+
+    @Column(
+            name = "data_types",
+            columnDefinition = "bigint COMMENT '多个类型'"
+    )
+    private DataType[] dataTypes;
+}

+ 25 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/resources/application.yml

@@ -0,0 +1,25 @@
+logging:
+  level:
+    org.hswebframework: DEBUG
+    org.hswebframework.expands: ERROR
+    com.ruiqi: DEBUG
+    access-logger: INFO
+    com.netflix: ERROR
+spring:
+    aop:
+        auto: true
+        proxy-target-class: true
+    profiles:
+      active: dev
+    datasource:
+      url: jdbc:h2:mem:test
+      username : sa
+      password :
+      type: com.alibaba.druid.pool.DruidDataSource
+    jpa:
+      generate-ddl: true
+      show-sql: true
+      hibernate:
+        ddl-auto: update
+mybatis:
+  mapper-locations: org/hswebframework/web/dao/test/*.xml

+ 35 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/resources/org/hswebframework/web/dao/test/TestDao.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="org.hswebframework.web.dao.crud.TestDao">
+
+    <resultMap id="TestResultMap" type="org.hswebframework.web.dao.crud.TestEntity">
+        <id property="id" column="id" javaType="Long" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <!--用于动态生成sql所需的配置-->
+    <sql id="config">
+        <bind name="resultMapId" value="'TestResultMap'"/>
+        <bind name="tableName" value="'h_test'"/>
+    </sql>
+
+    <insert id="insert" keyColumn="id" keyProperty="id" useGeneratedKeys="true" parameterType="org.hswebframework.web.dao.crud.TestEntity">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildInsertSql"/>
+    </insert>
+
+    <update id="update" parameterType="org.hswebframework.web.commons.entity.Entity">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildUpdateSql"/>
+    </update>
+
+    <select id="query" parameterType="org.hswebframework.web.commons.entity.Entity" resultMap="TestResultMap">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildSelectSql"/>
+    </select>
+
+    <select id="count" parameterType="org.hswebframework.web.commons.entity.Entity" resultType="int">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildTotalSql"/>
+    </select>
+
+</mapper>

+ 17 - 8
hsweb-core/src/main/java/org/hswebframework/web/dict/EnumDict.java

@@ -47,8 +47,10 @@ public interface EnumDict<V> {
      * @return 是否相等
      */
     default boolean eq(Object v) {
-        return getValue() == v
+        return this == v
+                || getValue() == v
                 || getValue().equals(v)
+                || v.equals(getBit())
                 || String.valueOf(getValue()).equalsIgnoreCase(String.valueOf(v))
                 || getText().equalsIgnoreCase(String.valueOf(v));
     }
@@ -74,7 +76,7 @@ public interface EnumDict<V> {
      * @param <T>       枚举类型
      * @return 查找到的结果
      */
-    static <T extends Enum & EnumDict> Optional<T> find(Class<T> type, Predicate<T> predicate) {
+    static <T extends EnumDict> Optional<T> find(Class<T> type, Predicate<T> predicate) {
         if (type.isEnum()) {
             for (T enumDict : type.getEnumConstants()) {
                 if (predicate.test(enumDict)) {
@@ -90,7 +92,7 @@ public interface EnumDict<V> {
      *
      * @see this#find(Class, Predicate)
      */
-    static <T extends Enum & EnumDict<?>> Optional<T> findByValue(Class<T> type, Object value) {
+    static <T extends EnumDict<?>> Optional<T> findByValue(Class<T> type, Object value) {
         return find(type, e -> e.getValue() == value || e.getValue().equals(value) || String.valueOf(e.getValue()).equalsIgnoreCase(String.valueOf(value)));
     }
 
@@ -99,7 +101,7 @@ public interface EnumDict<V> {
      *
      * @see this#find(Class, Predicate)
      */
-    static <T extends Enum & EnumDict> Optional<T> findByText(Class<T> type, String text) {
+    static <T extends EnumDict> Optional<T> findByText(Class<T> type, String text) {
         return find(type, e -> e.getText().equalsIgnoreCase(text));
     }
 
@@ -108,11 +110,12 @@ public interface EnumDict<V> {
      *
      * @see this#find(Class, Predicate)
      */
-    static <T extends Enum & EnumDict> Optional<T> find(Class<T> type, Object target) {
+    static <T extends EnumDict> Optional<T> find(Class<T> type, Object target) {
         return find(type, v -> v.eq(target));
     }
 
-    static <T extends Enum & EnumDict> long toBit(Class<T> type, T... t) {
+    @SafeVarargs
+    static <T extends EnumDict> long toBit(T... t) {
         long value = 0;
         for (T t1 : t) {
             value |= t1.getBit();
@@ -120,10 +123,16 @@ public interface EnumDict<V> {
         return value;
     }
 
-    static <T extends Enum & EnumDict> List<T> getByBit(Class<T> tClass, long mask) {
+    @SafeVarargs
+    static <T extends EnumDict> boolean bitIn(long bit, T... t) {
+        long value = toBit(t);
+        return (bit & value) == value;
+    }
+
+    static <T extends EnumDict> List<T> getByBit(Class<T> tClass, long bit) {
         List<T> arr = new ArrayList<>();
         for (T t : tClass.getEnumConstants()) {
-            if (t.in(mask)) {
+            if (t.in(bit)) {
                 arr.add(t);
             }
         }

+ 3 - 2
hsweb-core/src/test/java/org/hswebframework/web/dict/DictDefineTest.java

@@ -31,9 +31,9 @@ public class DictDefineTest {
 
         Assert.assertEquals(UserCode.SIMPLE, find(UserCode.class, UserCode.SIMPLE.getText()).orElse(null));
 
-        long bit = toBit(UserCode.class, UserCode.values());
+        long bit = toBit( UserCode.values());
 
-        System.out.println(bit);
+        System.out.println(bitIn(bit,UserCode.SIMPLE,UserCode.TEST,UserCode.SIMPLE));
 
         for (UserCode userCode : UserCode.values()) {
             Assert.assertTrue(userCode.in(bit));
@@ -41,6 +41,7 @@ public class DictDefineTest {
 
         List<UserCode> codes = getByBit(UserCode.class, bit);
 
+
     }
 
     @Test