diff --git a/pom.xml b/pom.xml
index ac329f3..bb1eea9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,6 +20,11 @@
股票行情
股票行情
+
+ com.squareup
+ javapoet
+ 1.11.1
+
org.springframework.boot
spring-boot-starter-tomcat
diff --git a/src/test/java/rp/lee/jpa/JpaDDDGen.java b/src/test/java/rp/lee/jpa/JpaDDDGen.java
new file mode 100644
index 0000000..f8ae5c8
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/JpaDDDGen.java
@@ -0,0 +1,57 @@
+package rp.lee.jpa;
+
+import java.sql.SQLException;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+
+import com.mysql.cj.jdbc.MysqlDataSource;
+
+import rp.lee.jpa.ddd.Cons;
+import rp.lee.jpa.ddd.ToolDDD;
+
+
+
+/**
+ *
+ * title: JpaDDDGen.java
+ * DDD 脚手架
+ *
+ * @author rplees
+ * @email rplees.i.ly@gmail.com
+ * @version 1.0
+ * @created 2023年8月9日 下午5:41:52
+ */
+public class JpaDDDGen {
+ @Resource DataSource dataSource;
+
+ /**
+ * 获取数据库连接
+ * @return
+ */
+ public static DataSource getMySQLDataSource() {
+ MysqlDataSource mysqlDS = new MysqlDataSource();
+ mysqlDS.setURL("jdbc:mysql://43.132.212.180:33306/india_stock?useUnicode=true&characterEncoding=utf-8");
+ mysqlDS.setUser("root");
+ mysqlDS.setPassword("33BsUUcnXRYgwt");
+ return mysqlDS;
+ }
+
+ public static void main(String[] args) throws SQLException, Exception {
+
+ Cons.module = "market";
+ /**
+ * 请修改实际上本机的项目路径
+ */
+ String path = "src/main/java";
+ Cons.CLIENT_FOLDER_PATH = path;
+ Cons.SERVER_FOLDER_PATH = path;
+
+ /**
+ * cs_statistic - 要生成的数据库表
+ */
+ Cons.tableNameToEntiyMapping.put("btoday_stock", null);
+
+ ToolDDD.g(getMySQLDataSource().getConnection());
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/ApiFeignGen.java b/src/test/java/rp/lee/jpa/ddd/ApiFeignGen.java
new file mode 100644
index 0000000..896b962
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/ApiFeignGen.java
@@ -0,0 +1,51 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public class ApiFeignGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+
+ Builder builder = TypeSpec.interfaceBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ .addSuperinterface(ddd.api.toClassName())
+ .addAnnotation(AnnotationSpec
+ .builder(ClassName.get("org.springframework.cloud.openfeign", "FeignClient"))
+ .addMember("name", "\"" + ddd.module + "\"")
+ .addMember("contextId", "\"" + StringUtils.uncapitalize(ddd.entityPrefix) + "\"")
+ .addMember("configuration", "{ $T.class }", ClassName.get("cn.qutaojing.common.feign", "FeignConfiguration"))
+
+ .build())
+
+ ;
+
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return "IFeign" + ddd.entityPrefix + "Client";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.CLIENT_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.API_FEIGN_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/ApiGen.java b/src/test/java/rp/lee/jpa/ddd/ApiGen.java
new file mode 100644
index 0000000..eecab6c
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/ApiGen.java
@@ -0,0 +1,137 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.util.List;
+
+import javax.lang.model.element.Modifier;
+import javax.validation.Valid;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public class ApiGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ ClassName springQueryMapClass = ClassName.get("org.springframework.cloud.openfeign", "SpringQueryMap");
+
+ Builder builder = TypeSpec.interfaceBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ .addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/" + StringUtils.lowerCase(ddd.entityPrefix) + "\"").build())
+
+ // 分页构造
+ .addMethod(MethodSpec.methodBuilder("page").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
+
+ .addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/page" + "\"").build())
+ .addParameter(ParameterSpec.builder(ddd.query.toClassName(), "query")
+ .addAnnotation(springQueryMapClass)
+ .build())
+ .addParameter(ParameterSpec.builder(ClassName.get("cn.qutaojing.common", "PageParam"), "p").build())
+ .returns(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common", "PageInfo"), ddd.dto.toClassName()))
+ .build()
+ )
+
+ // 列表构造
+ .addMethod(MethodSpec.methodBuilder("list").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
+ .addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/list\"").build())
+ .addParameter(ParameterSpec.builder(ddd.query.toClassName(), "query")
+ .addAnnotation(springQueryMapClass)
+ .build())
+ .returns(ParameterizedTypeName.get(ClassName.get(List.class), ddd.dto.toClassName()))
+ .build()
+ )
+
+ //create
+ .addMethod(MethodSpec.methodBuilder("create").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
+ .addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"create\"").build())
+ .addParameter(ParameterSpec.builder(ddd.put.toClassName(), "request").addAnnotation(Valid.class)
+ .addAnnotation(springQueryMapClass)
+ .build())
+ .addParameter(ParameterSpec.builder(BindingResult.class, "bindingResult")
+ .addAnnotation(AnnotationSpec.builder(RequestParam.class)
+ .addMember("required", "false")
+ .addMember("value", "\"bindingResult\"")
+ .build()).build())
+ .returns(ddd.dto.toClassName())
+ .build()
+ )
+
+ //update
+ .addMethod(MethodSpec.methodBuilder("update").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
+ .addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/update\"").build())
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
+ .addParameter(ParameterSpec.builder(ddd.put.toClassName(), "request")
+ .addAnnotation(springQueryMapClass)
+ .build())
+ .returns(ddd.dto.toClassName())
+ .build()
+ )
+
+ //根据ID获取
+ .addMethod(MethodSpec.methodBuilder("get").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
+ .addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/get\"").build())
+
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
+ .returns(ddd.dto.toClassName())
+ .build()
+ )
+
+ //启用
+ .addMethod(MethodSpec.methodBuilder("enable").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
+ .addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/enable\"").build())
+
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
+ .returns(void.class)
+ .build()
+ )
+
+ //禁用
+ .addMethod(MethodSpec.methodBuilder("disable").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
+ .addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/disable\"").build())
+
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
+ .returns(void.class)
+ .build()
+ )
+
+ //删除
+ .addMethod(MethodSpec.methodBuilder("remove").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
+ .addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/remove\"").build())
+
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
+ .returns(void.class)
+ .build()
+ )
+ ;
+
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return "I" + ddd.entityPrefix + "Client";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.CLIENT_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.API_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/ApiImplGen.java b/src/test/java/rp/lee/jpa/ddd/ApiImplGen.java
new file mode 100644
index 0000000..97da7b1
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/ApiImplGen.java
@@ -0,0 +1,163 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.util.List;
+
+import javax.lang.model.element.Modifier;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+public class ApiImplGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+
+ Builder builder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ .addSuperinterface(ddd.api.toClassName())
+ .addAnnotation(AnnotationSpec.builder(RestController.class).build())
+ .addAnnotation(AnnotationSpec.builder(RequiredArgsConstructor.class).addMember("onConstructor", "@__(@$T)", ClassName.get(Autowired.class)).build())
+ .addAnnotation(AnnotationSpec.builder(Slf4j.class).build())
+ .addField(FieldSpec.builder(ddd.service.toClassName(), "service").addModifiers(Modifier.FINAL).build())
+ .addField(FieldSpec.builder(ddd.assembler.toClassName(), "assembler").addModifiers(Modifier.FINAL).build())
+ .addField(FieldSpec.builder(ddd.factory.toClassName(), "factory").addModifiers(Modifier.FINAL).build())
+
+ // 分页构造
+ .addMethod(MethodSpec.methodBuilder("page")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+ .addParameter(ParameterSpec.builder(ddd.query.toClassName(), "query").build())
+ .addParameter(ParameterSpec.builder(ClassName.get("cn.qutaojing.common", "PageParam"), "p").build())
+ .returns(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common", "PageInfo"), ddd.dto.toClassName()))
+ .addStatement("$T<$T> page = service.repository().findAll($T.spec(query), PageParam.of(p))\n"
+ + " .map(entity -> assembler.toDTO(entity))",
+ ClassName.get("org.springframework.data.domain", "Page"),
+ ddd.dto.toClassName(),ClassName.get("cn.qutaojing.common.jpa", "QueryHelp"))
+
+ .addStatement("return PageInfo.with(page)")
+ .build()
+ )
+
+// // 列表构造
+ .addMethod(MethodSpec.methodBuilder("list")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+ .addParameter(ParameterSpec.builder(ddd.query.toClassName(), "query").build())
+ .returns(ParameterizedTypeName.get(ClassName.get(List.class), ddd.dto.toClassName()))
+ .addStatement("List<$T> list = service.repository().findAll($T.spec(query))", ddd.entity.toClassName(), ClassName.get("cn.qutaojing.common.jpa", "QueryHelp"))
+
+ .addStatement("return $T.transform(list, entity -> assembler.toDTO(entity))", ClassName.get("com.google.common.collect", "Lists"))
+ .build()
+ )
+
+// //create
+ .addMethod(MethodSpec.methodBuilder("create")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+ .addParameter(ParameterSpec.builder(ddd.put.toClassName(), "request").build())
+ .addParameter(ParameterSpec.builder(BindingResult.class, "bindingResult").build())
+ .returns(ddd.dto.toClassName())
+
+ .addStatement("$T.validBindResult(bindingResult)", ClassName.get("com.ag.utils", "AgAssert"))
+ .addStatement("$T createEntity = factory.entity(request)", ddd.entity.toClassName())
+ .addStatement("$T entity = service.repository().save(createEntity)", ddd.entity.toClassName())
+ .addStatement("return assembler.toDTO(entity)")
+ .build()
+ )
+//
+// //update
+ .addMethod(MethodSpec.methodBuilder("update")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
+ .addParameter(ParameterSpec.builder(ddd.put.toClassName(), "request").build())
+ .returns(ddd.dto.toClassName())
+
+ .addStatement("$T updateEntity = factory.entity(request)", ddd.entity.toClassName())
+ .addStatement("$T entity = service.update(id, updateEntity)", ddd.entity.toClassName())
+ .addStatement("return assembler.toDTO(entity)")
+ .build()
+ )
+//
+// //根据ID获取
+ .addMethod(MethodSpec.methodBuilder("get")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
+ .returns(ddd.dto.toClassName())
+
+ .addStatement("$T entity = service.repository().findById(id).orElseThrow($T::new)", ddd.entity.toClassName(), ClassName.get("com.ag.exception", "EntityNotFoundException"))
+ .addStatement("return assembler.toDTO(entity)")
+ .build()
+ )
+//
+// //启用
+ .addMethod(MethodSpec.methodBuilder("enable")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
+ .returns(void.class)
+ .addStatement("service.repository().setStatusEnable(id)")
+ .build()
+ )
+//
+// //禁用
+ .addMethod(MethodSpec.methodBuilder("disable")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
+ .returns(void.class)
+ .addStatement("service.repository().setStatusDisable(id)")
+ .build()
+ )
+//
+// //删除
+ .addMethod(MethodSpec.methodBuilder("remove")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+
+ .addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
+ .returns(void.class)
+ .addStatement("log.warn(\"删除{}实体\", id)")
+ .addStatement("service.repository().deleteById(id)")
+ .build()
+ )
+ ;
+
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "ClientImpl";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.API_IMPL_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/AssemblerGen.java b/src/test/java/rp/lee/jpa/ddd/AssemblerGen.java
new file mode 100644
index 0000000..1a609b2
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/AssemblerGen.java
@@ -0,0 +1,73 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public class AssemblerGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
+
+ Builder builder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(Component.class)
+ .addAnnotation(Lazy.class)
+
+ .addMethod(MethodSpec.methodBuilder("toDTO")
+ .addModifiers(Modifier.PUBLIC)
+ .addParameter(ddd.entity.toClassName(), "e")
+ .returns(ddd.dto.toClassName())
+ .addStatement("$T dto = $T.mapper(e, $T.class)", ddd.dto.toClassName(), ClassName.get("cn.qutaojing.common.utils", "Beans"), ddd.dto.toClassName())
+ .addStatement("if(dto == null) return dto")
+ .addStatement("fill(e, dto)")
+ .addStatement("return dto")
+ .build()
+ )
+
+ .addMethod(MethodSpec.methodBuilder("fill")
+ .addModifiers(Modifier.PROTECTED)
+ .addParameter(ddd.entity.toClassName(), "e")
+ .addParameter(ddd.dto.toClassName(), "dto")
+ .addStatement("if(dto == null) return")
+ .addStatement("return")
+ .build()
+ )
+
+ .addMethod(MethodSpec.methodBuilder("of")
+ .addModifiers(Modifier.PUBLIC)
+ .addModifiers(Modifier.STATIC)
+ .returns(slef)
+ .addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
+ .build()
+ )
+
+ .addJavadoc(String.format("%s \n", className(ddd)));
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "Assembler";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.ASSEMBLER_PACKAGE, ddd.module, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/ClassVO.java b/src/test/java/rp/lee/jpa/ddd/ClassVO.java
new file mode 100644
index 0000000..b1ee8e7
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/ClassVO.java
@@ -0,0 +1,19 @@
+package rp.lee.jpa.ddd;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import lombok.Data;
+
+@Data
+@lombok.Builder
+public class ClassVO {
+
+ String folderPath;
+ String packagePath;
+ String className;
+ Builder builder;
+
+ ClassName toClassName() {
+ return ClassName.get(packagePath, className);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/Cons.java b/src/test/java/rp/lee/jpa/ddd/Cons.java
new file mode 100644
index 0000000..7f45431
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/Cons.java
@@ -0,0 +1,58 @@
+package rp.lee.jpa.ddd;
+
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+
+public class Cons {
+ public static final boolean SIMPLE = true;
+ public static final boolean C = true;
+ /**
+ * 模块
+ */
+ public static String module = "cs";//项目
+ public static String entity = "basic"; //领域
+
+ /**
+ * 客户端项目的git路径
+ */
+ public static String CLIENT_FOLDER_PATH = "/Users/rplees/work/git/stock-company/cs_java/src/main/java";
+ /**
+ * Server项目的git路径
+ */
+ public static String SERVER_FOLDER_PATH = "/Users/rplees/work/git/stock-company/cs_java/src/main/java";
+
+ public static Map tableNameToEntiyMapping = Maps.newHashMap();
+ static {
+ /**
+ * 需要导出的数据库表名 -> 导出的 实体命名(不需要加后缀 PO/DTO/Entity)
+ */
+// tableNameToEntiyMapping.put("cs_statistic", null);
+ }
+
+ public static String BASE_PACKAGE = "cn.stock.%s";
+ public static String PO_PACKAGE = BASE_PACKAGE + ".infrastructure.db.po";
+ public static String PO_MONGO_PACKAGE = BASE_PACKAGE + ".infrastructure.mongodb.po";
+ public static String REPO_PACKAGE = BASE_PACKAGE + ".infrastructure.db.repo";
+ public static String REPO_MONGO_PACKAGE = BASE_PACKAGE + ".infrastructure.mongodb.repo";
+
+ public static String ENTITY_PACKAGE = BASE_PACKAGE + ".domain.%s.entity";
+ public static String SERVICE_PACKAGE = BASE_PACKAGE + ".domain.%s.service";
+ public static String REPOSITORY_PACKAGE = BASE_PACKAGE + ".domain.%s.repository";
+ public static String FACTORY_PACKAGE = BASE_PACKAGE + ".domain.%s.factory";
+ public static String CONVERT_PACKAGE = BASE_PACKAGE + ".domain.%s.convert";
+
+ public static String ASSEMBLER_PACKAGE = BASE_PACKAGE + ".application.assembler";
+
+ //client
+ public static String API_PACKAGE = BASE_PACKAGE + ".client";
+ public static String API_FEIGN_PACKAGE = BASE_PACKAGE + ".client.impl";
+ public static String API_IMPL_PACKAGE = BASE_PACKAGE + ".application";
+
+
+ public static String DTO_PACKAGE = BASE_PACKAGE + ".dto";
+ public static String QUERY_PACKAGE = BASE_PACKAGE + ".vo";
+ public static String PUT_PACKAGE = BASE_PACKAGE + ".vo";
+ public static String CREATE_PACKAGE = DTO_PACKAGE + ".command";
+ public static String MODIFY_PACKAGE = CREATE_PACKAGE;
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/ConvertGen.java b/src/test/java/rp/lee/jpa/ddd/ConvertGen.java
new file mode 100644
index 0000000..3686aad
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/ConvertGen.java
@@ -0,0 +1,92 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public class ConvertGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
+
+// Builder builder = TypeSpec.interfaceBuilder(className(ddd))
+// .addModifiers(Modifier.PUBLIC)
+// .addAnnotation(Component.class)
+// .addAnnotation(Lazy.class)
+// .addAnnotation(AnnotationSpec.builder(ClassName.get("org.mapstruct.Mapper", "Mapper"))
+// .addMember("componentModel", "spring")
+// .addMember("unmappedTargetPolicy", "ReportingPolicy.IGNORE)")
+// .build())
+// .addSuperinterface(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "IEntityPOConvert"),
+// ddd.entity.toClassName(),
+// ddd.po.toClassName()))
+//
+// .addJavadoc(String.format("%s \n", className(ddd)));
+
+ Builder builder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(Component.class)
+ .addAnnotation(Lazy.class)
+ .superclass(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "SimpleEntityPOConvert"),
+ ddd.entity.toClassName(),
+ ddd.po.toClassName()))
+// .addSuperinterface(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "IEntityPOConvert"),
+// ddd.entity.toClassName(),
+// ddd.po.toClassName()))
+//
+// .addMethod(MethodSpec.methodBuilder("toEntity")
+// .addModifiers(Modifier.PUBLIC)
+// .addAnnotation(Override.class)
+// .addParameter(ddd.po.toClassName(), "po")
+// .returns(ddd.entity.toClassName())
+// .addStatement("return $T.mapper(po, $T.class)", ClassName.get("cn.qutaojing.common.utils", "Beans"), ddd.entity.toClassName())
+// .build()
+// )
+//
+// .addMethod(MethodSpec.methodBuilder("toPo")
+// .addModifiers(Modifier.PUBLIC)
+// .addAnnotation(Override.class)
+// .addParameter(ddd.entity.toClassName(), "entity")
+// .returns(ddd.po.toClassName())
+// .addStatement("return $T.mapper(entity, $T.class)", ClassName.get("cn.qutaojing.common.utils", "Beans"), ddd.po.toClassName())
+// .build()
+// )
+
+ .addMethod(MethodSpec.methodBuilder("of")
+ .addModifiers(Modifier.PUBLIC)
+ .addModifiers(Modifier.STATIC)
+ .returns(slef)
+ .addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
+ .build()
+ )
+
+ .addJavadoc(String.format("%s \n", className(ddd)));
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "Convert";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.CONVERT_PACKAGE, ddd.module, ddd.e);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/CreateGen.java b/src/test/java/rp/lee/jpa/ddd/CreateGen.java
new file mode 100644
index 0000000..085f885
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/CreateGen.java
@@ -0,0 +1,87 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import javax.lang.model.element.Modifier;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import rp.lee.jpa.entity.ColumnStyle;
+import rp.lee.jpa.entity.Utils;
+
+public class CreateGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ String tableName = rs.getString("TABLE_NAME");
+ Builder classBuilder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ .addJavadoc(rs.getString("REMARKS"))
+ .addJavadoc("")
+ .addAnnotation(Data.class)
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
+ .addAnnotation(NoArgsConstructor.class)
+ ;
+
+ buildFields(ddd, conn, tableName, classBuilder);
+ return classBuilder;
+ }
+
+
+ static void buildFields(DDD ddd, Connection conn, String tableName, Builder classBuilder) throws SQLException {
+ ResultSet rs = null;
+ try {
+ DatabaseMetaData metaData = conn.getMetaData();
+ rs = metaData.getColumns(null, "%", tableName, "%");
+ while (rs.next()) {
+ String columnName = rs.getString("COLUMN_NAME");
+ int dataType = rs.getInt("DATA_TYPE");
+ String remarks = rs.getString("REMARKS");
+ String fieldName = Utils.columnNameToFieldName(columnName, ColumnStyle.defaultColumnStyle);
+ if("createTime".equals(fieldName) || "updateTime".equals(fieldName)) {//忽略
+
+ } else {
+ com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
+ .builder(Utils.dataTypeToFieldType(columnName, dataType),
+ fieldName)
+ .addJavadoc(remarks);
+
+ classBuilder.addField(fieldBuilder.build());
+ }
+
+ }
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "CreateCommand";
+ }
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.CLIENT_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.CREATE_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/DDD.java b/src/test/java/rp/lee/jpa/ddd/DDD.java
new file mode 100644
index 0000000..d6bc6d8
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/DDD.java
@@ -0,0 +1,54 @@
+package rp.lee.jpa.ddd;
+
+import java.lang.reflect.*;
+import java.util.List;
+import com.google.common.collect.Lists;
+
+public class DDD {
+ public DDD(String m, String e) {
+ this.module = m;
+ this.e = e;
+ }
+ String module;
+ String e;
+
+ Type poPK;
+ String poPKKey;
+
+ String entityPrefix;
+
+ ClassVO po; //ok
+ ClassVO entity; //ok
+ ClassVO dto;//ok
+
+ ClassVO assembler;//ok
+ ClassVO convert;//ok
+ ClassVO factory;//ok
+ ClassVO repository;//ok
+ ClassVO service;//ok
+
+ ClassVO repo;//ok
+ ClassVO query;//ok
+ ClassVO put;//ok
+
+ ClassVO create;//ok
+ ClassVO modify;//ok
+
+ ClassVO api;//ok
+ ClassVO apiFeign;//ok
+ ClassVO apiImplGen;//ok
+
+ public List list() {
+ if(Cons.SIMPLE) {
+ return Lists.newArrayList(po, entity, dto,create,modify, convert, factory,assembler, repository, service, repo, query, put);
+ }
+ if(Cons.C) {
+ return Lists.newArrayList(po, entity, dto, create,modify, convert, factory,assembler, repository, service, repo, query, put, api, apiFeign, apiImplGen);
+ }
+ return Lists.newArrayList(po, entity, dto, convert, factory,assembler, repository, service, repo, query, put, api, apiFeign, apiImplGen);
+ }
+
+ public List mongoList() {
+ return Lists.newArrayList(entity, dto,create,modify, convert, factory,assembler, repository, service, repo, query, put, api, apiFeign, apiImplGen);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/DTOGen.java b/src/test/java/rp/lee/jpa/ddd/DTOGen.java
new file mode 100644
index 0000000..7d011af
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/DTOGen.java
@@ -0,0 +1,60 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public class DTOGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+// String tableName = rs.getString("TABLE_NAME");
+// Builder classBuilder = TypeSpec.classBuilder(className(ddd))
+// .addModifiers(Modifier.PUBLIC)
+// .addJavadoc(String.format("%s \n", className(ddd)))
+// .addJavadoc(rs.getString("REMARKS"))
+// .addJavadoc("")
+// .addAnnotation(Data.class)
+// .addAnnotation(lombok.Builder.class)
+// .addAnnotation(NoArgsConstructor.class)
+// .addAnnotation(AllArgsConstructor.class)
+// ;
+//
+// buildFields(ddd, conn, tableName, classBuilder);
+// return classBuilder;
+
+ Builder builder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(lombok.Data.class)
+ .addAnnotation(lombok.NoArgsConstructor.class)
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
+ .superclass(ddd.po.toClassName())
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("lombok", "EqualsAndHashCode"))
+ .addMember("callSuper", "false")
+ .build())
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ ;
+
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "DTO";
+ }
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.CLIENT_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.DTO_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/EntityGen.java b/src/test/java/rp/lee/jpa/ddd/EntityGen.java
new file mode 100644
index 0000000..f586a10
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/EntityGen.java
@@ -0,0 +1,62 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public class EntityGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ Builder builder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(lombok.Data.class)
+ .addAnnotation(lombok.NoArgsConstructor.class)
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
+ .superclass(ddd.po.toClassName())
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("lombok", "EqualsAndHashCode"))
+ .addMember("callSuper", "false")
+ .build())
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ //public void update(E cmd) {
+// Beans.copyPropertiesIgnoreNull(cmd, this);
+// }
+ ;
+
+ if(Cons.C) {
+ builder.addMethod(MethodSpec.methodBuilder("update")
+ .addModifiers(Modifier.PUBLIC)
+ .returns(void.class)
+ .addParameter(ParameterSpec.builder(ddd.create.toClassName(), "cmd").build())
+// .addStatement("$T.copyPropertiesIgnoreNull(cmd, this)", ClassName.get("cn.qutaojing.common.utils", "Beans"))
+ .addStatement("$T.copyProperties(cmd, this)", ClassName.get("cn.qutaojing.common.utils", "Beans"))
+ .build()
+ );
+ }
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix; // + "Entity";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.ENTITY_PACKAGE, ddd.module, ddd.e);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/FactoryGen.java b/src/test/java/rp/lee/jpa/ddd/FactoryGen.java
new file mode 100644
index 0000000..4d6e57f
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/FactoryGen.java
@@ -0,0 +1,74 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public class FactoryGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
+
+ Builder builder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(Component.class)
+ .addAnnotation(Lazy.class)
+
+ .addMethod(MethodSpec.methodBuilder("of")
+ .addModifiers(Modifier.PUBLIC)
+ .addModifiers(Modifier.STATIC)
+ .returns(slef)
+ .addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
+ .build()
+ )
+
+// .addMethod(MethodSpec.methodBuilder("entity")
+// .addModifiers(Modifier.PUBLIC)
+// .addParameter(ddd.put.toClassName(), "request")
+// .returns(ddd.entity.toClassName())
+// .addStatement("return $T.mapper(request, $T.class)", ClassName.get("cn.qutaojing.common.utils", "Beans"), ddd.entity.toClassName())
+// .build()
+// )
+
+ .addJavadoc(String.format("%s \n", className(ddd)));
+ if(Cons.C) {
+ builder.addMethod(MethodSpec.methodBuilder("from")
+ .addModifiers(Modifier.PUBLIC)
+ .returns(ddd.entity.toClassName())
+ .addParameter(ParameterSpec.builder(ddd.create.toClassName(), "cmd").build())
+ .addStatement("$T e = $T.builder().build()", ddd.entity.toClassName(), ddd.entity.toClassName())
+ .addStatement("e.update(cmd)")
+ .addStatement("return e")
+ .build()
+ );
+
+ }
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "Factory";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.FACTORY_PACKAGE, ddd.module, ddd.e);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/IClassGenerate.java b/src/test/java/rp/lee/jpa/ddd/IClassGenerate.java
new file mode 100644
index 0000000..8485d91
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/IClassGenerate.java
@@ -0,0 +1,21 @@
+package rp.lee.jpa.ddd;
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import com.ag.utils.DateUtils;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public interface IClassGenerate {
+ Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception;
+ String className(DDD ddd);
+ String folerPath(DDD ddd);
+ String packagePath(DDD ddd);
+
+ default void addAuthor(Builder builder) {
+ builder
+ .addJavadoc("\n")
+ .addJavadoc(String.format("@author %s \n", "rplees"))
+ .addJavadoc(String.format("@email %s \n", "rplees.i.ly@gmail.com"))
+ .addJavadoc(String.format("@created %s \n", DateUtils.nowDate("yyyy/MM/dd")));
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/ModifyGen.java b/src/test/java/rp/lee/jpa/ddd/ModifyGen.java
new file mode 100644
index 0000000..78d526c
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/ModifyGen.java
@@ -0,0 +1,56 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+public class ModifyGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ Builder classBuilder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ .addJavadoc(rs.getString("REMARKS"))
+ .addJavadoc("")
+ .addAnnotation(Data.class)
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
+ .addAnnotation(NoArgsConstructor.class)
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("lombok", "EqualsAndHashCode"))
+ .addMember("callSuper", "false")
+ .build())
+ .superclass(ddd.create.toClassName())
+ ;
+
+ com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
+ .builder(Integer.class,
+ "id");
+ classBuilder.addField(fieldBuilder.build());
+
+ return classBuilder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "ModifyCommand";
+ }
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.CLIENT_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.MODIFY_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/POGen.java b/src/test/java/rp/lee/jpa/ddd/POGen.java
new file mode 100644
index 0000000..802f5a1
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/POGen.java
@@ -0,0 +1,158 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import javax.lang.model.element.Modifier;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.commons.lang.StringUtils;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import rp.lee.jpa.entity.ColumnStyle;
+import rp.lee.jpa.entity.Utils;
+
+public class POGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ String primaryKey = ""; //TODO:目前之支持一个主键
+ String tableName = "";
+
+ Builder classBuilder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+// .addJavadoc(rs.getString("REMARKS"))
+ .addJavadoc("")
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
+ .addAnnotation(Data.class)
+ .addAnnotation(NoArgsConstructor.class)
+ .addAnnotation(AllArgsConstructor.class);
+ if(conn != null) {
+ tableName = rs.getString("TABLE_NAME");
+ DatabaseMetaData metaData = conn.getMetaData();
+ ResultSet primaryKeyResultSet = metaData.getPrimaryKeys(conn.getCatalog(),null, tableName);
+
+ try {
+ while(primaryKeyResultSet.next()){
+ primaryKey = primaryKeyResultSet.getString("COLUMN_NAME");
+ }
+ } finally {
+ try {
+ primaryKeyResultSet.close();
+ } catch(Exception e) {}
+ }
+
+ if(StringUtils.isBlank(primaryKey)) {//没有主键的不生成
+ System.err.println(String.format("表[%s]没有主键, 将跳过", tableName));
+ return null;
+ }
+
+ classBuilder.addJavadoc(rs.getString("REMARKS"))
+ .addAnnotation(AnnotationSpec.builder(Entity.class).build())
+ .addAnnotation(AnnotationSpec.builder(DynamicInsert.class).build())
+ .addAnnotation(AnnotationSpec.builder(DynamicUpdate.class).build())
+ .addAnnotation(AnnotationSpec.builder(Table.class)
+ .addMember("name", "\"" + tableName + "\"").build());
+
+ } else {
+ primaryKey = "id";
+ }
+
+ buildFields(ddd, conn, tableName, primaryKey, classBuilder);
+ return classBuilder;
+ }
+
+
+ static void buildFields(DDD ddd, Connection conn, String tableName, String primaryKey, Builder classBuilder) throws SQLException {
+ if(conn == null) {
+ ddd.poPK = Long.class;
+ ddd.poPKKey = primaryKey;
+ } else {
+ ResultSet rs = null;
+ try {
+ DatabaseMetaData metaData = conn.getMetaData();
+ rs = metaData.getColumns(null, "%", tableName, "%");
+ while (rs.next()) {
+ String columnName = rs.getString("COLUMN_NAME");
+ String filedName = Utils.columnNameToFieldName(columnName, ColumnStyle.defaultColumnStyle);
+
+ int dataType = rs.getInt("DATA_TYPE");
+ String remarks = rs.getString("REMARKS");
+ String IS_AUTOINCREMENT = rs.getString("IS_AUTOINCREMENT");
+
+ com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
+ .builder(Utils.dataTypeToFieldType(columnName, dataType), filedName)
+ .addJavadoc(remarks);
+
+ if(StringUtils.equals(primaryKey, columnName)) {
+ fieldBuilder.addAnnotation(Id.class);
+ //主键类型
+ ddd.poPK = Utils.dataTypeToFieldType(filedName, dataType);
+ ddd.poPKKey = filedName;
+ }
+
+ if("create_time".equalsIgnoreCase(columnName) || "create_at".equalsIgnoreCase(columnName)) {
+ fieldBuilder.addAnnotation(CreationTimestamp.class);
+ fieldBuilder.addAnnotation(AnnotationSpec.builder(Column.class).addMember("updatable", "false").build());
+ }
+
+ if("update_time".equalsIgnoreCase(columnName) || "update_at".equalsIgnoreCase(columnName)) {
+ fieldBuilder.addAnnotation(UpdateTimestamp.class);
+ }
+ if("YES".equals(IS_AUTOINCREMENT)) {
+ AnnotationSpec generatedValue = AnnotationSpec.builder(ClassName.get("javax.persistence", "GeneratedValue"))
+ .addMember("strategy", "javax.persistence.GenerationType.IDENTITY")
+ .build();
+
+ fieldBuilder.addAnnotation(generatedValue);
+ }
+
+ classBuilder.addField(fieldBuilder.build());
+ /**
+ * 参考资料 https://www.cnblogs.com/lbangel/p/3487796.html
+ */
+ }
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "PO";
+ }
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.PO_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/POMongoGen.java b/src/test/java/rp/lee/jpa/ddd/POMongoGen.java
new file mode 100644
index 0000000..34dda9e
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/POMongoGen.java
@@ -0,0 +1,60 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import javax.lang.model.element.Modifier;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+public class POMongoGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ String primaryKey = ""; //TODO:目前之支持一个主键
+ String tableName = "";
+
+ Builder classBuilder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+// .addJavadoc(rs.getString("REMARKS"))
+ .addJavadoc("")
+ .addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
+ .addAnnotation(Data.class)
+ .addAnnotation(NoArgsConstructor.class)
+ .addAnnotation(AllArgsConstructor.class);
+ primaryKey = "id";
+
+ buildFields(ddd, conn, tableName, primaryKey, classBuilder);
+ return classBuilder;
+ }
+
+
+ static void buildFields(DDD ddd, Connection conn, String tableName, String primaryKey, Builder classBuilder) throws SQLException {
+ ddd.poPK = Long.class;
+ ddd.poPKKey = primaryKey;
+ }
+
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "PO";
+ }
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.PO_MONGO_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/PutGen.java b/src/test/java/rp/lee/jpa/ddd/PutGen.java
new file mode 100644
index 0000000..76b30f7
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/PutGen.java
@@ -0,0 +1,87 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import javax.lang.model.element.Modifier;
+
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import rp.lee.jpa.entity.ColumnStyle;
+import rp.lee.jpa.entity.Utils;
+
+public class PutGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ String tableName = rs.getString("TABLE_NAME");
+ Builder classBuilder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ .addJavadoc(rs.getString("REMARKS"))
+ .addJavadoc("")
+ .addAnnotation(Data.class)
+ .addAnnotation(lombok.Builder.class)
+ .addAnnotation(NoArgsConstructor.class)
+ .addAnnotation(AllArgsConstructor.class)
+ ;
+
+ buildFields(ddd, conn, tableName, classBuilder);
+ return classBuilder;
+ }
+
+
+ static void buildFields(DDD ddd, Connection conn, String tableName, Builder classBuilder) throws SQLException {
+ ResultSet rs = null;
+ try {
+ DatabaseMetaData metaData = conn.getMetaData();
+ rs = metaData.getColumns(null, "%", tableName, "%");
+ while (rs.next()) {
+ String columnName = rs.getString("COLUMN_NAME");
+ int dataType = rs.getInt("DATA_TYPE");
+ String remarks = rs.getString("REMARKS");
+ String fieldName = Utils.columnNameToFieldName(columnName, ColumnStyle.defaultColumnStyle);
+ if("createTime".equals(fieldName) || "updateTime".equals(fieldName)) {//忽略
+
+ } else {
+ com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
+ .builder(Utils.dataTypeToFieldType(columnName, dataType),
+ fieldName)
+ .addJavadoc(remarks);
+
+ classBuilder.addField(fieldBuilder.build());
+ }
+
+ }
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "PutRequest";
+ }
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.CLIENT_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.PUT_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/QueryGen.java b/src/test/java/rp/lee/jpa/ddd/QueryGen.java
new file mode 100644
index 0000000..1c51234
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/QueryGen.java
@@ -0,0 +1,110 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import javax.lang.model.element.Modifier;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import rp.lee.jpa.entity.ColumnStyle;
+import rp.lee.jpa.entity.Utils;
+
+public class QueryGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ String tableName = rs.getString("TABLE_NAME");
+ Builder classBuilder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ .addJavadoc(rs.getString("REMARKS"))
+ .addJavadoc("")
+ .addAnnotation(Data.class)
+ .addAnnotation(lombok.Builder.class)
+ .addAnnotation(NoArgsConstructor.class)
+ .addAnnotation(AllArgsConstructor.class)
+ ;
+
+ buildFields(ddd, conn, tableName, classBuilder);
+ return classBuilder;
+ }
+
+
+ static void buildFields(DDD ddd, Connection conn, String tableName, Builder classBuilder) throws SQLException {
+ ResultSet rs = null;
+ try {
+ DatabaseMetaData metaData = conn.getMetaData();
+ rs = metaData.getColumns(null, "%", tableName, "%");
+ while (rs.next()) {
+ String columnName = rs.getString("COLUMN_NAME");
+ int dataType = rs.getInt("DATA_TYPE");
+ String remarks = rs.getString("REMARKS");
+ String fieldName = Utils.columnNameToFieldName(columnName, ColumnStyle.defaultColumnStyle);
+
+ if("createTime".equals(fieldName)) {
+ com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
+ .builder(Utils.dataTypeToFieldType(columnName, dataType), "start" + StringUtils.capitalize(fieldName))
+ .addJavadoc(remarks);
+ fieldBuilder.addAnnotation(AnnotationSpec.builder(ClassName.get("cn.qutaojing.common.jpa", "QueryCriteria"))
+ .addMember("type", "$T.GREATER_THAN", ClassName.get("cn.qutaojing.common.jpa.QueryCriteria", "Type"))
+ .addMember("propName", "\"" + fieldName + "\"")
+ .build());
+
+ com.squareup.javapoet.FieldSpec.Builder fieldBuilder2 = FieldSpec
+ .builder(Utils.dataTypeToFieldType(columnName, dataType), "end" + StringUtils.capitalize(fieldName))
+ .addJavadoc(remarks);
+ fieldBuilder2.addAnnotation(AnnotationSpec.builder(ClassName.get("cn.qutaojing.common.jpa", "QueryCriteria"))
+ .addMember("type", "$T.LESS_THAN", ClassName.get("cn.qutaojing.common.jpa.QueryCriteria", "Type"))
+ .addMember("propName", "\"" + fieldName + "\"")
+ .build());
+
+ classBuilder.addField(fieldBuilder.build());
+ classBuilder.addField(fieldBuilder2.build());
+ } else if("updateTime".equals(fieldName)) {//忽略
+
+ } else {
+ com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
+ .builder(Utils.dataTypeToFieldType(columnName, dataType), fieldName)
+ .addJavadoc(remarks);
+ fieldBuilder.addAnnotation(AnnotationSpec.builder(ClassName.get("cn.qutaojing.common.jpa", "QueryCriteria"))
+ .addMember("type", "$T.EQUAL", ClassName.get("cn.qutaojing.common.jpa.QueryCriteria", "Type")).build());
+ classBuilder.addField(fieldBuilder.build());
+ }
+ }
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "Query";
+ }
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.CLIENT_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.QUERY_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/RepoGen.java b/src/test/java/rp/lee/jpa/ddd/RepoGen.java
new file mode 100644
index 0000000..2039ae4
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/RepoGen.java
@@ -0,0 +1,47 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import com.rp.spring.jpa.GenericJpaRepository;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public class RepoGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ //生成DAO
+ Builder daoClassBuilder = TypeSpec.interfaceBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addSuperinterface(ParameterizedTypeName.get(ClassName.get(GenericJpaRepository.class),
+ ddd.po.toClassName(),
+ TypeName.get(ddd.poPK)))
+
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ ;
+
+ return daoClassBuilder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "Repo";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.REPO_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/RepoMongoGen.java b/src/test/java/rp/lee/jpa/ddd/RepoMongoGen.java
new file mode 100644
index 0000000..f17f2e0
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/RepoMongoGen.java
@@ -0,0 +1,46 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+public class RepoMongoGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ ClassName className = ClassName.get("cn.qutaojing.data.analyse.infrastructure.mongodb.core", "GenericMongoRepository");
+ //生成DAO
+ Builder daoClassBuilder = TypeSpec.interfaceBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addSuperinterface(ParameterizedTypeName.get(className,
+ ddd.po.toClassName(),
+ TypeName.get(ddd.poPK)))
+
+ .addJavadoc(String.format("%s \n", className(ddd)))
+ ;
+
+ return daoClassBuilder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "Repo";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.REPO_MONGO_PACKAGE, ddd.module);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/RepositoryGen.java b/src/test/java/rp/lee/jpa/ddd/RepositoryGen.java
new file mode 100644
index 0000000..8f20b8c
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/RepositoryGen.java
@@ -0,0 +1,104 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.rp.spring.jpa.GenericJpaRepository;
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+import com.squareup.javapoet.TypeVariableName;
+
+import lombok.RequiredArgsConstructor;
+
+public class RepositoryGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
+
+ Builder builder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(org.springframework.stereotype.Repository.class)
+ .addAnnotation(AnnotationSpec.builder(RequiredArgsConstructor.class).addMember("onConstructor", "@__(@$T)", ClassName.get(Autowired.class)).build())
+ .superclass(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.respostory", "SimplePoConvertEntityRepository"),
+ ddd.entity.toClassName(),
+ ddd.po.toClassName(),
+ TypeName.get(ddd.poPK)))
+
+ .addJavadoc(String.format("%s \n", className(ddd)));
+
+ if(StringUtils.isNotBlank(ddd.poPKKey)) { //有主键
+// builder.addMethod(MethodSpec.methodBuilder("save")
+// .addModifiers(Modifier.PUBLIC)
+// .addAnnotation(AnnotationSpec.builder(Override.class).build())
+// .addParameter(ParameterSpec.builder(ddd.entity.toClassName(), "entity").build())
+// .returns(void.class)
+//
+// .addStatement("$T po = repo().save(convert().toPo(entity));", ddd.po.toClassName())
+// .addStatement(String.format("entity.set%s(po.get%s())", StringUtils.capitalize(ddd.poPKKey), StringUtils.capitalize(ddd.poPKKey)))
+// .build()
+// );
+ }
+
+
+ builder.addField(FieldSpec.builder(ddd.repo.toClassName(), "repo").addModifiers(Modifier.FINAL).build())
+ .addMethod(MethodSpec.methodBuilder("repo")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+ .returns(ParameterizedTypeName.get(ClassName.get(GenericJpaRepository.class),
+ ddd.po.toClassName(),
+ TypeName.get(ddd.poPK)))
+ .addStatement("return $T", TypeVariableName.get("repo"))
+ .build()
+ )
+
+ .addField(FieldSpec.builder(ddd.convert.toClassName(), "convert").addModifiers(Modifier.FINAL).build())
+ .addMethod(MethodSpec.methodBuilder("convert")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+ .returns(
+ ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "IEntityPOConvert"),
+ ddd.entity.toClassName(), ddd.po.toClassName()
+ )
+ )
+ .addStatement("return $T", TypeVariableName.get("convert"))
+ .build()
+ )
+ .addMethod(MethodSpec.methodBuilder("of")
+ .addModifiers(Modifier.PUBLIC)
+ .addModifiers(Modifier.STATIC)
+ .returns(slef)
+ .addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
+ .build()
+ )
+ ;
+
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "Repository";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.REPOSITORY_PACKAGE, ddd.module, ddd.e);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/RepositoryMongoGen.java b/src/test/java/rp/lee/jpa/ddd/RepositoryMongoGen.java
new file mode 100644
index 0000000..a70280d
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/RepositoryMongoGen.java
@@ -0,0 +1,97 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.rp.spring.jpa.GenericJpaRepository;
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+import com.squareup.javapoet.TypeVariableName;
+
+import lombok.RequiredArgsConstructor;
+
+public class RepositoryMongoGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ ClassName className = ClassName.get("cn.qutaojing.data.analyse.infrastructure.mongodb.core", "GenericMongoRepository");
+
+ Builder builder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(org.springframework.stereotype.Repository.class)
+ .addAnnotation(AnnotationSpec.builder(RequiredArgsConstructor.class).addMember("onConstructor", "@__(@$T)", ClassName.get(Autowired.class)).build())
+ .superclass(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.dataanalyse.infrastructure.mongodb.core", "SimplePoConvertEntityMongoRepository"),
+ ddd.entity.toClassName(),
+ ddd.po.toClassName(),
+ TypeName.get(ddd.poPK)))
+
+ .addJavadoc(String.format("%s \n", className(ddd)));
+
+ if(StringUtils.isNotBlank(ddd.poPKKey)) { //有主键
+// builder.addMethod(MethodSpec.methodBuilder("save")
+// .addModifiers(Modifier.PUBLIC)
+// .addAnnotation(AnnotationSpec.builder(Override.class).build())
+// .addParameter(ParameterSpec.builder(ddd.entity.toClassName(), "entity").build())
+// .returns(void.class)
+//
+// .addStatement("$T po = repo().save(convert().toPo(entity));", ddd.po.toClassName())
+// .addStatement(String.format("entity.set%s(po.get%s())", StringUtils.capitalize(ddd.poPKKey), StringUtils.capitalize(ddd.poPKKey)))
+// .build()
+// );
+ }
+
+
+ builder.addField(FieldSpec.builder(ddd.repo.toClassName(), "repo").addModifiers(Modifier.FINAL).build())
+ .addMethod(MethodSpec.methodBuilder("repo")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+ .returns(ParameterizedTypeName.get(className,
+ ddd.po.toClassName(),
+ TypeName.get(ddd.poPK)))
+ .addStatement("return $T", TypeVariableName.get("repo"))
+ .build()
+ )
+
+ .addField(FieldSpec.builder(ddd.convert.toClassName(), "convert").addModifiers(Modifier.FINAL).build())
+ .addMethod(MethodSpec.methodBuilder("convert")
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(AnnotationSpec.builder(Override.class).build())
+ .returns(
+ ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "IEntityPOConvert"),
+ ddd.entity.toClassName(), ddd.po.toClassName()
+ )
+ )
+ .addStatement("return $T", TypeVariableName.get("convert"))
+ .build()
+ )
+ ;
+
+ return builder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "Repository";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.REPOSITORY_PACKAGE, ddd.module, ddd.e);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/ServiceGen.java b/src/test/java/rp/lee/jpa/ddd/ServiceGen.java
new file mode 100644
index 0000000..0d6c83d
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/ServiceGen.java
@@ -0,0 +1,82 @@
+package rp.lee.jpa.ddd;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import javax.lang.model.element.Modifier;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeSpec.Builder;
+import com.squareup.javapoet.TypeVariableName;
+
+import lombok.RequiredArgsConstructor;
+
+public class ServiceGen implements IClassGenerate {
+ @Override
+ public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
+ ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
+
+ Builder serviceClassBuilder = TypeSpec.classBuilder(className(ddd))
+ .addModifiers(Modifier.PUBLIC)
+ .addAnnotation(org.springframework.stereotype.Service.class)
+ .addAnnotation(AnnotationSpec.builder(RequiredArgsConstructor.class).addMember("onConstructor", "@__(@$T)", ClassName.get(Autowired.class)).build())
+// .addAnnotation(Transactional.class)
+ .addJavadoc(String.format("%s \n", className(ddd)))
+
+ .addField(FieldSpec.builder(ddd.repository.toClassName(), "repository").addModifiers(Modifier.FINAL).build())
+ .addField(FieldSpec.builder(ddd.factory.toClassName(), "factory").addModifiers(Modifier.FINAL).build())
+
+ .addMethod(MethodSpec.methodBuilder("repository")
+ .addModifiers(Modifier.PUBLIC)
+ .returns(ddd.repository.toClassName())
+ .addStatement("return $T", TypeVariableName.get("repository"))
+ .build()
+ )
+
+ .addMethod(MethodSpec.methodBuilder("of")
+ .addModifiers(Modifier.PUBLIC)
+ .addModifiers(Modifier.STATIC)
+ .returns(slef)
+ .addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
+ .build()
+ )
+
+// .addMethod(MethodSpec.methodBuilder("update")
+// .addModifiers(Modifier.PUBLIC)
+// .addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
+// .addParameter(ParameterSpec.builder(ddd.entity.toClassName(), "updateEntity").build())
+// .returns(ddd.entity.toClassName())
+// .addStatement("$T entity = repository().findById(id).orElseThrow($T::new)", ddd.entity.toClassName(), ClassName.get("com.ag.exception", "EntityNotFoundException"))
+// .addStatement("$T.copyPropertiesIgnoreNull(updateEntity, entity)", ClassName.get("cn.qutaojing.common.utils", "Beans"))
+// .addStatement("return repository().save(entity)")
+//
+// .build()
+// )
+
+ ;
+
+ return serviceClassBuilder;
+ }
+
+ @Override
+ public String className(DDD ddd) {
+ return ddd.entityPrefix + "Service";
+ }
+
+
+ @Override
+ public String folerPath(DDD ddd) {
+ return Cons.SERVER_FOLDER_PATH;
+ }
+
+ @Override
+ public String packagePath(DDD ddd) {
+ return String.format(Cons.SERVICE_PACKAGE, ddd.module, ddd.e);
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/ToolDDD.java b/src/test/java/rp/lee/jpa/ddd/ToolDDD.java
new file mode 100644
index 0000000..254b311
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/ToolDDD.java
@@ -0,0 +1,98 @@
+package rp.lee.jpa.ddd;
+
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.function.Consumer;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import rp.lee.jpa.entity.Utils;
+
+public class ToolDDD {
+
+ public static void g(Connection conn) throws Exception {
+ ResultSet rs = null;
+ try {
+ String catalog = conn.getCatalog();
+ DatabaseMetaData metaData = conn.getMetaData();
+ rs = metaData.getTables(catalog, null, null, new String[] { "TABLE" });
+ while (rs.next()) {
+ String tableName = rs.getString("TABLE_NAME");
+ boolean pass = Cons.tableNameToEntiyMapping.keySet().contains(tableName);
+ if(pass) {
+ buildDDD(conn, rs, Cons.module, Cons.entity);
+ }
+ }
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ private static void buildDDD(Connection conn, ResultSet rs, String module, String e) throws Exception {
+ DDD ddd = new DDD(module, e);
+ String tableName = rs.getString("TABLE_NAME");
+
+ String entity = Cons.tableNameToEntiyMapping.get(tableName);
+ if(StringUtils.isBlank(entity)) {
+ entity = Utils.tableNameToEntityName(tableName);
+ }
+
+ ddd.entityPrefix = entity;
+
+ make(conn, rs, ddd, new POGen(), vo -> ddd.po = vo );
+ make(conn, rs, ddd, new CreateGen(), vo -> ddd.create = vo );
+ make(conn, rs, ddd, new ModifyGen(), vo -> ddd.modify = vo );
+ make(conn, rs, ddd, new EntityGen(), vo -> ddd.entity = vo );
+ make(conn, rs, ddd, new DTOGen(), vo -> ddd.dto = vo);
+
+ make(conn, rs, ddd, new ConvertGen(), vo -> ddd.convert = vo);
+ make(conn, rs, ddd, new AssemblerGen(), vo -> ddd.assembler = vo);
+ make(conn, rs, ddd, new FactoryGen(), vo -> ddd.factory = vo);
+
+ make(conn, rs, ddd, new RepoGen(), vo -> ddd.repo = vo);
+ make(conn, rs, ddd, new RepositoryGen(), vo -> ddd.repository = vo);
+ make(conn, rs, ddd, new ServiceGen(), vo -> ddd.service = vo);
+
+// make(conn, rs, ddd, new ApiGen(), vo -> ddd.api = vo);
+// make(conn, rs, ddd, new ApiFeignGen(), vo -> ddd.apiFeign = vo);
+// make(conn, rs, ddd, new ApiImplGen(), vo -> ddd.apiImplGen = vo);
+// make(conn, rs, ddd, new PutGen(), vo -> ddd.put = vo);
+// make(conn, rs, ddd, new QueryGen(), vo -> ddd.query = vo);
+
+ List list = ddd.list();
+ for (ClassVO classVO : list) {
+ if(classVO == null) continue;
+ JavaFile javaFile = JavaFile.builder(classVO.packagePath, classVO.builder.build())
+ .build();
+ javaFile.writeTo(System.out);
+ javaFile.writeTo(Paths.get(classVO.folderPath));
+ }
+ }
+
+ private static ClassVO make(Connection conn, ResultSet rs, DDD ddd, IClassGenerate ig, Consumer c) throws Exception {
+ Builder builder = ig.builder(ddd, conn, rs);
+ ig.addAuthor(builder);
+
+ ClassVO vo = ClassVO.builder()
+ .builder(builder)
+ .className(ig.className(ddd))
+ .folderPath(ig.folerPath(ddd))
+ .packagePath(ig.packagePath(ddd))
+ .build();
+
+ c.accept(vo);
+ return vo;
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/ddd/ToolDDDMongo.java b/src/test/java/rp/lee/jpa/ddd/ToolDDDMongo.java
new file mode 100644
index 0000000..99df278
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/ddd/ToolDDDMongo.java
@@ -0,0 +1,73 @@
+package rp.lee.jpa.ddd;
+
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.TypeSpec.Builder;
+
+import rp.lee.jpa.entity.Utils;
+
+public class ToolDDDMongo {
+
+ public static void main(String[] args) throws Exception {
+ g();
+ }
+
+ public static void g() throws Exception {
+ for(Map.Entry entry : Cons.tableNameToEntiyMapping.entrySet()) {
+ String entity = entry.getValue();
+ if(StringUtils.isBlank(entity)) {
+ entity = Utils.tableNameToEntityName(entry.getKey());
+ }
+ buildDDD(entity,Cons.module, Cons.entity);
+ }
+ Cons.tableNameToEntiyMapping.keySet();
+ }
+
+ private static void buildDDD(String entity, String module, String e) throws Exception {
+ DDD ddd = new DDD(module, e);
+ ddd.entityPrefix = entity;
+
+ make(ddd, new POMongoGen(), vo -> ddd.po = vo );
+ make(ddd, new EntityGen(), vo -> ddd.entity = vo );
+ make(ddd, new DTOGen(), vo -> ddd.dto = vo);
+
+ make(ddd, new ConvertGen(), vo -> ddd.convert = vo);
+ make(ddd, new AssemblerGen(), vo -> ddd.assembler = vo);
+ make(ddd, new FactoryGen(), vo -> ddd.factory = vo);
+
+ make(ddd, new RepoMongoGen(), vo -> ddd.repo = vo);
+ make(ddd, new RepositoryMongoGen(), vo -> ddd.repository = vo);
+ make(ddd, new ServiceGen(), vo -> ddd.service = vo);
+
+ List list = ddd.mongoList();
+ for (ClassVO classVO : list) {
+ if(classVO == null) continue;
+ JavaFile javaFile = JavaFile.builder(classVO.packagePath, classVO.builder.build())
+ .build();
+ System.out.println("路径:::" + Paths.get(classVO.folderPath) + "/" + classVO.packagePath);
+ javaFile.writeTo(System.out);
+ javaFile.writeTo(Paths.get(classVO.folderPath));
+ }
+ }
+
+ private static ClassVO make(DDD ddd, IClassGenerate ig, Consumer c) throws Exception {
+ Builder builder = ig.builder(ddd, null, null);
+ ig.addAuthor(builder);
+
+ ClassVO vo = ClassVO.builder()
+ .builder(builder)
+ .className(ig.className(ddd))
+ .folderPath(ig.folerPath(ddd))
+ .packagePath(ig.packagePath(ddd))
+ .build();
+
+ c.accept(vo);
+ return vo;
+ }
+}
diff --git a/src/test/java/rp/lee/jpa/entity/ColumnStyle.java b/src/test/java/rp/lee/jpa/entity/ColumnStyle.java
new file mode 100644
index 0000000..5479b1c
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/entity/ColumnStyle.java
@@ -0,0 +1,10 @@
+package rp.lee.jpa.entity;
+
+public enum ColumnStyle {
+ /**原值*/
+ normal,
+ /**下划线转驼峰*/
+ lowercaseTocamelhump;
+
+ public static ColumnStyle defaultColumnStyle = lowercaseTocamelhump;
+}
diff --git a/src/test/java/rp/lee/jpa/entity/Utils.java b/src/test/java/rp/lee/jpa/entity/Utils.java
new file mode 100644
index 0000000..4255ed5
--- /dev/null
+++ b/src/test/java/rp/lee/jpa/entity/Utils.java
@@ -0,0 +1,60 @@
+package rp.lee.jpa.entity;
+
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.sql.Types;
+import java.util.Date;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+
+public class Utils {
+ public static String tableNameToEntityName(String tableName) {
+ String[] split = StringUtils.split(tableName, '_');
+ StringBuffer buffer = new StringBuffer();
+ for (String string : split) {
+ buffer.append(StringUtils.capitalize(string));
+ }
+
+ return buffer.toString();
+ }
+
+ public static String columnNameToFieldName(String columnName, ColumnStyle columnStyle) {
+ if(ColumnStyle.normal == columnStyle) {
+ return columnName;
+ } else if(ColumnStyle.lowercaseTocamelhump == columnStyle) {
+ columnName = StringUtils.lowerCase(columnName);
+ //user_id_string ==> userIdString
+ String[] split = StringUtils.split(columnName, '_');
+ if(split.length <= 1) return columnName;
+
+ StringBuffer buffer = new StringBuffer(split[0]);
+ for (int i = 1; i < split.length; i++) {
+ buffer.append(StringUtils.capitalize(split[i]));
+ }
+
+ return buffer.toString();
+ }
+
+ //other
+ return columnName;
+ }
+
+ public static Type dataTypeToFieldType(String columnName, int dataType) {
+ if (ArrayUtils.contains(new int[] { Types.TINYINT, Types.SMALLINT, Types.INTEGER }, dataType)) {// int.class
+ return Integer.class;
+ } else if (ArrayUtils.contains(new int[] { Types.FLOAT, Types.DOUBLE, Types.NUMERIC, },
+ dataType)) {// double.class
+ return Double.class;
+ } else if (ArrayUtils.contains(new int[] {Types.DECIMAL },
+ dataType)) {// double.class
+ return BigDecimal.class;
+ } else if (ArrayUtils.contains(new int[] { Types.BIGINT }, dataType)) {
+ return Long.class;
+ } else if (ArrayUtils.contains(new int[] { Types.DATE, Types.TIME, Types.TIMESTAMP }, dataType)) {
+ return Date.class;
+ } else {
+ return String.class;
+ }
+ }
+}