浏览代码

优化枚举字典

zhou-hao 7 年之前
父节点
当前提交
ba9597a812
共有 15 个文件被更改,包括 213 次插入36 次删除
  1. 104 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/EnumDictHandlerRegister.java
  2. 7 1
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/MyBatisAutoConfiguration.java
  3. 15 1
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/main/java/org/hswebframework/web/dao/mybatis/builder/jpa/JpaAnnotationParser.java
  4. 1 1
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/mybatis/builder/jpa/JpaAnnotationParserTest.java
  5. 4 0
      hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/mybatis/builder/jpa/TestEntity.java
  6. 3 4
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/DataStatus.java
  7. 18 0
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/DataStatusEnum.java
  8. 16 2
      hsweb-core/src/main/java/org/hswebframework/web/dict/EnumDict.java
  9. 19 0
      hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/TrueOrFalse.java
  10. 1 1
      hsweb-core/src/main/java/org/hswebframework/web/validate/ValidateResults.java
  11. 1 0
      hsweb-core/src/main/java/org/hswebframework/web/validate/ValidationException.java
  12. 4 2
      hsweb-core/src/test/java/org/hswebframework/web/bean/FastBeanCopierTest.java
  13. 0 1
      hsweb-core/src/test/java/org/hswebframework/web/dict/DictDefineTest.java
  14. 0 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/AuthorizationSettingMenuService.java
  15. 20 22
      hsweb-system/hsweb-system-schedule/hsweb-system-schedule-service/hsweb-system-schedule-service-simple/src/main/java/org/hswebframework/web/service/schedule/simple/SimpleScheduleJobService.java

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

@@ -0,0 +1,104 @@
+package org.hswebframework.web.dao.mybatis;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.TypeHandler;
+import org.apache.ibatis.type.TypeHandlerRegistry;
+import org.hswebframework.web.dict.EnumDict;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.util.ClassUtils;
+
+import java.io.IOException;
+import java.sql.*;
+
+import static org.springframework.util.StringUtils.tokenizeToStringArray;
+
+@Slf4j
+public class EnumDictHandlerRegister {
+
+    static TypeHandlerRegistry typeHandlerRegistry;
+
+    private static MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
+
+    private static ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
+
+
+    public static void register(String packages) {
+        register(tokenizeToStringArray(packages,
+                ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
+    }
+
+    public static void register(String[] packages) {
+        if (typeHandlerRegistry == null) {
+            log.error("请在spring容器初始化后再调用此方法!");
+            return;
+        }
+        for (String basePackage : packages) {
+            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
+                    ClassUtils.convertClassNameToResourcePath(basePackage) + "/**/*.class";
+            try {
+                Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
+                for (Resource resource : resources) {
+                    try {
+                        MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);
+                        Class enumType = Class.forName(reader.getClassMetadata().getClassName());
+                        if (enumType.isEnum() && EnumDict.class.isAssignableFrom(enumType)) {
+                            log.debug("register typeHandler for enum dict:{}", enumType);
+                            typeHandlerRegistry.register(enumType, new EnumDictHandler(enumType));
+                        }
+                    } catch (Exception ignore) {
+
+                    }
+                }
+            } catch (IOException e) {
+                log.warn("register enum dict error", e);
+            }
+        }
+    }
+
+    @Getter
+    @Setter
+    @AllArgsConstructor
+    @MappedJdbcTypes({JdbcType.VARCHAR, JdbcType.BIT,
+            JdbcType.BOOLEAN, JdbcType.NUMERIC,
+            JdbcType.TINYINT, JdbcType.INTEGER,
+            JdbcType.BIGINT, JdbcType.DECIMAL,
+            JdbcType.CHAR})
+    static class EnumDictHandler<T extends Enum & EnumDict> implements TypeHandler<T> {
+
+        private Class<T> type;
+
+        @Override
+        public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
+            ps.setObject(i, parameter.getValue());
+        }
+
+        @Override
+        public T getResult(ResultSet rs, String columnName) throws SQLException {
+            Object val = rs.getObject(columnName);
+            return EnumDict.findByValue(getType(), val).orElse(null);
+        }
+
+        @Override
+        public T getResult(ResultSet rs, int columnIndex) throws SQLException {
+            Object val = rs.getObject(columnIndex);
+            return EnumDict.findByValue(getType(), val).orElse(null);
+        }
+
+        @Override
+        public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
+            Object val = cs.getObject(columnIndex);
+            return EnumDict.findByValue(getType(), val).orElse(null);
+        }
+    }
+}

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

