瀏覽代碼

有数据字典

zhouhao 6 年之前
父節點
當前提交
f5d987c51e

+ 21 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/MybatisDaoAutoConfiguration.java

@@ -21,6 +21,8 @@ package org.hswebframework.web.dao.mybatis;
 import org.hswebframework.ezorm.rdb.render.dialect.Dialect;
 import org.hswebframework.web.dao.Dao;
 import org.hswebframework.web.dao.mybatis.mapper.SqlTermCustomer;
+import org.hswebframework.web.dao.mybatis.mapper.dict.DictInTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.dict.DictTermTypeMapper;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -40,6 +42,25 @@ import java.util.Set;
 @AutoConfigureAfter(MyBatisAutoConfiguration.class)
 @EnableConfigurationProperties(MybatisProperties.class)
 public class MybatisDaoAutoConfiguration {
+    @Bean
+    public DictTermTypeMapper dictTermTypeMapper() {
+        return new DictTermTypeMapper(false);
+    }
+
+    @Bean
+    public DictTermTypeMapper dictNotTermTypeMapper() {
+        return new DictTermTypeMapper(true);
+    }
+
+    @Bean
+    public DictInTermTypeMapper dictInTermTypeMapper() {
+        return new DictInTermTypeMapper(false);
+    }
+
+    @Bean
+    public DictInTermTypeMapper dictNotInTermTypeMapper() {
+        return new DictInTermTypeMapper(true);
+    }
 
     @Bean
     public BeanPostProcessor SqlTermCustomerRegister() {

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

@@ -24,7 +24,6 @@ import org.apache.ibatis.mapping.ResultMap;
 import org.apache.ibatis.mapping.ResultMapping;
 import org.hswebframework.ezorm.core.ValueConverter;
 import org.hswebframework.ezorm.core.param.*;
-import org.hswebframework.ezorm.rdb.meta.Correlation;
 import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
 import org.hswebframework.ezorm.rdb.meta.RDBDatabaseMetaData;
 import org.hswebframework.ezorm.rdb.meta.RDBTableMetaData;
@@ -43,23 +42,17 @@ import org.hswebframework.web.BusinessException;
 import org.hswebframework.web.commons.entity.Entity;
 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;
 import org.hswebframework.web.datasource.DataSourceHolder;
 import org.hswebframework.web.datasource.DatabaseType;
-import org.hswebframework.web.proxy.Proxy;
 
 import java.sql.JDBCType;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
-import static org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper.supportArray;
 
 /**
  * 使用easyorm 动态构建 sql
@@ -103,30 +96,30 @@ 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.MYSQL.setTermTypeMapper("ain", supportArray(new MysqlEnumDicInTermTypeMapper(true, true)));
-        Dialect.MYSQL.setTermTypeMapper("anin", supportArray(new MysqlEnumDicInTermTypeMapper(false, 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.H2.setTermTypeMapper("ain", supportArray(new H2EnumDicInTermTypeMapper(true, true)));
-        Dialect.H2.setTermTypeMapper("anin", supportArray(new H2EnumDicInTermTypeMapper(false, 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)));
-        Dialect.ORACLE.setTermTypeMapper("ain", supportArray(new OracleEnumDicInTermTypeMapper(true, true)));
-        Dialect.ORACLE.setTermTypeMapper("anin", supportArray(new OracleEnumDicInTermTypeMapper(false, true)));
+//
+//        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.MYSQL.setTermTypeMapper("ain", supportArray(new MysqlEnumDicInTermTypeMapper(true, true)));
+//        Dialect.MYSQL.setTermTypeMapper("anin", supportArray(new MysqlEnumDicInTermTypeMapper(false, 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.H2.setTermTypeMapper("ain", supportArray(new H2EnumDicInTermTypeMapper(true, true)));
+//        Dialect.H2.setTermTypeMapper("anin", supportArray(new H2EnumDicInTermTypeMapper(false, 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)));
+//        Dialect.ORACLE.setTermTypeMapper("ain", supportArray(new OracleEnumDicInTermTypeMapper(true, true)));
+//        Dialect.ORACLE.setTermTypeMapper("anin", supportArray(new OracleEnumDicInTermTypeMapper(false, true)));
 
     }
 

+ 123 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/dict/DictInTermTypeMapper.java

@@ -0,0 +1,123 @@
+package org.hswebframework.web.dao.mybatis.mapper.dict;
+
+import org.hswebframework.ezorm.core.OptionConverter;
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.core.param.TermType;
+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.RenderPhase;
+import org.hswebframework.ezorm.rdb.render.dialect.function.SqlFunction;
+import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.AbstractSqlTermCustomer;
+import org.hswebframework.web.dao.mybatis.mapper.ChangedTermValue;
+import org.hswebframework.web.dict.EnumDict;
+
+import java.sql.JDBCType;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+public class DictInTermTypeMapper extends AbstractSqlTermCustomer {
+
+    private boolean not;
+
+    public static final String USE_DICT_MASK_FLAG = "dict-mask";
+
+    public DictInTermTypeMapper(boolean not) {
+        super(not ? TermType.nin : TermType.in);
+        this.not = not;
+    }
+
+    private boolean support(RDBColumnMetaData column) {
+        Class type = column.getJavaType();
+        if (type.isArray()) {
+            type = type.getComponentType();
+        }
+        return ((type.isEnum() && EnumDict.class.isAssignableFrom(type))
+                ||
+                (column.getProperty(USE_DICT_MASK_FLAG).isTrue() && column.getOptionConverter() != null));
+    }
+
+    @SuppressWarnings("all")
+    private List<EnumDict> getAllOption(RDBColumnMetaData column) {
+        Class type = column.getJavaType();
+        if (null != type) {
+            if (type.isArray()) {
+                type = type.getComponentType();
+            }
+            if (type.isEnum() && EnumDict.class.isAssignableFrom(type)) {
+                return (List) Arrays.asList(type.getEnumConstants());
+            }
+        }
+
+        OptionConverter converter = column.getOptionConverter();
+        if (converter == null) {
+            return Collections.emptyList();
+        }
+
+        return (List) converter.getOptions();
+    }
+
+    @Override
+    public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        //不支持数据字典
+        if (!support(column)) {
+            return buildNotSupport(wherePrefix, term, column, tableAlias);
+        }
+        ChangedTermValue changedValue = createChangedTermValue(term);
+
+        boolean any = term.getOptions().contains("any");
+
+        List<Object> list = BoostTermTypeMapper.convertList(column, changedValue.getOld());
+
+        EnumDict[] dicts = getAllOption(column)
+                .stream()
+                .filter(d -> d.eq(list))
+                .toArray(EnumDict[]::new);
+
+        changedValue.setValue(EnumDict.toMask(dicts));
+        Dialect dialect = column.getTableMetaData().getDatabaseMetaData().getDialect();
+
+        String columnName = dialect.buildColumnName(tableAlias, column.getName());
+        String where = "#{" + wherePrefix + ".value.value}";
+        SqlFunction sqlFunction = dialect.getFunction(SqlFunction.bitand);
+
+        if (sqlFunction == null) {
+            throw new UnsupportedOperationException("数据库不支持[BITAND]函数");
+        }
+        String bitAnd = sqlFunction.apply(SqlFunction.Param.of(RenderPhase.where, Arrays.asList(columnName, where)));
+
+        String n;
+        if (any) {
+            n = not ? "=" : "!=";
+        } else {
+            n = not ? "!=" : "=";
+        }
+        return new SqlAppender().add(bitAnd, n, any ? "0" : where);
+
+    }
+
+    protected SqlAppender buildNotSupport(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        ChangedTermValue changedValue = createChangedTermValue(term);
+        Dialect dialect = column.getTableMetaData().getDatabaseMetaData().getDialect();
+
+        List<Object> values = BoostTermTypeMapper.convertList(column, changedValue.getOld());
+
+        changedValue.setValue(values);
+
+        String columnName = dialect.buildColumnName(tableAlias, column.getName());
+        SqlAppender appender = new SqlAppender();
+        appender.add(columnName, not ? " NOT" : " ").add("IN(");
+        for (int i = 0; i < values.size(); i++) {
+            appender.add("#{", wherePrefix, ".value.value[", i, "]}", ",");
+        }
+        appender.removeLast();
+        appender.add(")");
+        return appender;
+    }
+}

+ 95 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/mapper/dict/DictTermTypeMapper.java

@@ -0,0 +1,95 @@
+package org.hswebframework.web.dao.mybatis.mapper.dict;
+
+import org.hswebframework.ezorm.core.OptionConverter;
+import org.hswebframework.ezorm.core.param.Term;
+import org.hswebframework.ezorm.core.param.TermType;
+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.RenderPhase;
+import org.hswebframework.ezorm.rdb.render.dialect.function.SqlFunction;
+import org.hswebframework.ezorm.rdb.render.dialect.term.BoostTermTypeMapper;
+import org.hswebframework.web.dao.mybatis.mapper.AbstractSqlTermCustomer;
+import org.hswebframework.web.dao.mybatis.mapper.ChangedTermValue;
+import org.hswebframework.web.dict.EnumDict;
+
+import java.sql.JDBCType;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hswebframework.web.dao.mybatis.mapper.dict.DictInTermTypeMapper.USE_DICT_MASK_FLAG;
+
+/**
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+public class DictTermTypeMapper extends AbstractSqlTermCustomer {
+
+    private boolean not;
+
+    public DictTermTypeMapper(boolean not) {
+        super(not ? TermType.not : TermType.eq);
+        this.not = not;
+    }
+
+    private boolean support(RDBColumnMetaData column) {
+        Class type = column.getJavaType();
+        if (type.isArray()) {
+            type = type.getComponentType();
+        }
+        return ((type.isEnum() && EnumDict.class.isAssignableFrom(type))
+                ||
+                (column.getProperty(USE_DICT_MASK_FLAG).isTrue() && column.getOptionConverter() != null));
+    }
+
+    @SuppressWarnings("all")
+    private List<EnumDict> getAllOption(RDBColumnMetaData column) {
+        Class type = column.getJavaType();
+        if (null != type) {
+            if (type.isArray()) {
+                type = type.getComponentType();
+            }
+            if (type.isEnum() && EnumDict.class.isAssignableFrom(type)) {
+                return (List) Arrays.asList(type.getEnumConstants());
+            }
+        }
+
+        OptionConverter converter = column.getOptionConverter();
+        if (converter == null) {
+            return Collections.emptyList();
+        }
+
+        return (List) converter.getOptions();
+    }
+
+    @Override
+    public SqlAppender accept(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        //不支持数据字典
+        if (!support(column)) {
+            return buildNotSupport(wherePrefix, term, column, tableAlias);
+        }
+        ChangedTermValue changedValue = createChangedTermValue(term);
+
+        List<Object> list = BoostTermTypeMapper.convertList(column, changedValue.getOld());
+
+        EnumDict[] dicts = getAllOption(column)
+                .stream()
+                .filter(d -> d.eq(list))
+                .toArray(EnumDict[]::new);
+
+        changedValue.setValue(EnumDict.toMask(dicts));
+        Dialect dialect = column.getTableMetaData().getDatabaseMetaData().getDialect();
+        String columnName = dialect.buildColumnName(tableAlias, column.getName());
+        return new SqlAppender().add(columnName, not ? " != " : "=", "#{", wherePrefix, ".value.value}");
+    }
+
+    protected SqlAppender buildNotSupport(String wherePrefix, Term term, RDBColumnMetaData column, String tableAlias) {
+        createChangedTermValue(term);
+        Dialect dialect = column.getTableMetaData().getDatabaseMetaData().getDialect();
+        String columnName = dialect.buildColumnName(tableAlias, column.getName());
+        SqlAppender appender = new SqlAppender();
+        appender.add(columnName, not ? " != " : "=", "#{", wherePrefix, ".value.value}");
+        return appender;
+    }
+}

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

@@ -4,6 +4,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
 import org.hswebframework.ezorm.core.param.QueryParam;
 import org.hswebframework.ezorm.rdb.executor.SqlExecutor;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.hswebframework.web.dict.EnumDict;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -66,7 +67,7 @@ public class TestCrud extends AbstractTransactionalJUnit4SpringContextTests {
 
         QueryParamEntity query = new QueryParamEntity();
         //any in
-        query.where("dataTypes", Arrays.asList(DataType.TYPE3, DataType.TYPE1));
+        query.where("dataTypes$in$any", Arrays.asList(DataType.TYPE1, DataType.TYPE3,DataType.TYPE2));
         query.includes("nest.name", "*");
         List<TestEntity> entities = testDao.queryNest(query);
 
@@ -75,4 +76,5 @@ public class TestCrud extends AbstractTransactionalJUnit4SpringContextTests {
         System.out.println(entities);
     }
 
+
 }

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

@@ -189,8 +189,8 @@ public interface EnumDict<V> extends JSONSerializable {
         return arr;
     }
 
-    static <T extends EnumDict> List<T> getByMask(Supplier<List<T>> allOptionsSuppiler, long mask) {
-        return getByMask(allOptionsSuppiler.get(), mask);
+    static <T extends EnumDict> List<T> getByMask(Supplier<List<T>> allOptionsSupplier, long mask) {
+        return getByMask(allOptionsSupplier.get(), mask);
     }
 
 

+ 5 - 1
hsweb-system/hsweb-system-dynamic-form/hsweb-system-dynamic-form-api/src/main/java/org/hswebframework/web/entity/form/DictConfig.java

@@ -2,10 +2,12 @@ package org.hswebframework.web.entity.form;
 
 import lombok.Getter;
 import lombok.Setter;
+import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
 import org.hswebframework.web.commons.bean.Bean;
 import org.hswebframework.web.commons.entity.Entity;
 
 import java.io.Serializable;
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -22,6 +24,8 @@ public class DictConfig implements Bean {
 
     private String toField;
 
-    private Map<String,Object> config;
+    private Map<String, Object> config=new HashMap<>();
+
+    private RDBColumnMetaData column;
 
 }