From 9b5b2925ca63cadc79ea7f7306eb28d25044391c Mon Sep 17 00:00:00 2001
From: xlorne <1991wangliang@gmail.com>
Date: Mon, 25 Dec 2023 09:09:55 +0800
Subject: [PATCH 01/29] add persistence module
---
pom.xml | 3 +
springboot-starter-persistence/pom.xml | 34 +++++
.../persistence/AutoConfiguration.java | 17 +++
.../persistence/DomainPersistence.java | 9 ++
.../jdbc/JdbcAutoConfiguration.java | 29 ++++
.../jdbc/JdbcDomainPersistence.java | 60 ++++++++
.../persistence/jdbc/JdbcSchemaExecutor.java | 22 +++
.../persistence/jdbc/JdbcSchemaFactory.java | 14 ++
.../jdbc/schema/JdbcBuildSchema.java | 35 +++++
.../jdbc/schema/JdbcSaveSchema.java | 34 +++++
.../persistence/jdbc/schema/JdbcSchema.java | 28 ++++
.../jdbc/schema/JdbcSearchSchema.java | 18 +++
.../register/DomainClassRegister.java | 29 ++++
.../persistence/scanner/SchemaContext.java | 30 ++++
.../persistence/scanner/SchemaScanner.java | 35 +++++
.../persistence/schema/BuildSchema.java | 12 ++
.../persistence/schema/Property.java | 141 ++++++++++++++++++
.../persistence/schema/SaveSchema.java | 35 +++++
.../springboot/persistence/schema/Schema.java | 33 ++++
.../persistence/schema/SchemaExecutor.java | 7 +
.../persistence/schema/SchemaFactory.java | 6 +
.../persistence/schema/SchemaProperty.java | 49 ++++++
.../persistence/schema/SearchSchema.java | 20 +++
.../main/resources/META-INF/spring.factories | 3 +
...ot.autoconfigure.AutoConfiguration.imports | 2 +
.../example/demo/PersistenceApplication.java | 12 ++
.../java/com/example/demo/domain/Demo.java | 12 ++
.../example/demo/register/DomainRegister.java | 15 ++
.../demo/repository/DemoRepository.java | 24 +++
.../demo/repository/DemoRepositoryTests.java | 41 +++++
.../src/test/resources/application.properties | 1 +
31 files changed, 810 insertions(+)
create mode 100644 springboot-starter-persistence/pom.xml
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/AutoConfiguration.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/DomainPersistence.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcAutoConfiguration.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcDomainPersistence.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcSchemaExecutor.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcSchemaFactory.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcBuildSchema.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSaveSchema.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSchema.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSearchSchema.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/register/DomainClassRegister.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/scanner/SchemaContext.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/scanner/SchemaScanner.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/BuildSchema.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/Property.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/SaveSchema.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/Schema.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/SchemaExecutor.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/SchemaFactory.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/SchemaProperty.java
create mode 100644 springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/SearchSchema.java
create mode 100644 springboot-starter-persistence/src/main/resources/META-INF/spring.factories
create mode 100644 springboot-starter-persistence/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
create mode 100644 springboot-starter-persistence/src/test/java/com/example/demo/PersistenceApplication.java
create mode 100644 springboot-starter-persistence/src/test/java/com/example/demo/domain/Demo.java
create mode 100644 springboot-starter-persistence/src/test/java/com/example/demo/register/DomainRegister.java
create mode 100644 springboot-starter-persistence/src/test/java/com/example/demo/repository/DemoRepository.java
create mode 100644 springboot-starter-persistence/src/test/java/com/example/demo/repository/DemoRepositoryTests.java
create mode 100644 springboot-starter-persistence/src/test/resources/application.properties
diff --git a/pom.xml b/pom.xml
index a4dd64e2..c71d1447 100644
--- a/pom.xml
+++ b/pom.xml
@@ -220,6 +220,7 @@
springboot-starter-security-jwt
springboot-starter-data-fast
springboot-starter-id-generator
+ springboot-starter-persistence
@@ -232,6 +233,7 @@
springboot-starter-security-jwt
springboot-starter-data-fast
springboot-starter-id-generator
+ springboot-starter-persistence
@@ -282,6 +284,7 @@
springboot-starter-security-jwt
springboot-starter-data-fast
springboot-starter-id-generator
+ springboot-starter-persistence
diff --git a/springboot-starter-persistence/pom.xml b/springboot-starter-persistence/pom.xml
new file mode 100644
index 00000000..d4b08d2d
--- /dev/null
+++ b/springboot-starter-persistence/pom.xml
@@ -0,0 +1,34 @@
+
+
+
+ springboot-parent
+ com.codingapi.springboot
+ 3.1.6
+
+ 4.0.0
+
+ springboot-starter-persistence
+
+
+ 17
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+ provided
+
+
+
+ com.h2database
+ h2
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/AutoConfiguration.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/AutoConfiguration.java
new file mode 100644
index 00000000..45f492b6
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/AutoConfiguration.java
@@ -0,0 +1,17 @@
+package com.codingapi.springboot.persistence;
+
+import com.codingapi.springboot.persistence.scanner.SchemaScanner;
+import com.codingapi.springboot.persistence.schema.SchemaExecutor;
+import com.codingapi.springboot.persistence.schema.SchemaFactory;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.context.annotation.Bean;
+
+@Configurable
+public class AutoConfiguration {
+
+ @Bean
+ public SchemaScanner domainScanner(SchemaExecutor schemaExecutor, SchemaFactory schemaFactory) {
+ return new SchemaScanner(schemaExecutor, schemaFactory);
+ }
+
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/DomainPersistence.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/DomainPersistence.java
new file mode 100644
index 00000000..1fa6c8b0
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/DomainPersistence.java
@@ -0,0 +1,9 @@
+package com.codingapi.springboot.persistence;
+
+public interface DomainPersistence {
+
+ void save(Object domain);
+
+ T get(Class domainClass, Object id);
+
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcAutoConfiguration.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcAutoConfiguration.java
new file mode 100644
index 00000000..1d5f50c4
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcAutoConfiguration.java
@@ -0,0 +1,29 @@
+package com.codingapi.springboot.persistence.jdbc;
+
+import com.codingapi.springboot.persistence.DomainPersistence;
+import com.codingapi.springboot.persistence.schema.SchemaExecutor;
+import com.codingapi.springboot.persistence.schema.SchemaFactory;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@ConditionalOnClass(JdbcTemplate.class)
+@Configurable
+public class JdbcAutoConfiguration {
+
+ @Bean
+ public SchemaExecutor schemaExecutor(JdbcTemplate jdbcTemplate) {
+ return new JdbcSchemaExecutor(jdbcTemplate);
+ }
+
+ @Bean
+ public DomainPersistence domainPersistence(JdbcTemplate jdbcTemplate) {
+ return new JdbcDomainPersistence(jdbcTemplate);
+ }
+
+ @Bean
+ public SchemaFactory schemaFactory() {
+ return new JdbcSchemaFactory();
+ }
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcDomainPersistence.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcDomainPersistence.java
new file mode 100644
index 00000000..d64c9443
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcDomainPersistence.java
@@ -0,0 +1,60 @@
+package com.codingapi.springboot.persistence.jdbc;
+
+import com.codingapi.springboot.persistence.DomainPersistence;
+import com.codingapi.springboot.persistence.scanner.SchemaContext;
+import com.codingapi.springboot.persistence.schema.SaveSchema;
+import com.codingapi.springboot.persistence.schema.Schema;
+import com.codingapi.springboot.persistence.schema.SearchSchema;
+import lombok.AllArgsConstructor;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.support.GeneratedKeyHolder;
+import org.springframework.jdbc.support.KeyHolder;
+
+import java.sql.PreparedStatement;
+import java.sql.Statement;
+
+@AllArgsConstructor
+public class JdbcDomainPersistence implements DomainPersistence {
+
+ private final JdbcTemplate jdbcTemplate;
+
+ @Override
+ public void save(Object domain) {
+ Schema schema = SchemaContext.getINSTANCE().getSchema(domain.getClass());
+ if (schema != null) {
+ SaveSchema saveSchema = schema.insertSchema();
+ if (schema.getSchemaProperty().hasIdValue(domain)) {
+ jdbcTemplate.update(saveSchema.saveSchema(), saveSchema.getSaveValues(domain));
+ } else {
+ KeyHolder keyHolder = new GeneratedKeyHolder();
+ jdbcTemplate.update(con -> {
+ PreparedStatement ps = con.prepareStatement(saveSchema.saveSchema(false), Statement.RETURN_GENERATED_KEYS);
+ int index = 1;
+ for (Object value : saveSchema.getSaveValues(domain, false)) {
+ ps.setObject(index++, value);
+ }
+ return ps;
+ }, keyHolder);
+ schema.getSchemaProperty().setIdValue(domain, keyHolder.getKey());
+ }
+ }
+ }
+
+ @Override
+ public T get(Class domainClass, Object id) {
+ Schema schema = SchemaContext.getINSTANCE().getSchema(domainClass);
+ if (schema != null) {
+ SearchSchema searchSchema = schema.getById();
+ String sql = searchSchema.getById();
+ try {
+ return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(domainClass));
+ } catch (EmptyResultDataAccessException e) {
+ // Handle the case where no results are found or rethrow a custom exception
+ return null;
+ }
+ }
+ return null;
+ }
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcSchemaExecutor.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcSchemaExecutor.java
new file mode 100644
index 00000000..fe004d91
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcSchemaExecutor.java
@@ -0,0 +1,22 @@
+package com.codingapi.springboot.persistence.jdbc;
+
+import com.codingapi.springboot.persistence.schema.Schema;
+import com.codingapi.springboot.persistence.schema.SchemaExecutor;
+import lombok.AllArgsConstructor;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Repository;
+
+@Repository
+@AllArgsConstructor
+public class JdbcSchemaExecutor implements SchemaExecutor {
+
+ private final JdbcTemplate jdbcTemplate;
+
+
+ @Override
+ public void create(Schema schema) {
+ jdbcTemplate.execute(schema.buildSchema().createSchema());
+ }
+
+
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcSchemaFactory.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcSchemaFactory.java
new file mode 100644
index 00000000..1cbfb250
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/JdbcSchemaFactory.java
@@ -0,0 +1,14 @@
+package com.codingapi.springboot.persistence.jdbc;
+
+import com.codingapi.springboot.persistence.jdbc.schema.JdbcSchema;
+import com.codingapi.springboot.persistence.schema.Schema;
+import com.codingapi.springboot.persistence.schema.SchemaFactory;
+
+public class JdbcSchemaFactory implements SchemaFactory {
+
+ @Override
+ public Schema getSchema(Class> domainClass) {
+ return new JdbcSchema(domainClass);
+ }
+
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcBuildSchema.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcBuildSchema.java
new file mode 100644
index 00000000..55fd4ac7
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcBuildSchema.java
@@ -0,0 +1,35 @@
+package com.codingapi.springboot.persistence.jdbc.schema;
+
+import com.codingapi.springboot.persistence.schema.BuildSchema;
+import com.codingapi.springboot.persistence.schema.Property;
+import com.codingapi.springboot.persistence.schema.Schema;
+
+import java.util.List;
+
+public class JdbcBuildSchema extends BuildSchema {
+
+ public JdbcBuildSchema(Schema schema) {
+ super(schema);
+ }
+
+ @Override
+ public String createSchema() {
+ StringBuilder sql = new StringBuilder();
+ sql.append("CREATE TABLE IF NOT EXISTS ");
+ sql.append(property.getSchemaName());
+ sql.append(" (");
+ sql.append("id INT PRIMARY KEY AUTO_INCREMENT,");
+ List properties = property.getProperties(false);
+ for (int i = 0; i < properties.size(); i++) {
+ Property property = properties.get(i);
+ sql.append(property.getName());
+ sql.append(" ");
+ sql.append(property.getJdbcType());
+ if (i != properties.size() - 1) {
+ sql.append(", ");
+ }
+ }
+ sql.append(")");
+ return sql.toString();
+ }
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSaveSchema.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSaveSchema.java
new file mode 100644
index 00000000..612e3166
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSaveSchema.java
@@ -0,0 +1,34 @@
+package com.codingapi.springboot.persistence.jdbc.schema;
+
+import com.codingapi.springboot.persistence.schema.Property;
+import com.codingapi.springboot.persistence.schema.SaveSchema;
+import com.codingapi.springboot.persistence.schema.Schema;
+
+public class JdbcSaveSchema extends SaveSchema {
+
+ public JdbcSaveSchema(Schema schema) {
+ super(schema);
+ }
+
+ @Override
+ public String saveSchema(boolean hasId) {
+ StringBuilder sql = new StringBuilder();
+ sql.append("INSERT INTO ");
+ sql.append(property.getSchemaName());
+ sql.append(" (");
+ for (Property property : property.getProperties(hasId)) {
+ sql.append(property.getName());
+ sql.append(", ");
+ }
+ sql.delete(sql.length() - 2, sql.length());
+ sql.append(") VALUES (");
+ for (Property property : property.getProperties(hasId)) {
+ sql.append("?, ");
+ }
+ sql.delete(sql.length() - 2, sql.length());
+ sql.append(")");
+ return sql.toString();
+ }
+
+
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSchema.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSchema.java
new file mode 100644
index 00000000..c5905a70
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSchema.java
@@ -0,0 +1,28 @@
+package com.codingapi.springboot.persistence.jdbc.schema;
+
+import com.codingapi.springboot.persistence.schema.BuildSchema;
+import com.codingapi.springboot.persistence.schema.SaveSchema;
+import com.codingapi.springboot.persistence.schema.Schema;
+import com.codingapi.springboot.persistence.schema.SearchSchema;
+
+public class JdbcSchema extends Schema {
+
+ public JdbcSchema(Class> domainClass) {
+ super(domainClass);
+ }
+
+ @Override
+ public BuildSchema buildSchema() {
+ return new JdbcBuildSchema(this);
+ }
+
+ @Override
+ public SaveSchema insertSchema() {
+ return new JdbcSaveSchema(this);
+ }
+
+ @Override
+ public SearchSchema getById() {
+ return new JdbcSearchSchema(this);
+ }
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSearchSchema.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSearchSchema.java
new file mode 100644
index 00000000..babbfcc4
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/jdbc/schema/JdbcSearchSchema.java
@@ -0,0 +1,18 @@
+package com.codingapi.springboot.persistence.jdbc.schema;
+
+import com.codingapi.springboot.persistence.schema.Schema;
+import com.codingapi.springboot.persistence.schema.SearchSchema;
+
+public class JdbcSearchSchema extends SearchSchema {
+
+ public JdbcSearchSchema(Schema schema) {
+ super(schema);
+ }
+
+ @Override
+ public String getById() {
+ return "SELECT * FROM " + property.getSchemaName() + " WHERE id = ?";
+ }
+
+
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/register/DomainClassRegister.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/register/DomainClassRegister.java
new file mode 100644
index 00000000..88bf69a9
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/register/DomainClassRegister.java
@@ -0,0 +1,29 @@
+package com.codingapi.springboot.persistence.register;
+
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Getter
+public class DomainClassRegister {
+
+ private final List> classes;
+
+ public final static DomainClassRegister INSTANCE = new DomainClassRegister();
+
+ private DomainClassRegister() {
+ this.classes = new ArrayList<>();
+ }
+
+ public void register(Class> domainClass) {
+ this.classes.add(domainClass);
+ }
+
+ public boolean supports(Class> domainClass) {
+ return this.classes.stream()
+ .anyMatch(clazz -> clazz.equals(domainClass));
+
+ }
+
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/scanner/SchemaContext.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/scanner/SchemaContext.java
new file mode 100644
index 00000000..17f579f6
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/scanner/SchemaContext.java
@@ -0,0 +1,30 @@
+package com.codingapi.springboot.persistence.scanner;
+
+import com.codingapi.springboot.persistence.schema.Schema;
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SchemaContext {
+
+ @Getter
+ public final static SchemaContext INSTANCE = new SchemaContext();
+
+ private final List schemas;
+
+ private SchemaContext() {
+ this.schemas = new ArrayList<>();
+ }
+
+ public void register(Schema schema) {
+ this.schemas.add(schema);
+ }
+
+ public Schema getSchema(Class> domainClass) {
+ return schemas.stream()
+ .filter(schema -> schema.getDomainClass().equals(domainClass))
+ .findFirst()
+ .orElseThrow(() -> new RuntimeException("schema not found"));
+ }
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/scanner/SchemaScanner.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/scanner/SchemaScanner.java
new file mode 100644
index 00000000..a8e2dd68
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/scanner/SchemaScanner.java
@@ -0,0 +1,35 @@
+package com.codingapi.springboot.persistence.scanner;
+
+import com.codingapi.springboot.persistence.register.DomainClassRegister;
+import com.codingapi.springboot.persistence.schema.Schema;
+import com.codingapi.springboot.persistence.schema.SchemaExecutor;
+import com.codingapi.springboot.persistence.schema.SchemaFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+
+import java.util.List;
+
+@Slf4j
+public class SchemaScanner implements ApplicationRunner {
+
+ private final SchemaExecutor schemaExecutor;
+
+ private final SchemaFactory schemaFactory;
+
+ public SchemaScanner(SchemaExecutor schemaExecutor, SchemaFactory schemaFactory) {
+ this.schemaExecutor = schemaExecutor;
+ this.schemaFactory = schemaFactory;
+ }
+
+ @Override
+ public void run(ApplicationArguments args) throws Exception {
+ List> domainClasses = DomainClassRegister.INSTANCE.getClasses();
+ for (Class> domainClass : domainClasses) {
+ Schema schema = schemaFactory.getSchema(domainClass);
+ SchemaContext.INSTANCE.register(schema);
+ schemaExecutor.create(schema);
+ }
+ }
+
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/BuildSchema.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/BuildSchema.java
new file mode 100644
index 00000000..09fb8376
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/BuildSchema.java
@@ -0,0 +1,12 @@
+package com.codingapi.springboot.persistence.schema;
+
+public abstract class BuildSchema {
+
+ public abstract String createSchema();
+
+ protected final SchemaProperty property;
+
+ public BuildSchema(Schema schema) {
+ this.property = schema.getSchemaProperty();
+ }
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/Property.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/Property.java
new file mode 100644
index 00000000..14ff61c2
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/Property.java
@@ -0,0 +1,141 @@
+package com.codingapi.springboot.persistence.schema;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class Property {
+
+ private final org.yaml.snakeyaml.introspector.Property property;
+
+ public Property(org.yaml.snakeyaml.introspector.Property property) {
+ this.property = property;
+ }
+
+ public boolean hasIdValue(Object domain) {
+ if (property.getType().equals(int.class))
+ return property.get(domain) != null && (int) property.get(domain) > 0;
+ else if (property.getType().equals(long.class))
+ return property.get(domain) != null && (long) property.get(domain) > 0;
+ else if (property.getType().equals(double.class))
+ return property.get(domain) != null && (double) property.get(domain) > 0;
+ else if (property.getType().equals(float.class))
+ return property.get(domain) != null && (float) property.get(domain) > 0;
+ else if (property.getType().equals(short.class))
+ return property.get(domain) != null && (short) property.get(domain) > 0;
+ else if (property.getType().equals(byte.class))
+ return property.get(domain) != null && (byte) property.get(domain) > 0;
+ else if (property.getType().equals(boolean.class))
+ return property.get(domain) != null && (boolean) property.get(domain);
+ else if (property.getType().equals(Integer.class))
+ return property.get(domain) != null && (Integer) property.get(domain) > 0;
+ else if (property.getType().equals(Long.class))
+ return property.get(domain) != null && (Long) property.get(domain) > 0;
+ else if (property.getType().equals(Double.class))
+ return property.get(domain) != null && (Double) property.get(domain) > 0;
+ else if (property.getType().equals(Float.class))
+ return property.get(domain) != null && (Float) property.get(domain) > 0;
+ else if (property.getType().equals(Short.class))
+ return property.get(domain) != null && (Short) property.get(domain) > 0;
+ else if (property.getType().equals(Byte.class))
+ return property.get(domain) != null && (Byte) property.get(domain) > 0;
+ else if (property.getType().equals(Boolean.class))
+ return property.get(domain) != null && (Boolean) property.get(domain);
+ else if (property.getType().equals(String.class))
+ return property.get(domain) != null && !((String) property.get(domain)).isEmpty();
+ else if (property.getType().equals(Object.class))
+ return property.get(domain) != null;
+ else
+ throw new RuntimeException("not support type");
+ }
+
+
+ public void setIdValue(Object domain, Number key) {
+ try {
+ if (property.getType().equals(int.class))
+ property.set(domain, key.intValue());
+ else if (property.getType().equals(long.class))
+ property.set(domain, key.longValue());
+ else if (property.getType().equals(double.class))
+ property.set(domain, key.doubleValue());
+ else if (property.getType().equals(float.class))
+ property.set(domain, key.floatValue());
+ else if (property.getType().equals(short.class))
+ property.set(domain, key.shortValue());
+ else if (property.getType().equals(byte.class))
+ property.set(domain, key.byteValue());
+ else if (property.getType().equals(boolean.class))
+ property.set(domain, key.byteValue());
+ else if (property.getType().equals(Integer.class))
+ property.set(domain, key.intValue());
+ else if (property.getType().equals(Long.class))
+ property.set(domain, key.longValue());
+ else if (property.getType().equals(Double.class))
+ property.set(domain, key.doubleValue());
+ else if (property.getType().equals(Float.class))
+ property.set(domain, key.floatValue());
+ else if (property.getType().equals(Short.class))
+ property.set(domain, key.shortValue());
+ else if (property.getType().equals(Byte.class))
+ property.set(domain, key.byteValue());
+ else if (property.getType().equals(Boolean.class))
+ property.set(domain, key.byteValue());
+ else if (property.getType().equals(String.class))
+ property.set(domain, key.toString());
+ else if (property.getType().equals(Object.class))
+ property.set(domain, key);
+ } catch (Exception e) {
+ log.error("setIdValue error", e);
+ }
+ }
+
+
+ public String getName() {
+ return property.getName();
+ }
+
+ public Object get(Object domain) {
+ try {
+ return property.get(domain);
+ } catch (Exception e) {
+ log.error("get error", e);
+ return null;
+ }
+ }
+
+ public String getJdbcType(){
+ if (property.getType().equals(int.class))
+ return "INT";
+ else if (property.getType().equals(long.class))
+ return "BIGINT";
+ else if (property.getType().equals(double.class))
+ return "DOUBLE";
+ else if (property.getType().equals(float.class))
+ return "FLOAT";
+ else if (property.getType().equals(short.class))
+ return "SMALLINT";
+ else if (property.getType().equals(byte.class))
+ return "TINYINT";
+ else if (property.getType().equals(boolean.class))
+ return "BOOLEAN";
+ else if (property.getType().equals(Integer.class))
+ return "INT";
+ else if (property.getType().equals(Long.class))
+ return "BIGINT";
+ else if (property.getType().equals(Double.class))
+ return "DOUBLE";
+ else if (property.getType().equals(Float.class))
+ return "FLOAT";
+ else if (property.getType().equals(Short.class))
+ return "SMALLINT";
+ else if (property.getType().equals(Byte.class))
+ return "TINYINT";
+ else if (property.getType().equals(Boolean.class))
+ return "BOOLEAN";
+ else if (property.getType().equals(String.class))
+ return "VARCHAR(255)";
+ else if (property.getType().equals(Object.class))
+ return "VARCHAR(255)";
+ else
+ throw new RuntimeException("not support type");
+ }
+}
diff --git a/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/SaveSchema.java b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/SaveSchema.java
new file mode 100644
index 00000000..5fa7ad62
--- /dev/null
+++ b/springboot-starter-persistence/src/main/java/com/codingapi/springboot/persistence/schema/SaveSchema.java
@@ -0,0 +1,35 @@
+package com.codingapi.springboot.persistence.schema;
+
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Getter
+public abstract class SaveSchema {
+
+ protected final SchemaProperty property;
+
+ public SaveSchema(Schema schema) {
+ this.property = schema.getSchemaProperty();
+ }
+
+ public String saveSchema() {
+ return saveSchema(true);
+ }
+
+ public abstract String saveSchema(boolean hasId);
+
+
+ public Object[] getSaveValues(Object object, boolean hasId) {
+ List