@@ -74,7 +74,6 @@ public class MyBatisAutoConfiguration {
     public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
         SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
         MybatisProperties mybatisProperties = this.mybatisProperties();
-
         if (null != entityFactory) {
             factory.setObjectFactory(new MybatisEntityFactory(entityFactory));
         }
@@ -109,7 +108,11 @@ public class MyBatisAutoConfiguration {
         }
         factory.setTypeHandlersPackage(typeHandlers);
         factory.setMapperLocations(mybatisProperties.resolveMapperLocations());
+
         SqlSessionFactory sqlSessionFactory = factory.getObject();
+        EnumDictHandlerRegister.typeHandlerRegistry = sqlSessionFactory.getConfiguration().getTypeHandlerRegistry();
+        EnumDictHandlerRegister.register("org.hswebframework.web;" + mybatisProperties.getTypeHandlersPackage());
+
         ResultMapsUtils.setSqlSession(sqlSessionFactory);
         try {
             Class.forName("javax.persistence.Table");
@@ -117,6 +120,9 @@ public class MyBatisAutoConfiguration {
         } catch (@SuppressWarnings("all") Exception ignore) {
         }
         EasyOrmSqlBuilder.getInstance().entityFactory = entityFactory;
+
+        sqlSessionFactory.getConfiguration().getTypeAliasRegistry();
+
         return sqlSessionFactory;
     }
 

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

@@ -7,6 +7,8 @@ import org.hswebframework.ezorm.rdb.meta.RDBColumnMetaData;
 import org.hswebframework.ezorm.rdb.meta.RDBTableMetaData;
 import org.hswebframework.ezorm.rdb.meta.converter.DateTimeConverter;
 import org.hswebframework.ezorm.rdb.meta.converter.NumberValueConverter;
+import org.hswebframework.utils.ClassUtils;
+import org.hswebframework.web.dict.EnumDict;
 import org.springframework.core.annotation.AnnotationUtils;
 
 import javax.persistence.Column;
@@ -59,6 +61,8 @@ public class JpaAnnotationParser {
         jdbcTypeMapping.put(java.sql.Date.class, JDBCType.TIMESTAMP);
         jdbcTypeMapping.put(java.sql.Timestamp.class, JDBCType.TIMESTAMP);
 
+        jdbcTypeMapping.put(Object.class, JDBCType.VARCHAR);
+
         jdbcTypeConvert.add((type, property) -> {
             Enumerated enumerated = getAnnotation(type, property, Enumerated.class);
             return enumerated != null ? JDBCType.VARCHAR : null;
@@ -67,6 +71,14 @@ public class JpaAnnotationParser {
             Lob enumerated = getAnnotation(type, property, Lob.class);
             return enumerated != null ? JDBCType.CLOB : null;
         });
+
+        jdbcTypeConvert.add((type, property) -> {
+            if (type.isEnum() && EnumDict.class.isAssignableFrom(type)) {
+                Class genType = ClassUtils.getGenericType(type);
+                return jdbcTypeMapping.getOrDefault(genType, JDBCType.OTHER);
+            }
+            return null;
+        });
     }
 
     public static RDBTableMetaData parseMetaDataFromEntity(Class entityClass) {
@@ -92,7 +104,9 @@ public class JpaAnnotationParser {
             columnMetaData.setPrecision(column.precision());
             columnMetaData.setJavaType(descriptor.getPropertyType());
 
-            JDBCType type = jdbcTypeMapping.get(descriptor.getPropertyType());
+            Class propertyType = descriptor.getPropertyType();
+
+            JDBCType type = jdbcTypeMapping.get(propertyType);
             if (type == null) {
                 type = jdbcTypeConvert.stream()
                         .map(func -> func.apply(entityClass, descriptor))

+ 1 - 1
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/mybatis/builder/jpa/JpaAnnotationParserTest.java

@@ -20,6 +20,6 @@ public class JpaAnnotationParserTest {
         RDBTableMetaData metaData = JpaAnnotationParser.parseMetaDataFromEntity(TestEntity.class);
 
         Assert.assertNotNull(metaData);
-        Assert.assertEquals(metaData.getColumns().size(), 4);
+        Assert.assertEquals(metaData.getColumns().size(), 5);
     }
 }

+ 4 - 0
hsweb-commons/hsweb-commons-dao/hsweb-commons-dao-mybatis/src/test/java/org/hswebframework/web/dao/mybatis/builder/jpa/TestEntity.java

@@ -1,6 +1,7 @@
 package org.hswebframework.web.dao.mybatis.builder.jpa;
 
 import lombok.Data;
+import org.hswebframework.web.dict.defaults.TrueOrFalse;
 
 import javax.persistence.Column;
 import javax.persistence.Table;
@@ -22,4 +23,7 @@ public class TestEntity extends AbstractEntity {
     @Column(name = "role_id")
     private String roleId;
 
+    @Column(name = "enabled")
+    private TrueOrFalse enabled;
+
 }

+ 3 - 4
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/DataStatus.java

@@ -1,12 +1,11 @@
 package org.hswebframework.web.commons.entity;
 
 /**
- * TODO 完成注释
- *
  * @author zhouhao
+ * @see DataStatusEnum
  */
 public interface DataStatus {
-    Byte STATUS_ENABLED  = 1;
+    Byte STATUS_ENABLED = 1;
     Byte STATUS_DISABLED = 0;
-    Byte STATUS_LOCKED   = -1;
+    Byte STATUS_LOCKED = -1;
 }

+ 18 - 0
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/DataStatusEnum.java

@@ -0,0 +1,18 @@
+package org.hswebframework.web.commons.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.hswebframework.web.dict.EnumDict;
+
+@AllArgsConstructor
+@Getter
+public enum DataStatusEnum implements EnumDict<Byte> {
+    ENABLED((byte) 1, "正常"),
+    DISABLED((byte) 0, "禁用"),
+    LOCK((byte) -1, "锁定"),
+    DELETED((byte) -10, "删除");
+
+    private Byte value;
+
+    private String text;
+}

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

@@ -26,6 +26,20 @@ public interface EnumDict<V> {
      */
     String getText();
 
+    /**
+     * 对比是否和value相等,对比地址,值,value转为string忽略大小写对比,text忽略大小写对比
+     *
+     * @param v value
+     * @return 是否相等
+     */
+    default boolean eq(Object v) {
+        return getValue() == v
+                || getValue().equals(v)
+                || String.valueOf(getValue()).equalsIgnoreCase(String.valueOf(v))
+                || getText().equalsIgnoreCase(String.valueOf(v));
+    }
+
+
     /**
      * 枚举选项的描述,对一个选项进行详细的描述有时候是必要的.默认值为{@link this#getText()}
      *
@@ -77,7 +91,7 @@ public interface EnumDict<V> {
      *
      * @see this#find(Class, Predicate)
      */
-    static <T extends Enum & EnumDict> Optional<T> find(Class<T> type, Object valueOrTextOrAlias) {
-        return Optional.ofNullable(findByValue(type, valueOrTextOrAlias).orElseGet(() -> findByText(type, String.valueOf(valueOrTextOrAlias)).orElse(null)));
+    static <T extends Enum & EnumDict> Optional<T> find(Class<T> type, Object target) {
+        return find(type, v->v.eq(target));
     }
 }

+ 19 - 0
hsweb-core/src/main/java/org/hswebframework/web/dict/defaults/TrueOrFalse.java

@@ -0,0 +1,19 @@
+package org.hswebframework.web.dict.defaults;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.hswebframework.web.dict.EnumDict;
+
+@Getter
+@AllArgsConstructor
+public enum TrueOrFalse implements EnumDict<Byte> {
+    
+    TRUE((byte) 1, "是"),
+
+    FALSE((byte) 0, "否");
+
+    private Byte value;
+
+    private String text;
+
+}

+ 1 - 1
hsweb-core/src/main/java/org/hswebframework/web/validate/ValidateResults.java

@@ -22,7 +22,7 @@ import java.io.Serializable;
 import java.util.List;
 
 /**
- * TODO 完成注释
+ * 验证结果
  *
  * @author zhouhao
  */

+ 1 - 0
hsweb-core/src/main/java/org/hswebframework/web/validate/ValidationException.java

@@ -24,6 +24,7 @@ import org.hswebframework.web.BusinessException;
 import java.util.List;
 
 public class ValidationException extends BusinessException {
+    private static final long serialVersionUID = 7807607467371210082L;
     private ValidateResults results;
 
     public ValidationException(String message) {

+ 4 - 2
hsweb-core/src/test/java/org/hswebframework/web/bean/FastBeanCopierTest.java

@@ -1,7 +1,9 @@
 package org.hswebframework.web.bean;
 
+import org.apache.commons.beanutils.BeanUtils;
 import org.junit.Test;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -13,7 +15,7 @@ import java.util.Map;
 public class FastBeanCopierTest {
 
     @Test
-    public void test() {
+    public void test() throws InvocationTargetException, IllegalAccessException {
         Source source = new Source();
         source.setAge(100);
         source.setName("测试");
@@ -31,8 +33,8 @@ public class FastBeanCopierTest {
         Target target = new Target();
         FastBeanCopier.copy(source, target);
 
+
         long t = System.currentTimeMillis();
-//        Copier copier = FastBeanCopier.getCopier(source, target, true);
         for (int i = 10_0000; i > 0; i--) {
             FastBeanCopier.copy(source, target);
         }

+ 0 - 1
hsweb-core/src/test/java/org/hswebframework/web/dict/DictDefineTest.java

@@ -29,7 +29,6 @@ public class DictDefineTest {
         Assert.assertEquals(UserCode.SIMPLE, EnumDict.findByText(UserCode.class, UserCode.SIMPLE.getText()).orElse(null));
 
         Assert.assertEquals(UserCode.SIMPLE, EnumDict.find(UserCode.class, UserCode.SIMPLE.getText()).orElse(null));
-
     }
 
     @Test

+ 0 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/AuthorizationSettingMenuService.java

@@ -7,7 +7,6 @@ import org.hswebframework.web.service.TreeService;
 import java.util.List;
 
 /**
- * TODO 完成注释
  *
  * @author zhouhao
  */

+ 20 - 22
hsweb-system/hsweb-system-schedule/hsweb-system-schedule-service/hsweb-system-schedule-service-simple/src/main/java/org/hswebframework/web/service/schedule/simple/SimpleScheduleJobService.java

@@ -8,7 +8,6 @@ import org.hswebframework.web.commons.entity.DataStatus;
 import org.hswebframework.web.dao.schedule.ScheduleJobDao;
 import org.hswebframework.web.entity.schedule.ScheduleJobEntity;
 import org.hswebframework.web.id.IDGenerator;
-import org.hswebframework.web.service.EnableCacheGenericEntityService;
 import org.hswebframework.web.service.GenericEntityService;
 import org.hswebframework.web.service.schedule.ScheduleJobService;
 import org.hswebframework.web.service.schedule.ScheduleTriggerBuilder;
@@ -16,7 +15,6 @@ import org.quartz.*;
 import org.quartz.spi.MutableTrigger;
 import org.quartz.spi.OperableTrigger;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.annotation.CacheConfig;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
@@ -83,18 +81,18 @@ public class SimpleScheduleJobService extends GenericEntityService<ScheduleJobEn
 
     protected void startJob(ScheduleJobEntity jobEntity) {
         try {
-        if(scheduler.checkExists(createJobKey(jobEntity))) {
-            return;
-        }
-        JobDetail jobDetail = JobBuilder
-                .newJob(DynamicJob.class)
-                .withIdentity(createJobKey(jobEntity))
-                .setJobData(createJobDataMap(jobEntity.getParameters()))
-                .usingJobData(DynamicJobFactory.JOB_ID_KEY, jobEntity.getId())
-                .withDescription(jobEntity.getName() + (jobEntity.getRemark() == null ? "" : jobEntity.getRemark()))
-                .build();
-        MutableTrigger trigger = scheduleTriggerBuilder.buildTrigger(jobEntity.getQuartzConfig());
-        trigger.setKey(createTriggerKey(jobEntity));
+            if (scheduler.checkExists(createJobKey(jobEntity))) {
+                return;
+            }
+            JobDetail jobDetail = JobBuilder
+                    .newJob(DynamicJob.class)
+                    .withIdentity(createJobKey(jobEntity))
+                    .setJobData(createJobDataMap(jobEntity.getParameters()))
+                    .usingJobData(DynamicJobFactory.JOB_ID_KEY, jobEntity.getId())
+                    .withDescription(jobEntity.getName() + (jobEntity.getRemark() == null ? "" : jobEntity.getRemark()))
+                    .build();
+            MutableTrigger trigger = scheduleTriggerBuilder.buildTrigger(jobEntity.getQuartzConfig());
+            trigger.setKey(createTriggerKey(jobEntity));
 
             scheduler.scheduleJob(jobDetail, trigger);
         } catch (SchedulerException e) {
@@ -129,11 +127,11 @@ public class SimpleScheduleJobService extends GenericEntityService<ScheduleJobEn
     @Override
     public void enable(String id) {
         Objects.requireNonNull(id);
-      int size=  createUpdate().set(ScheduleJobEntity.status, DataStatus.STATUS_ENABLED)
+        int size = createUpdate().set(ScheduleJobEntity.status, DataStatus.STATUS_ENABLED)
                 .where(ScheduleJobEntity.id, id).exec();
-      if(size>0) {
-          startJob(selectByPk(id));
-      }
+        if (size > 0) {
+            startJob(selectByPk(id));
+        }
     }
 
     private void deleteJob(ScheduleJobEntity jobEntity) {
@@ -150,10 +148,10 @@ public class SimpleScheduleJobService extends GenericEntityService<ScheduleJobEn
     @Override
     public void disable(String id) {
         Objects.requireNonNull(id);
-       int size =  createUpdate().set(ScheduleJobEntity.status, DataStatus.STATUS_DISABLED)
+        int size = createUpdate().set(ScheduleJobEntity.status, DataStatus.STATUS_DISABLED)
                 .where(ScheduleJobEntity.id, id).exec();
-       if(size>0) {
-           deleteJob(selectByPk(id));
-       }
+        if (size > 0) {
+            deleteJob(selectByPk(id));
+        }
     }
 }