Selaa lähdekoodia

增加表结构自定义

zhouhao 3 vuotta sitten
vanhempi
commit
417a31e6fe

+ 2 - 4
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/CompositeEntityTableMetadataResolver.java

@@ -15,7 +15,7 @@ public class CompositeEntityTableMetadataResolver implements EntityTableMetadata
 
     private final List<EntityTableMetadataParser> resolvers = new ArrayList<>();
 
-    private final Map<Class, AtomicReference<RDBTableMetadata>> cache = new ConcurrentHashMap<>();
+    private final Map<Class<?>, AtomicReference<RDBTableMetadata>> cache = new ConcurrentHashMap<>();
 
     public void addParser(EntityTableMetadataParser resolver) {
         resolvers.add(resolver);
@@ -33,9 +33,7 @@ public class CompositeEntityTableMetadataResolver implements EntityTableMetadata
                 .filter(Optional::isPresent)
                 .map(Optional::get)
                 .reduce((t1, t2) -> {
-                    for (RDBColumnMetadata column : t1.getColumns()) {
-                        t2.addColumn(column.clone());
-                    }
+                    t2.merge(t1);
                     return t2;
                 }).orElse(null);
     }

+ 83 - 43
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfiguration.java

@@ -10,9 +10,12 @@ import org.hswebframework.ezorm.rdb.mapping.EntityColumnMapping;
 import org.hswebframework.ezorm.rdb.mapping.EntityManager;
 import org.hswebframework.ezorm.rdb.mapping.MappingFeatureType;
 import org.hswebframework.ezorm.rdb.mapping.jpa.JpaEntityTableMetadataParser;
+import org.hswebframework.ezorm.rdb.mapping.jpa.JpaEntityTableMetadataParserProcessor;
 import org.hswebframework.ezorm.rdb.mapping.parser.EntityTableMetadataParser;
+import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
 import org.hswebframework.ezorm.rdb.metadata.RDBDatabaseMetadata;
 import org.hswebframework.ezorm.rdb.metadata.RDBSchemaMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
 import org.hswebframework.ezorm.rdb.operator.DatabaseOperator;
 import org.hswebframework.ezorm.rdb.operator.DefaultDatabaseOperator;
 import org.hswebframework.web.api.crud.entity.EntityFactory;
@@ -35,9 +38,13 @@ import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
 import java.time.Duration;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 
 @Configuration
 @EnableConfigurationProperties(EasyormProperties.class)
@@ -61,49 +68,6 @@ public class EasyormConfiguration {
         return factory;
     }
 
-    @Bean
-    @ConditionalOnMissingBean
-    public EntityManager entityManager(EntityTableMetadataResolver resolver, EntityFactory entityFactory) {
-        return new EntityManager() {
-            @Override
-            @SneakyThrows
-            public <E> E newInstance(Class<E> type) {
-                return entityFactory.newInstance(type);
-            }
-
-            @Override
-            public EntityColumnMapping getMapping(Class entity) {
-
-                return resolver.resolve(entityFactory.getInstanceType(entity, true))
-                               .getFeature(MappingFeatureType.columnPropertyMapping.createFeatureId(entity))
-                               .map(EntityColumnMapping.class::cast)
-                               .orElse(null);
-            }
-        };
-    }
-
-    @Bean
-    public DefaultEntityResultWrapperFactory defaultEntityResultWrapperFactory(EntityManager entityManager) {
-        return new DefaultEntityResultWrapperFactory(entityManager);
-    }
-
-    @Bean
-    @ConditionalOnMissingBean
-    public EntityTableMetadataResolver entityTableMappingResolver(List<EntityTableMetadataParser> parsers) {
-        CompositeEntityTableMetadataResolver resolver = new CompositeEntityTableMetadataResolver();
-        parsers.forEach(resolver::addParser);
-        return resolver;
-    }
-
-    @Bean
-    @ConditionalOnMissingBean
-    public EntityTableMetadataParser jpaEntityTableMetadataParser(RDBDatabaseMetadata metadata) {
-        JpaEntityTableMetadataParser parser = new JpaEntityTableMetadataParser();
-        parser.setDatabaseMetadata(metadata);
-
-        return parser;
-    }
-
     @Bean
     @ConditionalOnMissingBean
     @SuppressWarnings("all")
@@ -182,4 +146,80 @@ public class EasyormConfiguration {
         return new CurrentTimeGenerator();
     }
 
