Bladeren bron

优化实体类自定义拓展

zhouhao 3 jaren geleden
bovenliggende
commit
2b656b5943
13 gewijzigde bestanden met toevoegingen van 184 en 73 verwijderingen
  1. 7 9
      hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/AutoDDLProcessor.java
  2. 56 0
      hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/DetectEntityColumnMapping.java
  3. 15 4
      hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfiguration.java
  4. 16 38
      hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/EasyormRepositoryRegistrar.java
  5. 3 3
      hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/EntityInfo.java
  6. 5 0
      hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/entity/factory/MapperEntityFactory.java
  7. 6 9
      hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/generator/DefaultIdGenerator.java
  8. 18 8
      hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/CrudTests.java
  9. 6 2
      hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/TestApplication.java
  10. 26 0
      hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/entity/CustomTestEntity.java
  11. 2 0
      hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/entity/TestEntity.java
  12. 15 0
      hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/service/CustomTestCustom.java
  13. 9 0
      hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/service/TestEntityService.java

+ 7 - 9
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/AutoDDLProcessor.java

@@ -49,13 +49,11 @@ public class AutoDDLProcessor implements InitializingBean {
     @Override
     @SneakyThrows
     public void afterPropertiesSet() {
-        if (entityFactory instanceof MapperEntityFactory) {
-            MapperEntityFactory factory = ((MapperEntityFactory) entityFactory);
-            for (EntityInfo entity : entities) {
-                factory.addMapping(entity.getEntityType(), MapperEntityFactory.defaultMapper(entity.getRealType()));
-            }
-        }
-        List<Class> entities = this.entities.stream().map(EntityInfo::getRealType).collect(Collectors.toList());
+
+        List<Class<?>> entities = this.entities
+                .stream()
+                .map(e -> entityFactory.getInstanceType(e.getRealType(), true))
+                .collect(Collectors.toList());
         if (properties.isAutoDdl()) {
             //加载全部表信息
             if (reactive) {
@@ -63,7 +61,7 @@ public class AutoDDLProcessor implements InitializingBean {
                     .doOnNext(type -> log.trace("auto ddl for {}", type))
                     .map(type -> {
                         RDBTableMetadata metadata = resolver.resolve(type);
-                        EntityDDLEvent event = new EntityDDLEvent(this,type,metadata);
+                        EntityDDLEvent<?> event = new EntityDDLEvent<>(this, type, metadata);
                         eventPublisher.publishEvent(new GenericsPayloadApplicationEvent<>(this, event, type));
                         return metadata;
                     })
@@ -83,7 +81,7 @@ public class AutoDDLProcessor implements InitializingBean {
                     log.trace("auto ddl for {}", type);
                     try {
                         RDBTableMetadata metadata = resolver.resolve(type);
-                        EntityDDLEvent event = new EntityDDLEvent(this,type,metadata);
+                        EntityDDLEvent<?> event = new EntityDDLEvent<>(this, type, metadata);
                         eventPublisher.publishEvent(new GenericsPayloadApplicationEvent<>(this, event, type));
                         operator.ddl()
                                 .createOrAlter(metadata)

+ 56 - 0
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/DetectEntityColumnMapping.java

@@ -0,0 +1,56 @@
+package org.hswebframework.web.crud.configuration;
+
+import org.hswebframework.ezorm.rdb.mapping.EntityColumnMapping;
+import org.hswebframework.ezorm.rdb.mapping.MappingFeatureType;
+import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
+
+import java.util.Map;
+import java.util.Optional;
+
+class DetectEntityColumnMapping implements EntityColumnMapping {
+    private final String id;
+    private final Class<?> type;
+    private final EntityColumnMapping mapping;
+
+    public DetectEntityColumnMapping(Class<?> type,
+                                     EntityColumnMapping mapping) {
+        this.id = MappingFeatureType.columnPropertyMapping.createFeatureId(type);
+        this.type = type;
+        this.mapping = mapping;
+    }
+
+    @Override
+    public Class<?> getEntityType() {
+        return type;
+    }
+
+    @Override
+    public Optional<RDBColumnMetadata> getColumnByProperty(String property) {
+        return  mapping.getColumnByProperty(property);
+    }
+
+    @Override
+    public Optional<String> getPropertyByColumnName(String columnName) {
+        return  mapping.getPropertyByColumnName(columnName);
+    }
+
+    @Override
+    public Optional<RDBColumnMetadata> getColumnByName(String columnName) {
+        return mapping.getColumnByName(columnName);
+    }
+
+    @Override
+    public Map<String, String> getColumnPropertyMapping() {
+        return mapping.getColumnPropertyMapping();
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public String getName() {
+        return getId();
+    }
+}

+ 15 - 4
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/EasyormConfiguration.java

@@ -6,6 +6,7 @@ import org.hswebframework.ezorm.core.meta.Feature;
 import org.hswebframework.ezorm.rdb.events.EventListener;
 import org.hswebframework.ezorm.rdb.executor.SyncSqlExecutor;
 import org.hswebframework.ezorm.rdb.executor.reactive.ReactiveSqlExecutor;
+import org.hswebframework.ezorm.rdb.mapping.DefaultEntityColumnMapping;
 import org.hswebframework.ezorm.rdb.mapping.EntityColumnMapping;
 import org.hswebframework.ezorm.rdb.mapping.EntityManager;
 import org.hswebframework.ezorm.rdb.mapping.MappingFeatureType;
@@ -186,16 +187,25 @@ public class EasyormConfiguration {
         @Bean
         @ConditionalOnMissingBean
         public EntityTableMetadataParser jpaEntityTableMetadataParser(RDBDatabaseMetadata metadata,
+                                                                      EntityFactory factory,
                                                                       ObjectProvider<TableMetadataCustomizer> customizers) {
 
             JpaEntityTableMetadataParser parser = new JpaEntityTableMetadataParser() {
 
                 @Override
                 public Optional<RDBTableMetadata> parseTableMetadata(Class<?> entityType) {
-                    Optional<RDBTableMetadata> tableOpt = super.parseTableMetadata(entityType);
+                    Class<?> realType = factory.getInstanceType(entityType, true);
+                    Optional<RDBTableMetadata> tableOpt = super.parseTableMetadata(realType);
                     tableOpt.ifPresent(table -> {
+                        if (realType != entityType) {
+                            table.addFeature(new DetectEntityColumnMapping(
+                                    entityType,
+                                    table.findFeatureNow(
+                                            MappingFeatureType.columnPropertyMapping.createFeatureId(realType)
+                                    )));
+                        }
                         for (TableMetadataCustomizer customizer : customizers) {
-                            customizer.customTable(entityType, table);
+                            customizer.customTable(realType, table);
                         }
                     });
                     return tableOpt;
@@ -203,7 +213,8 @@ public class EasyormConfiguration {
 
                 @Override
                 protected JpaEntityTableMetadataParserProcessor createProcessor(RDBTableMetadata table, Class<?> type) {
-                    return new JpaEntityTableMetadataParserProcessor(table, type) {
+                    Class<?> realType = factory.getInstanceType(type, true);
+                    return new JpaEntityTableMetadataParserProcessor(table, realType) {
                         @Override
                         protected void customColumn(PropertyDescriptor descriptor,
                                                     Field field,
@@ -211,7 +222,7 @@ public class EasyormConfiguration {
                                                     Set<Annotation> annotations) {
                             super.customColumn(descriptor, field, column, annotations);
                             for (TableMetadataCustomizer customizer : customizers) {
-                                customizer.customColumn(type, descriptor, field, annotations, column);
+                                customizer.customColumn(realType, descriptor, field, annotations, column);
                             }
                         }
                     };

+ 16 - 38
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/EasyormRepositoryRegistrar.java

@@ -46,8 +46,10 @@ public class EasyormRepositoryRegistrar implements ImportBeanDefinitionRegistrar
 
     private String getResourceClassName(Resource resource) {
         try {
-            return metadataReaderFactory.getMetadataReader(resource)
-                                        .getClassMetadata().getClassName();
+            return metadataReaderFactory
+                    .getMetadataReader(resource)
+                    .getClassMetadata()
+                    .getClassName();
         } catch (IOException e) {
             return null;
         }
@@ -98,46 +100,31 @@ public class EasyormRepositoryRegistrar implements ImportBeanDefinitionRegistrar
         for (String className : scanEntities(arr)) {
             Class<?> entityType = org.springframework.util.ClassUtils.forName(className, null);
             if (Arrays.stream(anno)
-                      .noneMatch(ann -> AnnotationUtils.findAnnotation(entityType, ann) != null)) {
+                      .noneMatch(ann -> AnnotationUtils.getAnnotation(entityType, ann) != null)) {
                 continue;
             }
 
-            ImplementFor implementFor = AnnotationUtils.findAnnotation(entityType, ImplementFor.class);
             Reactive reactive = AnnotationUtils.findAnnotation(entityType, Reactive.class);
-            Class genericType = Optional
-                    .ofNullable(implementFor)
-                    .map(ImplementFor::value)
-                    .orElseGet(() -> {
-                        return Stream
-                                .of(entityType.getInterfaces())
-                                .filter(e -> GenericEntity.class.isAssignableFrom(e))
-                                .findFirst()
-                                .orElse(entityType);
-                    });
 
             Class idType = null;
-            if (implementFor == null || implementFor.idType() == Void.class) {
-                try {
-                    if (GenericEntity.class.isAssignableFrom(entityType)) {
-                        idType = ClassUtils.getGenericType(entityType);
-                    }
-                    if (idType == null) {
-                        Method getId = org.springframework.util.ClassUtils.getMethod(entityType, "getId");
-                        idType = getId.getReturnType();
-                    }
-                } catch (Exception e) {
-                    idType = String.class;
+            try {
+                if (GenericEntity.class.isAssignableFrom(entityType)) {
+                    idType = ClassUtils.getGenericType(entityType);
                 }
-            } else {
-                idType = implementFor.idType();
+                if (idType == null) {
+                    Method getId = org.springframework.util.ClassUtils.getMethod(entityType, "getId");
+                    idType = getId.getReturnType();
+                }
+            } catch (Exception e) {
+                idType = String.class;
             }
 
-            EntityInfo entityInfo = new EntityInfo(genericType,
+            EntityInfo entityInfo = new EntityInfo(entityType,
                                                    entityType,
                                                    idType,
                                                    reactiveEnabled,
                                                    nonReactiveEnabled);
-            if (!entityInfos.contains(entityInfo) || implementFor != null) {
+            if (!entityInfos.contains(entityInfo)) {
                 entityInfos.add(entityInfo);
             }
 
@@ -187,15 +174,6 @@ public class EasyormRepositoryRegistrar implements ImportBeanDefinitionRegistrar
             registry.registerBeanDefinition(AutoDDLProcessor.class.getName() + "_" + count.incrementAndGet(), definition);
         }
 
-//        try {
-//            BeanDefinition definition = registry.getBeanDefinition(AutoDDLProcessor.class.getName());
-//            Set<EntityInfo> infos = (Set) definition.getPropertyValues().get("entities");
-//            infos.addAll(entityInfos);
-//        } catch (NoSuchBeanDefinitionException e) {
-//
-//        }
-
-
     }
 
     static AtomicInteger count = new AtomicInteger();

+ 3 - 3
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/EntityInfo.java

@@ -10,11 +10,11 @@ import lombok.Setter;
 @EqualsAndHashCode(of = "entityType")
 @AllArgsConstructor
 public class EntityInfo {
-    private Class entityType;
+    private Class<?> entityType;
 
-    private Class realType;
+    private Class<?> realType;
 
-    private Class idType;
+    private Class<?> idType;
 
     private boolean reactive;
 

+ 5 - 0
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/entity/factory/MapperEntityFactory.java

@@ -73,6 +73,11 @@ public class MapperEntityFactory implements EntityFactory, BeanFactory {
         return this;
     }
 
+    public <T> MapperEntityFactory addMappingIfAbsent(Class<T> target, Mapper<? extends T> mapper) {
+        realTypeMapper.putIfAbsent(target, mapper);
+        return this;
+    }
+
     public <S, T> MapperEntityFactory addCopier(PropertyCopier<S, T> copier) {
         Class<S> source = (Class<S>) ClassUtils.getGenericType(copier.getClass(), 0);
         Class<T> target = (Class<T>) ClassUtils.getGenericType(copier.getClass(), 1);

+ 6 - 9
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/generator/DefaultIdGenerator.java

@@ -8,13 +8,14 @@ import org.hswebframework.ezorm.core.DefaultValue;
 import org.hswebframework.ezorm.core.DefaultValueGenerator;
 import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
 import org.hswebframework.web.id.IDGenerator;
+import org.springframework.util.StringUtils;
 import reactor.core.publisher.Mono;
 
 import java.util.HashMap;
 import java.util.Map;
 
 @Slf4j
-public class DefaultIdGenerator implements DefaultValueGenerator<RDBColumnMetadata>  {
+public class DefaultIdGenerator implements DefaultValueGenerator<RDBColumnMetadata> {
 
     @Getter
     @Setter
@@ -32,14 +33,10 @@ public class DefaultIdGenerator implements DefaultValueGenerator<RDBColumnMetada
     @Override
     @SneakyThrows
     public DefaultValue generate(RDBColumnMetadata metadata) {
-        return Mono.justOrEmpty(mappings.get(metadata.getOwner().getName()))
-                .switchIfEmpty(Mono.justOrEmpty(defaultId))
-                .flatMap(id->Mono.justOrEmpty(metadata.findFeature(DefaultValueGenerator.createId(id))))
-                .doOnNext(gen-> log.debug("use default id generator : {} for column : {}", gen.getSortId(), metadata.getFullName()))
-                .map(gen->gen.generate(metadata))
-                .switchIfEmpty(Mono.error(()->new UnsupportedOperationException("不支持的生成器:" + defaultId)))
-                .toFuture()
-                .get();
+        String genId = mappings.getOrDefault(metadata.getOwner().getName(), defaultId);
+        DefaultValueGenerator<RDBColumnMetadata> generator = metadata.findFeatureNow(DefaultValueGenerator.createId(genId));
+        log.debug("use default id generator : {} for column : {}", generator.getSortId(), metadata.getFullName());
+        return generator.generate(metadata);
     }
 
     @Override

+ 18 - 8
hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/CrudTests.java

@@ -1,5 +1,6 @@
 package org.hswebframework.web.crud;
 
+import org.hswebframework.web.crud.entity.CustomTestEntity;
 import org.hswebframework.web.crud.entity.TestEntity;
 import org.hswebframework.web.crud.service.TestEntityService;
 import org.junit.Assert;
@@ -13,22 +14,31 @@ import reactor.test.StepVerifier;
 
 @SpringBootTest
 @RunWith(SpringJUnit4ClassRunner.class)
-public class CrudTests  {
+public class CrudTests {
 
     @Autowired
     private TestEntityService service;
 
 
     @Test
-    public void test(){
-
-        TestEntity entity = TestEntity.of("test",100);
+    public void test() {
 
+        CustomTestEntity entity = new CustomTestEntity();
+        entity.setExt("xxx");
+        entity.setAge(1);
+        entity.setName("test");
+        
         Mono.just(entity)
-                .as(service::insert)
-                .as(StepVerifier::create)
-                .expectNext(1)
-                .verifyComplete();
+            .cast(TestEntity.class)
+            .as(service::insert)
+            .as(StepVerifier::create)
+            .expectNext(1)
+            .verifyComplete();
         Assert.assertNotNull(entity.getId());
+
+        service.findById(entity.getId())
+               .as(StepVerifier::create)
+               .expectNextMatches(e -> e instanceof CustomTestEntity)
+               .verifyComplete();
     }
 }

+ 6 - 2
hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/TestApplication.java

@@ -1,7 +1,9 @@
 package org.hswebframework.web.crud;
 
 import org.hswebframework.web.api.crud.entity.EntityFactory;
+import org.hswebframework.web.crud.entity.factory.EntityMappingCustomizer;
 import org.hswebframework.web.crud.entity.factory.MapperEntityFactory;
+import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.context.annotation.Bean;
@@ -13,7 +15,9 @@ import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
 public class TestApplication {
 
     @Bean
-    public EntityFactory entityFactory(){
-        return new MapperEntityFactory();
+    public EntityFactory entityFactory(ObjectProvider<EntityMappingCustomizer> customizers) {
+        MapperEntityFactory factory = new MapperEntityFactory();
+        customizers.forEach(customizer -> customizer.custom(factory));
+        return factory;
     }
 }

+ 26 - 0
hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/entity/CustomTestEntity.java

@@ -0,0 +1,26 @@
+package org.hswebframework.web.crud.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.hswebframework.web.api.crud.entity.GenericEntity;
+import org.hswebframework.web.bean.ToString;
+import org.hswebframework.web.crud.generator.Generators;
+
+import javax.persistence.Column;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Table;
+
+@Getter
+@Setter
+@AllArgsConstructor(staticName = "of")
+@NoArgsConstructor
+public class CustomTestEntity extends TestEntity {
+
+
+    @Column
+    @ToString.Ignore
+    private String ext;
+
+}

+ 2 - 0
hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/entity/TestEntity.java

@@ -5,6 +5,7 @@ import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
 import org.hswebframework.web.api.crud.entity.GenericEntity;
+import org.hswebframework.web.crud.annotation.EnableEntityEvent;
 import org.hswebframework.web.crud.generator.Generators;
 
 import javax.persistence.Column;
@@ -16,6 +17,7 @@ import javax.persistence.Table;
 @Table(name = "s_test")
 @AllArgsConstructor(staticName = "of")
 @NoArgsConstructor
+@EnableEntityEvent
 public class TestEntity extends GenericEntity<String> {
 
     @Column(length = 32)

+ 15 - 0
hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/service/CustomTestCustom.java

@@ -0,0 +1,15 @@
+package org.hswebframework.web.crud.service;
+
+import org.hswebframework.web.crud.entity.CustomTestEntity;
+import org.hswebframework.web.crud.entity.TestEntity;
+import org.hswebframework.web.crud.entity.factory.EntityMappingCustomizer;
+import org.hswebframework.web.crud.entity.factory.MapperEntityFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CustomTestCustom implements EntityMappingCustomizer {
+    @Override
+    public void custom(MapperEntityFactory factory) {
+        factory.addMapping(TestEntity.class, new MapperEntityFactory.Mapper<>(CustomTestEntity.class,CustomTestEntity::new));
+    }
+}

+ 9 - 0
hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/service/TestEntityService.java

@@ -1,10 +1,19 @@
 package org.hswebframework.web.crud.service;
 
 import org.hswebframework.web.crud.entity.TestEntity;
+import org.hswebframework.web.crud.events.EntityCreatedEvent;
 import org.hswebframework.web.id.IDGenerator;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.event.EventListener;
 import org.springframework.stereotype.Service;
 
 @Service
 public class TestEntityService extends GenericReactiveCrudService<TestEntity,String> {
 
+
+    @EventListener
+    public void handleEvent(EntityCreatedEvent<TestEntity> event){
+
+        System.out.println(event.getEntity());
+    }
 }