From ca801a35a93121676f8fa979760647a4ef74f631 Mon Sep 17 00:00:00 2001 From: lorne <1991wangliang@gmail.com> Date: Thu, 11 Dec 2025 22:41:11 +0800 Subject: [PATCH] fix #167 --- .../example-app-cmd-domain/pom.xml | 2 +- .../example-app/example-app-cmd-meta/pom.xml | 2 +- example/example-app/example-app-query/pom.xml | 2 +- example/example-app/pom.xml | 2 +- .../example-domain-leave/pom.xml | 2 +- .../example-domain-user/pom.xml | 2 +- example/example-domain/pom.xml | 2 +- .../example-infra/example-infra-flow/pom.xml | 2 +- .../example-infra/example-infra-jpa/pom.xml | 2 +- .../example-infra-security/pom.xml | 2 +- example/example-infra/pom.xml | 2 +- example/example-interface/pom.xml | 2 +- example/example-server/pom.xml | 2 +- .../src/main/resources/application.properties | 16 +- example/pom.xml | 2 +- pom.xml | 2 +- springboot-starter-data-authorization/pom.xml | 2 +- springboot-starter-data-fast/pom.xml | 2 +- .../classloader/DynamicEntityClassLoader.java | 60 ----- .../DynamicEntityClassLoaderContext.java | 27 --- .../classloader/DynamicTableClassLoader.java | 158 ++++++++++++ .../DynamicTableGenerator.java} | 82 ++++++- .../fast/metadata/EntityMetaData.java | 133 ---------- .../TableEntityClassBuilder.java} | 182 ++++---------- .../fast/metadata/TableEntityMetadata.java | 228 ++++++++++++++++++ .../dynamic/DynamicEntityBuilderTest.java | 62 ----- .../generator/DynamicTableGeneratorTest.java | 61 +++++ springboot-starter-flow/pom.xml | 2 +- springboot-starter-security/pom.xml | 2 +- springboot-starter/pom.xml | 2 +- 30 files changed, 597 insertions(+), 452 deletions(-) delete mode 100644 springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassLoader.java delete mode 100644 springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassLoaderContext.java create mode 100644 springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicTableClassLoader.java rename springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/{dynamic/DynamicEntityBuilder.java => generator/DynamicTableGenerator.java} (72%) delete mode 100644 springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/EntityMetaData.java rename springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/{classloader/DynamicEntityClassBuilder.java => metadata/TableEntityClassBuilder.java} (50%) create mode 100644 springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/TableEntityMetadata.java delete mode 100644 springboot-starter-data-fast/src/test/java/com/codingapi/springboot/fast/dynamic/DynamicEntityBuilderTest.java create mode 100644 springboot-starter-data-fast/src/test/java/com/codingapi/springboot/fast/generator/DynamicTableGeneratorTest.java diff --git a/example/example-app/example-app-cmd-domain/pom.xml b/example/example-app/example-app-cmd-domain/pom.xml index 86a1c254..e78052e5 100644 --- a/example/example-app/example-app-cmd-domain/pom.xml +++ b/example/example-app/example-app-cmd-domain/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-app - 3.4.24 + 3.4.25 ../pom.xml diff --git a/example/example-app/example-app-cmd-meta/pom.xml b/example/example-app/example-app-cmd-meta/pom.xml index c0ed3c91..3a80d9a1 100644 --- a/example/example-app/example-app-cmd-meta/pom.xml +++ b/example/example-app/example-app-cmd-meta/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-app - 3.4.24 + 3.4.25 ../pom.xml diff --git a/example/example-app/example-app-query/pom.xml b/example/example-app/example-app-query/pom.xml index f9d5cd14..7bcba2d6 100644 --- a/example/example-app/example-app-query/pom.xml +++ b/example/example-app/example-app-query/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-app - 3.4.24 + 3.4.25 ../pom.xml diff --git a/example/example-app/pom.xml b/example/example-app/pom.xml index 735483bf..0ce8c630 100644 --- a/example/example-app/pom.xml +++ b/example/example-app/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot springboot-example - 3.4.24 + 3.4.25 ../pom.xml pom diff --git a/example/example-domain/example-domain-leave/pom.xml b/example/example-domain/example-domain-leave/pom.xml index d369d840..c70daa4a 100644 --- a/example/example-domain/example-domain-leave/pom.xml +++ b/example/example-domain/example-domain-leave/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-domain - 3.4.24 + 3.4.25 ../pom.xml diff --git a/example/example-domain/example-domain-user/pom.xml b/example/example-domain/example-domain-user/pom.xml index 010e9712..68949119 100644 --- a/example/example-domain/example-domain-user/pom.xml +++ b/example/example-domain/example-domain-user/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-domain - 3.4.24 + 3.4.25 ../pom.xml diff --git a/example/example-domain/pom.xml b/example/example-domain/pom.xml index d0b4bf53..42fac3ca 100644 --- a/example/example-domain/pom.xml +++ b/example/example-domain/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot springboot-example - 3.4.24 + 3.4.25 ../pom.xml 4.0.0 diff --git a/example/example-infra/example-infra-flow/pom.xml b/example/example-infra/example-infra-flow/pom.xml index 12e565f6..f43916d2 100644 --- a/example/example-infra/example-infra-flow/pom.xml +++ b/example/example-infra/example-infra-flow/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot example-infra - 3.4.24 + 3.4.25 ../pom.xml diff --git a/example/example-infra/example-infra-jpa/pom.xml b/example/example-infra/example-infra-jpa/pom.xml index 07fa83dc..5e1243ba 100644 --- a/example/example-infra/example-infra-jpa/pom.xml +++ b/example/example-infra/example-infra-jpa/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot example-infra - 3.4.24 + 3.4.25 ../pom.xml diff --git a/example/example-infra/example-infra-security/pom.xml b/example/example-infra/example-infra-security/pom.xml index d905d92a..c362aa78 100644 --- a/example/example-infra/example-infra-security/pom.xml +++ b/example/example-infra/example-infra-security/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot example-infra - 3.4.24 + 3.4.25 ../pom.xml diff --git a/example/example-infra/pom.xml b/example/example-infra/pom.xml index a1d0acfc..91bc1c05 100644 --- a/example/example-infra/pom.xml +++ b/example/example-infra/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot springboot-example - 3.4.24 + 3.4.25 ../pom.xml pom diff --git a/example/example-interface/pom.xml b/example/example-interface/pom.xml index f6d78dd0..15edf40c 100644 --- a/example/example-interface/pom.xml +++ b/example/example-interface/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot springboot-example - 3.4.24 + 3.4.25 example-interface diff --git a/example/example-server/pom.xml b/example/example-server/pom.xml index be3ef03c..fa3017b0 100644 --- a/example/example-server/pom.xml +++ b/example/example-server/pom.xml @@ -5,7 +5,7 @@ springboot-example com.codingapi.springboot - 3.4.24 + 3.4.25 4.0.0 diff --git a/example/example-server/src/main/resources/application.properties b/example/example-server/src/main/resources/application.properties index 314b78fb..35a250d8 100644 --- a/example/example-server/src/main/resources/application.properties +++ b/example/example-server/src/main/resources/application.properties @@ -1,16 +1,16 @@ server.port=8090 application.version=@project.version@ -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:file:./example.db -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +#spring.datasource.driver-class-name=org.h2.Driver +#spring.datasource.url=jdbc:h2:file:./example.db +#spring.jpa.database-platform=org.hibernate.dialect.H2Dialect -#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -#spring.datasource.url=jdbc:mysql://localhost:3306/flow?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true -#spring.datasource.username=root -#spring.datasource.password=admin123 -#spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.datasource.url=jdbc:mysql://localhost:3306/flow?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true +spring.datasource.username=root +spring.datasource.password=12345678 +spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true diff --git a/example/pom.xml b/example/pom.xml index 24b4ebfb..b47025af 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -19,7 +19,7 @@ springboot-example - 3.4.24 + 3.4.25 springboot-example springboot-example project for Spring Boot diff --git a/pom.xml b/pom.xml index 861192da..c6334482 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ com.codingapi.springboot springboot-parent - 3.4.24 + 3.4.25 https://github.com/codingapi/springboot-framewrok springboot-parent diff --git a/springboot-starter-data-authorization/pom.xml b/springboot-starter-data-authorization/pom.xml index e6116bf4..ebb3a4c6 100644 --- a/springboot-starter-data-authorization/pom.xml +++ b/springboot-starter-data-authorization/pom.xml @@ -6,7 +6,7 @@ com.codingapi.springboot springboot-parent - 3.4.24 + 3.4.25 springboot-starter-data-authorization diff --git a/springboot-starter-data-fast/pom.xml b/springboot-starter-data-fast/pom.xml index 82e10ab5..1a4bbf5e 100644 --- a/springboot-starter-data-fast/pom.xml +++ b/springboot-starter-data-fast/pom.xml @@ -5,7 +5,7 @@ springboot-parent com.codingapi.springboot - 3.4.24 + 3.4.25 4.0.0 diff --git a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassLoader.java b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassLoader.java deleted file mode 100644 index 202a80dc..00000000 --- a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassLoader.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.codingapi.springboot.fast.classloader; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -class DynamicEntityClassLoader extends ClassLoader { - - private final Map> dynamicClasses = new ConcurrentHashMap<>(); - - public DynamicEntityClassLoader(ClassLoader parent) { - super(parent); - } - - public void registerClass(String className, Class clazz) { - dynamicClasses.put(className, clazz); - } - - public void registerClass(Class clazz) { - this.registerClass(clazz.getName(), clazz); - } - - - @Override - protected Class findClass(String name) throws ClassNotFoundException { - // 首先检查已加载的动态类 - if (dynamicClasses.containsKey(name)) { - return dynamicClasses.get(name); - } - // 委托给父类 - return super.findClass(name); - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException { - return loadClass(name, false); - } - - @Override - protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - synchronized (getClassLoadingLock(name)) { - // 首先检查是否已经加载 - Class c = findLoadedClass(name); - if (c == null) { - // 检查是否是动态类 - if (dynamicClasses.containsKey(name)) { - c = dynamicClasses.get(name); - } else { - // 委托给父类 - c = super.loadClass(name, resolve); - } - } - - if (resolve) { - resolveClass(c); - } - return c; - } - } - -} diff --git a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassLoaderContext.java b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassLoaderContext.java deleted file mode 100644 index 555e4917..00000000 --- a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassLoaderContext.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.codingapi.springboot.fast.classloader; - -import lombok.Getter; - -public class DynamicEntityClassLoaderContext { - - @Getter - private final static DynamicEntityClassLoaderContext instance = new DynamicEntityClassLoaderContext(); - - private final DynamicEntityClassLoader dynamicEntityClassLoader; - - private DynamicEntityClassLoaderContext(){ - dynamicEntityClassLoader = new DynamicEntityClassLoader(Thread.currentThread().getContextClassLoader() != null - ? Thread.currentThread().getContextClassLoader() - : getClass().getClassLoader()); - Thread.currentThread().setContextClassLoader(dynamicEntityClassLoader); - } - - public void registerClass(String className, Class clazz) { - dynamicEntityClassLoader.registerClass(className, clazz); - } - - public void registerClass(Class clazz) { - dynamicEntityClassLoader.registerClass(clazz); - } - -} diff --git a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicTableClassLoader.java b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicTableClassLoader.java new file mode 100644 index 00000000..cf182bf2 --- /dev/null +++ b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicTableClassLoader.java @@ -0,0 +1,158 @@ +package com.codingapi.springboot.fast.classloader; + +import lombok.Getter; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 动态表的 ClassLoader + */ +public class DynamicTableClassLoader { + + @Getter + private final static DynamicTableClassLoader instance = new DynamicTableClassLoader(); + + private final $DynamicTableClassLoader dynamicTableClassLoader; + + private DynamicTableClassLoader() { + dynamicTableClassLoader = new $DynamicTableClassLoader(Thread.currentThread().getContextClassLoader() != null + ? Thread.currentThread().getContextClassLoader() + : getClass().getClassLoader()); + Thread.currentThread().setContextClassLoader(dynamicTableClassLoader); + } + + /** + * 注册类 + * @param className name + * @param clazz class + */ + public void registerClass(String className, Class clazz) { + dynamicTableClassLoader.registerClass(className, clazz); + } + + /** + * 注册类 + * @param clazz class + */ + public void registerClass(Class clazz) { + dynamicTableClassLoader.registerClass(clazz); + } + + /** + * 获取类 + * @param name className + * @return class + */ + public Class findClass(String name) throws ClassNotFoundException { + return dynamicTableClassLoader.findClass(name); + } + + /** + * 加载类 + * @param name className + * @param resolve resolve + * @return class + */ + public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + return dynamicTableClassLoader.loadClass(name, resolve); + } + + /** + * 清空动态类 + * @param name 类名称 + */ + public void cleanDynamicClass(String name) { + dynamicTableClassLoader.cleanClass(name); + } + + /** + * 获取全部的动态类 + */ + public Collection> getDynamicClasses(){ + return dynamicTableClassLoader.getDynamicClasses(); + } + + /** + * 获取全部动态类的名称 + */ + public Set getDynamicClassNames(){ + return dynamicTableClassLoader.getDynamicClassNames(); + } + + + /** + * $DynamicTableClassLoader + */ + private static class $DynamicTableClassLoader extends ClassLoader { + + private final Map> dynamicClasses = new ConcurrentHashMap<>(); + + public $DynamicTableClassLoader(ClassLoader parent) { + super(parent); + } + + public void registerClass(String className, Class clazz) { + dynamicClasses.put(className, clazz); + } + + public void registerClass(Class clazz) { + this.registerClass(clazz.getName(), clazz); + } + + public void cleanClass(String className) { + this.dynamicClasses.remove(className); + } + + public Collection> getDynamicClasses(){ + return dynamicClasses.values(); + } + + public Set getDynamicClassNames(){ + return dynamicClasses.keySet(); + } + + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + // 首先检查已加载的动态类 + if (dynamicClasses.containsKey(name)) { + return dynamicClasses.get(name); + } + // 委托给父类 + return super.findClass(name); + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + return loadClass(name, false); + } + + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + synchronized (getClassLoadingLock(name)) { + // 首先检查是否已经加载 + Class c = findLoadedClass(name); + if (c == null) { + // 检查是否是动态类 + if (dynamicClasses.containsKey(name)) { + c = dynamicClasses.get(name); + } else { + // 委托给父类 + c = super.loadClass(name, resolve); + } + } + + if (resolve) { + resolveClass(c); + } + return c; + } + } + + } + + +} diff --git a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/dynamic/DynamicEntityBuilder.java b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/generator/DynamicTableGenerator.java similarity index 72% rename from springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/dynamic/DynamicEntityBuilder.java rename to springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/generator/DynamicTableGenerator.java index 5a153b80..a4a26b97 100644 --- a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/dynamic/DynamicEntityBuilder.java +++ b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/generator/DynamicTableGenerator.java @@ -1,4 +1,4 @@ -package com.codingapi.springboot.fast.dynamic; +package com.codingapi.springboot.fast.generator; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; @@ -15,17 +15,23 @@ import java.util.*; -public class DynamicEntityBuilder { +/** + * DynamicTableGenerator 数据库表动态构建器 + */ +public class DynamicTableGenerator { + /** + * 数据库方言 + */ private final Dialect dialect; private final StandardServiceRegistry serviceRegistry; private final SchemaManagementTool managementTool; - public DynamicEntityBuilder(Class dialectClass, String jdbcUrl) { + public DynamicTableGenerator(Class dialectClass, String jdbcUrl) { this(dialectClass,jdbcUrl,null,null); } - public DynamicEntityBuilder(Class dialectClass, String jdbcUrl, String username, String password) { + public DynamicTableGenerator(Class dialectClass, String jdbcUrl, String username, String password) { try { this.dialect = (Dialect) dialectClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { @@ -87,10 +93,20 @@ public ScriptSourceInput getScriptSourceInput() { private static class TargetDescriptorImpl implements TargetDescriptor { private final List sqlCommands = new ArrayList<>(); + private final boolean executable; + + public TargetDescriptorImpl(boolean executable) { + this.executable = executable; + } @Override public EnumSet getTargetTypes() { - return EnumSet.of(TargetType.SCRIPT); + EnumSet targetTypes = EnumSet.of(TargetType.SCRIPT); + if(executable) { + // 在数据库中执行 + targetTypes.add(TargetType.DATABASE); + } + return targetTypes; } @Override @@ -118,11 +134,26 @@ public String getDDL() { } } + /** + * 创建删除DDL语句 + * @param entityClass entity class对象 + * @return DDL + */ public String generateDropTableDDL(Class entityClass) { + return this.generateDropTableDDL(entityClass,false); + } + + /** + * 创建删除DDL语句 + * @param entityClass entity class对象 + * @param executable 是否数据中执行 + * @return DDL + */ + public String generateDropTableDDL(Class entityClass,boolean executable) { MetadataSources metadataSources = new MetadataSources(serviceRegistry); metadataSources.addAnnotatedClass(entityClass); Metadata metadata = metadataSources.buildMetadata(); - TargetDescriptorImpl targetDescriptor = new TargetDescriptorImpl(); + TargetDescriptorImpl targetDescriptor = new TargetDescriptorImpl(executable); managementTool.getSchemaDropper(Collections.emptyMap()).doDrop(metadata, new ExecutionOptionsImpl(), @@ -133,12 +164,27 @@ public String generateDropTableDDL(Class entityClass) { return targetDescriptor.getDDL(); } + /** + * 创建创建DDL语句 + * @param entityClass entity class对象 + * @return DDL + */ public String generateCreateTableDDL(Class entityClass) { + return this.generateCreateTableDDL(entityClass,false); + } + + /** + * 创建创建DDL语句 + * @param entityClass entity class对象 + * @param executable 是否数据中执行 + * @return DDL + */ + public String generateCreateTableDDL(Class entityClass,boolean executable) { MetadataSources metadataSources = new MetadataSources(serviceRegistry); metadataSources.addAnnotatedClass(entityClass); Metadata metadata = metadataSources.buildMetadata(); - TargetDescriptorImpl targetDescriptor = new TargetDescriptorImpl(); + TargetDescriptorImpl targetDescriptor = new TargetDescriptorImpl(executable); managementTool.getSchemaCreator(Collections.emptyMap()).doCreation(metadata, new ExecutionOptionsImpl(), @@ -148,12 +194,27 @@ public String generateCreateTableDDL(Class entityClass) { return targetDescriptor.getDDL(); } + /** + * 创建变更DDL语句,当数据不存在时则为创建,当数据中的表对象与entityClass不一致时则创建调整DDL + * @param entityClass entity class对象 + * @return DDL + */ public String generateMigratorTableDDL(Class entityClass) { + return this.generateMigratorTableDDL(entityClass,false); + } + + /** + * 创建变更DDL语句,当数据不存在时则为创建,当数据中的表对象与entityClass不一致时则创建调整DDL + * @param entityClass entity class对象 + * @param executable 是否数据中执行 + * @return DDL + */ + public String generateMigratorTableDDL(Class entityClass,boolean executable) { MetadataSources metadataSources = new MetadataSources(serviceRegistry); metadataSources.addAnnotatedClass(entityClass); Metadata metadata = metadataSources.buildMetadata(); - TargetDescriptorImpl targetDescriptor = new TargetDescriptorImpl(); + TargetDescriptorImpl targetDescriptor = new TargetDescriptorImpl(executable); managementTool.getSchemaMigrator(Collections.emptyMap()).doMigration(metadata, new ExecutionOptionsImpl(), @@ -162,6 +223,11 @@ public String generateMigratorTableDDL(Class entityClass) { return targetDescriptor.getDDL(); } + /** + * 检验对象与数据库是否一致,一致时无异常信息 + * @param entityClass entity class对象 + * @return 异常列表 + */ public List validatorTable(Class entityClass) { ExceptionHandlerCollectingImpl exceptionHandler = new ExceptionHandlerCollectingImpl(); MetadataSources metadataSources = new MetadataSources(serviceRegistry); diff --git a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/EntityMetaData.java b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/EntityMetaData.java deleted file mode 100644 index 171f405c..00000000 --- a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/EntityMetaData.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.codingapi.springboot.fast.metadata; - -import com.codingapi.springboot.fast.classloader.DynamicEntityClassBuilder; -import jakarta.persistence.GenerationType; -import lombok.Getter; -import lombok.Setter; - -import java.util.ArrayList; -import java.util.List; - -@Getter -public class EntityMetaData { - - private final String className; - private final TableMeta table; - private final List columns; - - public EntityMetaData(String className) { - this.className = className; - this.table = new TableMeta(); - this.columns = new ArrayList<>(); - } - - public void setTable(String name,String catalog,String schema,String comment){ - this.table.setName(name); - this.table.setCatalog(catalog); - this.table.setSchema(schema); - this.table.setComment(comment); - } - - public void setTable(String name,String comment){ - this.setTable(name,null,null,comment); - } - - public void setTable(String name){ - this.setTable(name,null,null,null); - } - - public void addPrimaryKeyColumn(Class type,String name,GenerationType strategy,String generator,String comment,boolean unique,boolean nullable, boolean insertable, - boolean updatable,String columnDefinition, int length,int precision,int scale){ - ColumnMeta column = new ColumnMeta(); - column.setType(type); - column.setName(name); - column.setPrimaryKey(true); - GeneratedValueMeta generatedValueMeta = new GeneratedValueMeta(); - generatedValueMeta.setGenerator(generator); - generatedValueMeta.setStrategy(strategy); - column.setGeneratedValue(generatedValueMeta); - column.setComment(comment); - column.setUnique(unique); - column.setNullable(nullable); - column.setInsertable(insertable); - column.setUpdatable(updatable); - column.setColumnDefinition(columnDefinition); - column.setLength(length); - column.setPrecision(precision); - column.setScale(scale); - this.columns.add(column); - } - - public void addColumn(Class type,String name,String comment,boolean unique,boolean nullable, boolean insertable, - boolean updatable,String columnDefinition, int length,int precision,int scale){ - ColumnMeta column = new ColumnMeta(); - column.setPrimaryKey(false); - column.setType(type); - column.setName(name); - column.setComment(comment); - column.setUnique(unique); - column.setNullable(nullable); - column.setInsertable(insertable); - column.setUpdatable(updatable); - column.setColumnDefinition(columnDefinition); - column.setLength(length); - column.setPrecision(precision); - column.setScale(scale); - this.columns.add(column); - } - - public void addColumn(Class type,String name,String comment){ - this.addColumn(type,name,comment,false,false,false,false,null,255,0,0); - } - - public void addColumn(Class type,String name){ - this.addColumn(type,name,null,false,false,false,false,null,255,0,0); - } - - public void addPrimaryKeyColumn(Class type,String name,GenerationType strategy){ - this.addPrimaryKeyColumn(type,name,strategy,null,null,false,false,false,false,null,255,0,0); - } - - public void addPrimaryKeyColumn(Class type,String name,GenerationType strategy,String comment){ - this.addPrimaryKeyColumn(type,name,strategy,null,comment,false,false,false,false,null,255,0,0); - } - - public Class buildClass(){ - return DynamicEntityClassBuilder.buildDynamicEntity(this); - } - - @Setter - @Getter - public static class TableMeta{ - private String name; - private String catalog; - private String schema; - private String comment; - } - - @Setter - @Getter - public static class ColumnMeta{ - private Class type; - private String name; - private boolean isPrimaryKey; - private GeneratedValueMeta generatedValue; - private String comment; - private boolean unique; - private boolean nullable; - private boolean insertable; - private boolean updatable; - private String columnDefinition; - private int length; - private int precision; - private int scale; - } - - @Setter - @Getter - public static class GeneratedValueMeta{ - private GenerationType strategy; - private String generator; - } - -} diff --git a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassBuilder.java b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/TableEntityClassBuilder.java similarity index 50% rename from springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassBuilder.java rename to springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/TableEntityClassBuilder.java index 94ed83f2..2193e897 100644 --- a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/classloader/DynamicEntityClassBuilder.java +++ b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/TableEntityClassBuilder.java @@ -1,6 +1,6 @@ -package com.codingapi.springboot.fast.classloader; +package com.codingapi.springboot.fast.metadata; -import com.codingapi.springboot.fast.metadata.EntityMetaData; +import com.codingapi.springboot.fast.classloader.DynamicTableClassLoader; import jakarta.persistence.*; import net.bytebuddy.ByteBuddy; import net.bytebuddy.description.annotation.AnnotationDescription; @@ -16,70 +16,64 @@ import java.util.List; /** - * 动态实体构建器 - 基于 EntityClass 元数据 + * 动态实体构建器 - 基于 TableEntityMetadata 元数据 */ -public class DynamicEntityClassBuilder { +class TableEntityClassBuilder { - /** - * 根据 EntityClass 构建动态实体 - */ - public static Class buildDynamicEntity(EntityMetaData entityMetaData) { - if (entityMetaData == null || entityMetaData.getClassName() == null) { + private final TableEntityMetadata metadata; + private DynamicType.Builder builder; + + public TableEntityClassBuilder(TableEntityMetadata metadata) { + if (metadata == null || metadata.getClassName() == null) { throw new IllegalArgumentException("Entity metadata cannot be null"); } + this.metadata = metadata; + this.builder = new ByteBuddy() + .subclass(Object.class) + .name(metadata.getClassName()) + .implement(Serializable.class) + .annotateType(buildEntityAnnotations()); + } + public Class build() { try { - DynamicType.Builder builder = new ByteBuddy() - .subclass(Object.class) - .name(entityMetaData.getClassName()) - .implement(Serializable.class) - .annotateType(buildEntityAnnotations(entityMetaData)); - - // 添加字段 - boolean hasPrimaryKey = false; - for (EntityMetaData.ColumnMeta column : entityMetaData.getColumns()) { - builder = addColumnField(builder, column); - if (column.isPrimaryKey()) { - hasPrimaryKey = true; - } - } - - // 如果没有主键,添加默认ID字段 - if (!hasPrimaryKey) { - builder = addDefaultIdField(builder); - } - - + this.buildColumns(); Class clazz = builder.make() - .load(DynamicEntityClassBuilder.class.getClassLoader(), + .load(TableEntityClassBuilder.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); - - DynamicEntityClassLoaderContext.getInstance().registerClass(clazz); - + DynamicTableClassLoader.getInstance().registerClass(clazz); return clazz; } catch (Exception e) { throw new RuntimeException("Failed to build dynamic entity: " + - entityMetaData.getClassName(), e); + metadata.getClassName(), e); } } + + private void buildColumns() { + for (TableEntityMetadata.ColumnMeta column : metadata.getColumns()) { + this.addColumnField(column); + } + } + + /** * 构建实体类注解 */ - private static AnnotationDescription[] buildEntityAnnotations(EntityMetaData entityMetaData) { + private AnnotationDescription[] buildEntityAnnotations() { List annotations = new ArrayList<>(); // @Entity 注解 annotations.add(AnnotationDescription.Builder.ofType(Entity.class).build()); // @Table 注解 - if (entityMetaData.getTable() != null) { + if (metadata.getTable() != null) { AnnotationDescription.Builder tableBuilder = AnnotationDescription.Builder.ofType(Table.class); - EntityMetaData.TableMeta tableMeta = entityMetaData.getTable(); + TableEntityMetadata.TableMeta tableMeta = metadata.getTable(); if (tableMeta.getName() != null && !tableMeta.getName().isEmpty()) { tableBuilder = tableBuilder.define("name", tableMeta.getName()); } @@ -94,11 +88,11 @@ private static AnnotationDescription[] buildEntityAnnotations(EntityMetaData ent } // @Comment 注解 - 注释应该放在类上,而不是表注解上 - if (entityMetaData.getTable() != null && StringUtils.hasText(entityMetaData.getTable().getComment())) { + if (metadata.getTable() != null && StringUtils.hasText(metadata.getTable().getComment())) { AnnotationDescription.Builder commentBuilder = AnnotationDescription.Builder.ofType(Comment.class); - EntityMetaData.TableMeta tableMeta = entityMetaData.getTable(); + TableEntityMetadata.TableMeta tableMeta = metadata.getTable(); commentBuilder = commentBuilder.define("value", tableMeta.getComment()); annotations.add(commentBuilder.build()); } @@ -109,28 +103,20 @@ private static AnnotationDescription[] buildEntityAnnotations(EntityMetaData ent /** * 添加字段 */ - private static DynamicType.Builder addColumnField(DynamicType.Builder builder, - EntityMetaData.ColumnMeta columnMeta) { + private void addColumnField(TableEntityMetadata.ColumnMeta columnMeta) { // 确定字段类型 Class fieldType = columnMeta.getType(); - // 构建字段名(转换驼峰命名) - String fieldName = convertToCamelCase(columnMeta.getName()); - - + // 构建字段名 + String fieldName = columnMeta.getFieldName(); // 构建字段注解 - List fieldAnnotations = - buildFieldAnnotations(columnMeta, fieldName); - - // 开始定义字段 - DynamicType.Builder fieldBuilder = builder; - + List fieldAnnotations = this.buildFieldAnnotations(columnMeta); if (fieldAnnotations.isEmpty()) { - fieldBuilder = fieldBuilder.defineField(fieldName, fieldType, Visibility.PRIVATE); - }else { - fieldBuilder = fieldBuilder.defineField(fieldName, fieldType, Visibility.PRIVATE) + builder = builder.defineField(fieldName, fieldType, Visibility.PRIVATE); + } else { + builder = builder.defineField(fieldName, fieldType, Visibility.PRIVATE) .annotateField(fieldAnnotations.toArray(new AnnotationDescription[0])); } @@ -144,24 +130,20 @@ private static DynamicType.Builder addColumnField(DynamicType.Builder buil getterName = "is" + capitalizedFieldName; } - fieldBuilder = fieldBuilder - .defineMethod(getterName, fieldType, Visibility.PUBLIC) + builder = builder.defineMethod(getterName, fieldType, Visibility.PUBLIC) .intercept(FieldAccessor.ofField(fieldName)); - fieldBuilder = fieldBuilder - .defineMethod(setterName, void.class, Visibility.PUBLIC) + builder = builder.defineMethod(setterName, void.class, Visibility.PUBLIC) .withParameter(fieldType) .intercept(FieldAccessor.ofField(fieldName)); - return fieldBuilder; } /** * 构建字段注解 */ - private static List buildFieldAnnotations( - EntityMetaData.ColumnMeta columnMeta, String fieldName) { - + private List buildFieldAnnotations( + TableEntityMetadata.ColumnMeta columnMeta) { List annotations = new ArrayList<>(); // @Id 注解 @@ -170,7 +152,7 @@ private static List buildFieldAnnotations( // @GeneratedValue 注解 if (columnMeta.getGeneratedValue() != null) { - EntityMetaData.GeneratedValueMeta genMeta = columnMeta.getGeneratedValue(); + TableEntityMetadata.GeneratedValueMeta genMeta = columnMeta.getGeneratedValue(); AnnotationDescription.Builder genBuilder = AnnotationDescription.Builder.ofType(GeneratedValue.class); @@ -191,7 +173,7 @@ private static List buildFieldAnnotations( AnnotationDescription.Builder.ofType(Column.class); columnBuilder = columnBuilder - .define("name", columnMeta.getName()) + .define("name", columnMeta.getColumnName()) .define("nullable", columnMeta.isNullable()) .define("unique", columnMeta.isUnique()) .define("insertable", columnMeta.isInsertable()) @@ -224,76 +206,8 @@ private static List buildFieldAnnotations( return annotations; } - /** - * 添加默认ID字段 - 修正版本 - */ - private static DynamicType.Builder addDefaultIdField(DynamicType.Builder builder) { - - - // 创建字段注解 - List fieldAnnotations = new ArrayList<>(); - fieldAnnotations.add(AnnotationDescription.Builder.ofType(Id.class).build()); - - // @GeneratedValue 注解 - AnnotationDescription.Builder genBuilder = - AnnotationDescription.Builder.ofType(GeneratedValue.class); - genBuilder = genBuilder.define("strategy", GenerationType.IDENTITY); - fieldAnnotations.add(genBuilder.build()); - - // @Column 注解 - AnnotationDescription.Builder columnBuilder = - AnnotationDescription.Builder.ofType(Column.class); - columnBuilder = columnBuilder - .define("name", "id") - .define("nullable", false); - fieldAnnotations.add(columnBuilder.build()); - - // 应用字段注解 - builder = builder.defineField("id", Long.class, Visibility.PRIVATE).annotateField(fieldAnnotations.toArray(new AnnotationDescription[0])); - - // 添加 getter 和 setter - builder = builder - .defineMethod("getId", Long.class, Visibility.PUBLIC) - .intercept(FieldAccessor.ofField("id")) - .defineMethod("setId", void.class, Visibility.PUBLIC) - .withParameter(Long.class) - .intercept(FieldAccessor.ofField("id")); - - return builder; - } - - /** - * 转换为驼峰命名 - */ - private static String convertToCamelCase(String name) { - if (name == null || name.isEmpty()) { - return name; - } - - // 处理下划线命名 - if (name.contains("_")) { - StringBuilder result = new StringBuilder(); - String[] parts = name.split("_"); - if (parts.length > 0) { - result.append(parts[0].toLowerCase()); - - for (int i = 1; i < parts.length; i++) { - if (!parts[i].isEmpty()) { - result.append(Character.toUpperCase(parts[i].charAt(0))); - if (parts[i].length() > 1) { - result.append(parts[i].substring(1).toLowerCase()); - } - } - } - } - return result.toString(); - } - - // 已经是驼峰命名,首字母小写 - return Character.toLowerCase(name.charAt(0)) + name.substring(1); - } - private static String capitalize(String str) { + private String capitalize(String str) { if (str == null || str.isEmpty()) { return str; } diff --git a/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/TableEntityMetadata.java b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/TableEntityMetadata.java new file mode 100644 index 00000000..017e3aa0 --- /dev/null +++ b/springboot-starter-data-fast/src/main/java/com/codingapi/springboot/fast/metadata/TableEntityMetadata.java @@ -0,0 +1,228 @@ +package com.codingapi.springboot.fast.metadata; + +import jakarta.persistence.GenerationType; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +/** + * 表实体元数据 + */ +@Getter +public class TableEntityMetadata { + + /** + * 类名称 + */ + private final String className; + /** + * 数据库表信息 + */ + private final TableMeta table; + /** + * 字段信息 + */ + private final List columns; + + @Setter + @Getter + public static class TableMeta { + /** + * 数据库名称 + */ + private String name; + private String catalog; + private String schema; + /** + * 备注信息 + */ + private String comment; + } + + @Setter + @Getter + public static class ColumnMeta { + /** + * 字段类型 + */ + private Class type; + /** + * 表字段名称 + */ + private String columnName; + /** + * 类字段名称 + */ + private String fieldName; + /** + * 是否主键 + */ + private boolean isPrimaryKey; + /** + * 主键自增策略 + */ + private GeneratedValueMeta generatedValue; + /** + * 备注 + */ + private String comment; + /** + * 是否唯一 + */ + private boolean unique; + /** + * 是否为空 + */ + private boolean nullable; + /** + * 是否可以插入数据 + */ + private boolean insertable; + /** + * 是否可以更新数据 + */ + private boolean updatable; + /** + * 字段定义 + */ + private String columnDefinition; + /** + * 字段长度 + */ + private int length; + private int precision; + private int scale; + } + + @Setter + @Getter + public static class GeneratedValueMeta { + /** + * 自增长策略 + */ + private GenerationType strategy; + /** + * 自定义 + */ + private String generator; + } + + + /** + * 类名称 + * + * @param className 类名称 + */ + public TableEntityMetadata(String className) { + this.className = className; + this.table = new TableMeta(); + this.columns = new ArrayList<>(); + } + + + public void setTable(String name, String catalog, String schema, String comment) { + this.table.setName(name); + this.table.setCatalog(catalog); + this.table.setSchema(schema); + this.table.setComment(comment); + } + + public void setTable(String name, String comment) { + this.setTable(name, null, null, comment); + } + + public void setTable(String name) { + this.setTable(name, null, null, null); + } + + public void addPrimaryKeyColumn(Class type, String fieldName, String columnName, GenerationType strategy, + String generator, String comment, boolean unique, boolean nullable, + boolean insertable, boolean updatable, String columnDefinition, + int length, int precision, int scale) { + ColumnMeta column = new ColumnMeta(); + column.setType(type); + column.setFieldName(fieldName); + column.setColumnName(columnName); + column.setPrimaryKey(true); + GeneratedValueMeta generatedValueMeta = new GeneratedValueMeta(); + generatedValueMeta.setGenerator(generator); + generatedValueMeta.setStrategy(strategy); + column.setGeneratedValue(generatedValueMeta); + column.setComment(comment); + column.setUnique(unique); + column.setNullable(nullable); + column.setInsertable(insertable); + column.setUpdatable(updatable); + column.setColumnDefinition(columnDefinition); + column.setLength(length); + column.setPrecision(precision); + column.setScale(scale); + this.columns.add(column); + } + + public void addColumn(Class type, String fieldName, String columnName, String comment, + boolean unique, boolean nullable, boolean insertable, + boolean updatable, String columnDefinition, int length, + int precision, int scale) { + ColumnMeta column = new ColumnMeta(); + column.setPrimaryKey(false); + column.setType(type); + column.setFieldName(fieldName); + column.setColumnName(columnName); + column.setComment(comment); + column.setUnique(unique); + column.setNullable(nullable); + column.setInsertable(insertable); + column.setUpdatable(updatable); + column.setColumnDefinition(columnDefinition); + column.setLength(length); + column.setPrecision(precision); + column.setScale(scale); + this.columns.add(column); + } + + public void addColumn(Class type, String name, String comment) { + this.addColumn(type, name, name, comment, false, false, false, false, null, 255, 0, 0); + } + + public void addColumn(Class type, String name) { + this.addColumn(type, name, name, null, false, false, false, false, null, 255, 0, 0); + } + + public void addPrimaryKeyColumn(Class type, String name) { + this.addPrimaryKeyColumn(type, name, name, null, null, null, false, false, false, false, null, 255, 0, 0); + } + + public void addPrimaryKeyColumn(Class type, String name, GenerationType strategy) { + this.addPrimaryKeyColumn(type, name, name, strategy, null, null, false, false, false, false, null, 255, 0, 0); + } + + public void addPrimaryKeyColumn(Class type, String name, GenerationType strategy, String comment) { + this.addPrimaryKeyColumn(type, name, name, strategy, null, comment, false, false, false, false, null, 255, 0, 0); + } + + public void verify() { + if (columns.isEmpty()) { + throw new IllegalArgumentException("columns must not null."); + } + boolean hasPrimaryKey = false; + for (ColumnMeta column : columns) { + if (column.isPrimaryKey) { + hasPrimaryKey = true; + } + } + if (!hasPrimaryKey) { + throw new IllegalArgumentException("columns must has primaryKey."); + } + } + + public Class buildClass() { + this.verify(); + TableEntityClassBuilder builder = new TableEntityClassBuilder(this); + return builder.build(); + } + + +} diff --git a/springboot-starter-data-fast/src/test/java/com/codingapi/springboot/fast/dynamic/DynamicEntityBuilderTest.java b/springboot-starter-data-fast/src/test/java/com/codingapi/springboot/fast/dynamic/DynamicEntityBuilderTest.java deleted file mode 100644 index 16aa4ded..00000000 --- a/springboot-starter-data-fast/src/test/java/com/codingapi/springboot/fast/dynamic/DynamicEntityBuilderTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.codingapi.springboot.fast.dynamic; - -import com.codingapi.springboot.fast.entity.Demo; -import com.codingapi.springboot.fast.metadata.EntityMetaData; -import jakarta.persistence.GenerationType; -import org.hibernate.dialect.H2Dialect; -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -class DynamicEntityBuilderTest { - - @Test - void generateTableDDL() { - DynamicEntityBuilder dynamicEntityBuilder = new DynamicEntityBuilder(H2Dialect.class,"jdbc:h2:file:./test.db"); - List exceptions = dynamicEntityBuilder.validatorTable(Demo.class); - System.out.println(exceptions); - - String createDDL = dynamicEntityBuilder.generateCreateTableDDL(Demo.class); - System.out.println("createDDL:\n" + createDDL); - assertNotNull(createDDL); - - String dropDDL = dynamicEntityBuilder.generateDropTableDDL(Demo.class); - System.out.println("dropDDL:\n" + dropDDL); - assertNotNull(dropDDL); - - String migrateDDL = dynamicEntityBuilder.generateMigratorTableDDL(Demo.class); - System.out.println("migrateDDL:\n" + migrateDDL); - assertNotNull(migrateDDL); - } - - @Test - void dynamicGenerateTableDDL() { - DynamicEntityBuilder dynamicEntityBuilder = new DynamicEntityBuilder(H2Dialect.class,"jdbc:h2:file:./test.db"); - - EntityMetaData entityMetaData = new EntityMetaData("com.codingapi.entity.Test"); - entityMetaData.setTable("test"); - entityMetaData.addPrimaryKeyColumn(Long.class,"id", GenerationType.IDENTITY,"主键"); - entityMetaData.addColumn(String.class,"name","姓名"); - - Class entityClass = entityMetaData.buildClass(); - - List exceptions = dynamicEntityBuilder.validatorTable(entityClass); - System.out.println(exceptions); - assertFalse(exceptions.isEmpty()); - - String createDDL = dynamicEntityBuilder.generateCreateTableDDL(entityClass); - System.out.println("createDDL:\n" + createDDL); - assertNotNull(createDDL); - - String dropDDL = dynamicEntityBuilder.generateDropTableDDL(entityClass); - System.out.println("dropDDL:\n" + dropDDL); - assertNotNull(dropDDL); - - String migrateDDL = dynamicEntityBuilder.generateMigratorTableDDL(entityClass); - System.out.println("migrateDDL:\n" + migrateDDL); - assertNotNull(migrateDDL); - - } -} \ No newline at end of file diff --git a/springboot-starter-data-fast/src/test/java/com/codingapi/springboot/fast/generator/DynamicTableGeneratorTest.java b/springboot-starter-data-fast/src/test/java/com/codingapi/springboot/fast/generator/DynamicTableGeneratorTest.java new file mode 100644 index 00000000..87b1ed63 --- /dev/null +++ b/springboot-starter-data-fast/src/test/java/com/codingapi/springboot/fast/generator/DynamicTableGeneratorTest.java @@ -0,0 +1,61 @@ +package com.codingapi.springboot.fast.generator; + +import com.codingapi.springboot.fast.entity.Demo; +import com.codingapi.springboot.fast.metadata.TableEntityMetadata; +import jakarta.persistence.GenerationType; +import org.hibernate.dialect.H2Dialect; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class DynamicTableGeneratorTest { + + @Test + void generateTableDDL() { + DynamicTableGenerator dynamicTableGenerator = new DynamicTableGenerator(H2Dialect.class,"jdbc:h2:file:./test.db"); + List exceptions = dynamicTableGenerator.validatorTable(Demo.class); + System.out.println(exceptions); + + String createDDL = dynamicTableGenerator.generateCreateTableDDL(Demo.class); + System.out.println("createDDL:\n" + createDDL); + assertNotNull(createDDL); + + String dropDDL = dynamicTableGenerator.generateDropTableDDL(Demo.class); + System.out.println("dropDDL:\n" + dropDDL); + assertNotNull(dropDDL); + + String migrateDDL = dynamicTableGenerator.generateMigratorTableDDL(Demo.class); + System.out.println("migrateDDL:\n" + migrateDDL); + assertNotNull(migrateDDL); + } + + @Test + void dynamicGenerateTableDDL() { + DynamicTableGenerator dynamicTableGenerator = new DynamicTableGenerator(H2Dialect.class,"jdbc:h2:file:./test.db"); + + TableEntityMetadata tableEntityMetadata = new TableEntityMetadata("com.codingapi.entity.Test"); + tableEntityMetadata.setTable("test"); + tableEntityMetadata.addPrimaryKeyColumn(Long.class,"id", GenerationType.IDENTITY,"主键"); + tableEntityMetadata.addColumn(String.class,"name","姓名"); + + Class entityClass = tableEntityMetadata.buildClass(); + + List exceptions = dynamicTableGenerator.validatorTable(entityClass); + System.out.println(exceptions); + + String createDDL = dynamicTableGenerator.generateCreateTableDDL(entityClass); + System.out.println("createDDL:\n" + createDDL); + assertNotNull(createDDL); + + String dropDDL = dynamicTableGenerator.generateDropTableDDL(entityClass); + System.out.println("dropDDL:\n" + dropDDL); + assertNotNull(dropDDL); + + String migrateDDL = dynamicTableGenerator.generateMigratorTableDDL(entityClass); + System.out.println("migrateDDL:\n" + migrateDDL); + assertNotNull(migrateDDL); + + } +} \ No newline at end of file diff --git a/springboot-starter-flow/pom.xml b/springboot-starter-flow/pom.xml index 4d13e158..c1be9a18 100644 --- a/springboot-starter-flow/pom.xml +++ b/springboot-starter-flow/pom.xml @@ -6,7 +6,7 @@ springboot-parent com.codingapi.springboot - 3.4.24 + 3.4.25 springboot-starter-flow diff --git a/springboot-starter-security/pom.xml b/springboot-starter-security/pom.xml index 6dd3c797..f6cbc722 100644 --- a/springboot-starter-security/pom.xml +++ b/springboot-starter-security/pom.xml @@ -6,7 +6,7 @@ springboot-parent com.codingapi.springboot - 3.4.24 + 3.4.25 springboot-starter-security diff --git a/springboot-starter/pom.xml b/springboot-starter/pom.xml index d6b970d1..0a327316 100644 --- a/springboot-starter/pom.xml +++ b/springboot-starter/pom.xml @@ -5,7 +5,7 @@ com.codingapi.springboot springboot-parent - 3.4.24 + 3.4.25 springboot-starter