+    @Configuration
+    public static class EntityTableMetadataParserConfiguration {
+
+        @Bean
+        public DefaultEntityResultWrapperFactory defaultEntityResultWrapperFactory(EntityManager entityManager) {
+            return new DefaultEntityResultWrapperFactory(entityManager);
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        public EntityManager entityManager(EntityTableMetadataResolver resolver, EntityFactory entityFactory) {
+            return new EntityManager() {
+                @Override
+                @SneakyThrows
+                public <E> E newInstance(Class<E> type) {
+                    return entityFactory.newInstance(type);
+                }
+
+                @Override
+                public EntityColumnMapping getMapping(Class entity) {
+
+                    return resolver.resolve(entityFactory.getInstanceType(entity, true))
+                                   .getFeature(MappingFeatureType.columnPropertyMapping.createFeatureId(entity))
+                                   .map(EntityColumnMapping.class::cast)
+                                   .orElse(null);
+                }
+            };
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        public EntityTableMetadataResolver entityTableMappingResolver(ObjectProvider<EntityTableMetadataParser> parsers) {
+            CompositeEntityTableMetadataResolver resolver = new CompositeEntityTableMetadataResolver();
+            parsers.forEach(resolver::addParser);
+            return resolver;
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        public EntityTableMetadataParser jpaEntityTableMetadataParser(RDBDatabaseMetadata metadata,
+                                                                      ObjectProvider<TableMetadataCustomizer> customizers) {
+
+            JpaEntityTableMetadataParser parser = new JpaEntityTableMetadataParser() {
+
+                @Override
+                public Optional<RDBTableMetadata> parseTableMetadata(Class<?> entityType) {
+                    Optional<RDBTableMetadata> tableOpt = super.parseTableMetadata(entityType);
+                    tableOpt.ifPresent(table -> {
+                        for (TableMetadataCustomizer customizer : customizers) {
+                            customizer.customTable(entityType, table);
+                        }
+                    });
+                    return tableOpt;
+                }
+
+                @Override
+                protected JpaEntityTableMetadataParserProcessor createProcessor(RDBTableMetadata table, Class<?> type) {
+                    return new JpaEntityTableMetadataParserProcessor(table, type) {
+                        @Override
+                        protected void customColumn(PropertyDescriptor descriptor,
+                                                    Field field,
+                                                    RDBColumnMetadata column,
+                                                    Set<Annotation> annotations) {
+                            super.customColumn(descriptor, field, column, annotations);
+                            for (TableMetadataCustomizer customizer : customizers) {
+                                customizer.customColumn(type, descriptor, field, annotations, column);
+                            }
+                        }
+                    };
+                }
+            };
+            parser.setDatabaseMetadata(metadata);
+
+            return parser;
+        }
+    }
 }

+ 41 - 0
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/TableMetadataCustomizer.java

@@ -0,0 +1,41 @@
+package org.hswebframework.web.crud.configuration;
+
+import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
+import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
+
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.Set;
+
+/**
+ * 表结构自定义器,实现此接口来自定义表结构.
+ *
+ * @author zhouhao
+ * @since 4.0.14
+ */
+public interface TableMetadataCustomizer {
+
+    /**
+     * 自定义列,在列被解析后调用.
+     *
+     * @param entityType  实体类型
+     * @param descriptor  字段描述
+     * @param field       字段
+     * @param column      列定义
+     * @param annotations 字段上的注解
+     */
+    void customColumn(Class<?> entityType,
+                      PropertyDescriptor descriptor,
+                      Field field,
+                      Set<Annotation> annotations,
+                      RDBColumnMetadata column);
+
+    /**
+     * 自定义表,在实体类被解析完成后调用.
+     *
+     * @param entityType 字段类型
+     * @param table      表结构
+     */
+    void customTable(Class<?> entityType, RDBTableMetadata table);
+}

+ 1 - 1
pom.xml

@@ -90,7 +90,7 @@
         <cglib.version>3.2.2</cglib.version>
         <aspectj.version>1.6.12</aspectj.version>
 
-        <hsweb.ezorm.version>4.0.12</hsweb.ezorm.version>
+        <hsweb.ezorm.version>4.0.14-SNAPSHOT</hsweb.ezorm.version>
         <hsweb.utils.version>3.0.2</hsweb.utils.version>
         <hsweb.expands.version>3.0.2</hsweb.expands.version>
         <swagger.version>2.7.0</swagger.version>