update code generator

This commit is contained in:
luming 2021-04-19 17:09:45 +08:00
parent e10fa83f73
commit 0e7eb33349
12 changed files with 535 additions and 199 deletions

View File

@ -16,17 +16,11 @@ repositories {
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'com.baomidou:mybatis-plus-boot-starter:3.4.2'
implementation 'com.baomidou:mybatis-plus-generator:3.4.1'
implementation 'org.freemarker:freemarker:2.3.31'
implementation 'org.springframework.boot:spring-boot-configuration-processor'
implementation 'org.postgresql:postgresql:42.2.19'
implementation 'org.springframework.boot:spring-boot-configuration-processor:2.1.4.RELEASE'
// https://mvnrepository.com/artifact/org.projectlombok/lombok
implementation'org.projectlombok:lombok:1.18.20'
implementation 'org.projectlombok:lombok:1.18.20'
implementation 'org.yaml:snakeyaml:1.28'
implementation 'org.apache.commons:commons-lang3:3.12.0'
}
test {

View File

@ -1,7 +1,26 @@
package cn.rainss.codegenerator;
public class DDDGenerator {
public static void main(String[] args) {
import cn.rainss.codegenerator.utils.Column;
import cn.rainss.codegenerator.utils.DatabaseUtil;
import cn.rainss.codegenerator.utils.GenerateConfig;
import cn.rainss.codegenerator.utils.GeneratorUtil;
import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.SQLException;
import java.util.List;
public class DDDGenerator {
public static void main(String[] args) throws FileNotFoundException, SQLException, ClassNotFoundException {
GeneratorUtil.Generator();
// GeneratorUtil.package2Path(DatabaseUtil.getInstance().getConfig().getGenerate().packageName);
// List<String> timemail = DatabaseUtil.getInstance().getTable();
// List<Column> tm_user = DatabaseUtil.getInstance().getColumn("tm_content");
// Yaml yaml = new Yaml();
// InputStream resourceAsStream = DDDGenerator.class.getClass().getClassLoader().getResourceAsStream("config.yaml");
// GenerateConfig generate = yaml.loadAs(new FileInputStream(new File("src/main/resources/config.yaml")),GenerateConfig.class);
System.out.printf("1");
}
}

View File

@ -0,0 +1,52 @@
package cn.rainss.codegenerator.config;
import lombok.Data;
/**
* 数据库配置信息
*
* @author rainerosion
* @email: yushangwl@gmail.com
* @date 2021/4/19 10:50
*/
@Data
public class Config {
/**
* 驱动类
*/
public String driverClass;
/**
* 数据库用户名
*/
public String username;
/**
* 数据库密码
*/
public String password;
/**
* 数据库名
*/
public String catalog;
/**
* 数据库连接地址
*/
public String url;
/**
* 包名
*/
public String packageName;
/**
* 项目名
*/
public String projectName;
/**
* 表前缀
*/
public String tablePrefix;
}

View File

@ -1,6 +1,7 @@
package cn.rainss.codegenerator.utils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -12,7 +13,8 @@ import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ColumnClass {
@Builder
public class Column {
/**
* 表名称
*/
@ -32,9 +34,13 @@ public class ColumnClass {
/**
* 列的注释
*/
private String columnComment;
private String remarks;
/**
* 是否能为空值
*/
private Boolean nullAble;
/**
* java数据类型
*/
private String javaType;
}

View File

@ -0,0 +1,140 @@
package cn.rainss.codegenerator.utils;
import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.sql.*;
import java.util.LinkedList;
import java.util.List;
/**
* 数据库连接
*
* @author rainerosion
* @email: yushangwl@gmail.com
* @date 2021/4/19 9:24
*/
public class DatabaseUtil {
private static DatabaseUtil instance = null;
private DatabaseUtil() {
}
/**
* 获取数据库连接实例
*
* @return
*/
public static DatabaseUtil getInstance() {
if (instance == null) {
synchronized (DatabaseUtil.class) {
if (instance == null) {
instance = new DatabaseUtil();
}
}
}
return instance;
}
/**
* 获取配置文件信息
*
* @return
*/
public GenerateConfig getConfig() {
try {
Yaml yaml = new Yaml();
return yaml.loadAs(new FileInputStream(new File("src/main/resources/config.yaml")), GenerateConfig.class);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取Connection数据库连接对象
*
* @return
*/
public Connection getConnection() {
try{
GenerateConfig config = getConfig();
String classDriver = config.getGenerate().getDriverClass();
String url = config.getGenerate().getUrl();
String username = config.getGenerate().getUsername();
String password = config.getGenerate().getPassword();
if (config == null) {
//抛出异常
}
Class.forName(classDriver);
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
} catch (ClassNotFoundException | SQLException e){
e.printStackTrace();
}
return null;
}
/**
* 获取数据库元数据
*
* @return
* @throws SQLException
* @throws FileNotFoundException
* @throws ClassNotFoundException
*/
public DatabaseMetaData getMetaData() throws SQLException, FileNotFoundException, ClassNotFoundException {
return getConnection().getMetaData();
}
/**
* 获取数据库表
*
* @return
* @throws SQLException
* @throws FileNotFoundException
* @throws ClassNotFoundException
*/
public List<String> getTable() throws SQLException, FileNotFoundException, ClassNotFoundException {
LinkedList<String> tables = new LinkedList<>();
ResultSet resultSet = getMetaData().getTables(null, null, "%", new String[]{"TABLE"});
while (resultSet.next()) {
tables.add(resultSet.getString("TABLE_NAME"));
}
return tables;
}
/**
* 获取指定表的列信息
* @param tableName
* @return
* @throws SQLException
* @throws FileNotFoundException
* @throws ClassNotFoundException
*/
public List<Column> getColumn(String tableName) throws SQLException, FileNotFoundException, ClassNotFoundException {
LinkedList<Column> columns = new LinkedList<>();
ResultSet resultSet = getMetaData().getColumns(null, null, tableName, null);
while (resultSet.next()) {
String columnName = resultSet.getString("COLUMN_NAME");
String remarks = resultSet.getString("REMARKS");
boolean nullable = resultSet.getBoolean("NULLABLE");
int columnSize = resultSet.getInt("COLUMN_SIZE");
String typeName = resultSet.getString("TYPE_NAME");
columns.add(
Column.builder()
.tableName(tableName)
.columnName(GeneratorUtil.toCamelCase(columnName))
.remarks(remarks)
.columnSize(columnSize)
.columnType(typeName)
.nullAble(nullable)
.javaType(GeneratorUtil.getJavaType(GeneratorUtil.toLowerCase(typeName)))
.build()
);
}
return columns;
}
}

View File

@ -1,91 +0,0 @@
package cn.rainss.codegenerator.utils;
import cn.rainss.codegenerator.config.PGConfig;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class DatabaseUtils {
public DatabaseUtils(){}
public DatabaseUtils(PGConfig config){
}
/**
* 获取数据库元数据
*
* @return 元数据
* @throws Exception 异常
*/
private DatabaseMetaData getMetaData() throws Exception {
Class.forName(PGConfig.driverClass);
return DriverManager.getConnection(PGConfig.url,
PGConfig.username, PGConfig.password).getMetaData();
}
/**
* 获取库的所有表
*
* @return 所有表
*/
public List<String> getTables() {
List<String> tables = new ArrayList<>();
try {
ResultSet resultSet = getMetaData().getTables(PGConfig.catalog, null,
"%", new String[]{"TABLE"});
while (resultSet.next()) {
String tableName = resultSet.getString("TABLE_NAME");
tables.add(tableName);
}
resultSet.close();
} catch (Exception e) {
// log.error("Please check your database conf! {}", e.getMessage());
e.printStackTrace();
}
return tables;
}
/**
* 获取指定表的所有列
*
* @param tableName 表名
* @return 所有列的集合
*/
public List<ColumnClass> getColumns(String tableName) {
try (ResultSet resultSet = getMetaData().getColumns(PGConfig.catalog, null, tableName, "%")) {
return getColumns(resultSet, tableName);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取某列的结果集抽取
*
* @param resultSet 结果集
* @param tableName 表名
* @throws SQLException 异常
*/
private List<ColumnClass> getColumns(ResultSet resultSet, String tableName) throws SQLException {
List<ColumnClass> columns = new ArrayList<>();
while (resultSet.next()) {
String columnName = resultSet.getString("COLUMN_NAME");
String remarks = resultSet.getString("REMARKS");
Boolean nullAble = resultSet.getInt("NULLABLE") == 1;
columns.add(new ColumnClass(
tableName,
GenUtil.underlineToHump(columnName),
resultSet.getInt("COLUMN_SIZE"),
GenUtil.fieldConversion(resultSet.getString("TYPE_NAME")),
remarks, nullAble
));
}
return columns;
}
}

View File

@ -1,83 +0,0 @@
package cn.rainss.codegenerator.utils;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
/**
* 工具类
*
* @author echo
*/
@Slf4j
public class GenUtil {
private static final String UNDERLINE = "_";
private static final Map<String, String> MYSQL_TO_JAVA = new HashMap<>();
public static final String SUFFIX = ".java";
static {
MYSQL_TO_JAVA.put("VARCHAR", "java.lang.String");
MYSQL_TO_JAVA.put("BIGINT", "java.lang.Long");
MYSQL_TO_JAVA.put("DATE", "java.time.LocalDate");
MYSQL_TO_JAVA.put("FLOAT", "java.lang.Float");
MYSQL_TO_JAVA.put("TINYINT", "java.lang.Integer");
MYSQL_TO_JAVA.put("INT", "java.lang.Integer");
MYSQL_TO_JAVA.put("INT2", "java.lang.Short");
MYSQL_TO_JAVA.put("INT4", "java.lang.Integer");
MYSQL_TO_JAVA.put("INT8", "java.lang.Long");
MYSQL_TO_JAVA.put("BINARY", "java.lang.Byte");
MYSQL_TO_JAVA.put("SMALLINT", "java.lang.Short");
MYSQL_TO_JAVA.put("DATETIME", "java.time.LocalDateTime");
MYSQL_TO_JAVA.put("TIMESTAMP", "java.time.LocalDateTime");
MYSQL_TO_JAVA.put("BIT", "java.lang.Boolean");
}
/**
* 下划线命名转驼峰式命名
*
* @param para 下划线命名
* @return 驼峰式命名
*/
public static String underlineToHump(String para) {
StringBuilder result = new StringBuilder();
for (String s : para.split(UNDERLINE)) {
if (!para.contains("_")) {
result.append(s);
continue;
}
if (result.length() == 0) {
result.append(s.toLowerCase());
} else {
result.append(s.substring(0, 1).toUpperCase());
result.append(s.substring(1).toLowerCase());
}
}
return result.toString();
}
/**
* 下划线命名转驼峰式命名
*
* @param para 下划线命名
* @param firstCharChange 首字母是否转换
* @return 驼峰式命名
*/
public static String underlineToHump(String para, boolean firstCharChange) {
String result = underlineToHump(para);
return firstCharChange ? result.substring(0, 1).toUpperCase() + result.substring(1) : result;
}
/**
* 数据库字段转换
*
* @param mysqlDataType 数据库字段类型
* @return 转换结果
*/
public static String fieldConversion(String mysqlDataType) {
return MYSQL_TO_JAVA.getOrDefault(mysqlDataType, "Object");
}
}

View File

@ -0,0 +1,16 @@
package cn.rainss.codegenerator.utils;
import cn.rainss.codegenerator.config.Config;
import lombok.Data;
/**
* 配置信息
*
* @author rainerosion
* @email: yushangwl@gmail.com
* @date 2021/4/19 9:54
*/
@Data
public class GenerateConfig {
public Config generate;
}

View File

@ -0,0 +1,252 @@
package cn.rainss.codegenerator.utils;
import cn.rainss.codegenerator.config.Config;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 工具类
*
* @author echo
*/
public class GeneratorUtil {
// 类型映射
private final static Map<String, String> SQL_TYPE_TO_JAVA_TYPE = new HashMap<>();
// 文件后缀
private final static String SUFFIX = ".java";
private final static Config CONFIG = DatabaseUtil.getInstance().getConfig().getGenerate();
static {
SQL_TYPE_TO_JAVA_TYPE.put("bit", "Boolean");
SQL_TYPE_TO_JAVA_TYPE.put("bool", "Boolean");
// SQL_TYPE_TO_JAVA_TYPE.put("box","");
// SQL_TYPE_TO_JAVA_TYPE.put("bytea","");
SQL_TYPE_TO_JAVA_TYPE.put("char", "String");
// SQL_TYPE_TO_JAVA_TYPE.put("cidr","");
// SQL_TYPE_TO_JAVA_TYPE.put("circle","");
SQL_TYPE_TO_JAVA_TYPE.put("date", "LocalDate");
SQL_TYPE_TO_JAVA_TYPE.put("decimal", "BigDecimal");
SQL_TYPE_TO_JAVA_TYPE.put("float4", "Float");
SQL_TYPE_TO_JAVA_TYPE.put("float8", "Double");
// SQL_TYPE_TO_JAVA_TYPE.put("inet","");
SQL_TYPE_TO_JAVA_TYPE.put("int2", "Short");
SQL_TYPE_TO_JAVA_TYPE.put("int4", "Integer");
SQL_TYPE_TO_JAVA_TYPE.put("int8", "Long");
// SQL_TYPE_TO_JAVA_TYPE.put("interval","");
// SQL_TYPE_TO_JAVA_TYPE.put("json","");
// SQL_TYPE_TO_JAVA_TYPE.put("jsonb","");
// SQL_TYPE_TO_JAVA_TYPE.put("line","");
// SQL_TYPE_TO_JAVA_TYPE.put("lseg","");
// SQL_TYPE_TO_JAVA_TYPE.put("macaddr","");
SQL_TYPE_TO_JAVA_TYPE.put("money", "Double");
SQL_TYPE_TO_JAVA_TYPE.put("numeric", "BigDecimal");
// SQL_TYPE_TO_JAVA_TYPE.put("path","");
// SQL_TYPE_TO_JAVA_TYPE.put("point","");
// SQL_TYPE_TO_JAVA_TYPE.put("polygon","");
// SQL_TYPE_TO_JAVA_TYPE.put("serial2","");
// SQL_TYPE_TO_JAVA_TYPE.put("serial4","");
// SQL_TYPE_TO_JAVA_TYPE.put("serial8","");
SQL_TYPE_TO_JAVA_TYPE.put("text", "String");
SQL_TYPE_TO_JAVA_TYPE.put("time", "LocalTime");
SQL_TYPE_TO_JAVA_TYPE.put("timestamp", "LocalDateTime");
// SQL_TYPE_TO_JAVA_TYPE.put("timestamptz","");
// SQL_TYPE_TO_JAVA_TYPE.put("timetz","");
// SQL_TYPE_TO_JAVA_TYPE.put("tsquery","");
// SQL_TYPE_TO_JAVA_TYPE.put("tsvector","");
// SQL_TYPE_TO_JAVA_TYPE.put("txid_snapshot","");
SQL_TYPE_TO_JAVA_TYPE.put("uuid", "String");
// SQL_TYPE_TO_JAVA_TYPE.put("varbit","");
SQL_TYPE_TO_JAVA_TYPE.put("varchar", "String");
// SQL_TYPE_TO_JAVA_TYPE.put("xml","");
}
public static String toLowerCase(String str) {
if (StringUtils.isNotEmpty(str)) {
return str.toLowerCase();
}
return null;
}
public static String toUpperCase(String str) {
if (StringUtils.isNotEmpty(str)) {
return str.toUpperCase();
}
return null;
}
/**
* 下划线转驼峰
* user_name ----> userName
* userName ---> userName
*
* @param underlineStr 带有下划线的字符串
* @return 驼峰字符串
*/
public static String toCamelCase(String underlineStr) {
if (underlineStr == null) {
return null;
}
// 分成数组
char[] charArray = underlineStr.toCharArray();
// 判断上次循环的字符是否是"_"
boolean underlineBefore = false;
StringBuffer buffer = new StringBuffer();
for (int i = 0, l = charArray.length; i < l; i++) {
// 判断当前字符是否是"_",如果跳出本次循环
if (charArray[i] == 95) {
underlineBefore = true;
} else if (underlineBefore) {
// 如果为true代表上次的字符是"_",当前字符需要转成大写
buffer.append(charArray[i] -= 32);
underlineBefore = false;
} else {
// 不是"_"后的字符就直接追加
buffer.append(charArray[i]);
}
}
return buffer.toString();
}
/**
* 驼峰转 下划线
* userName ----> user_name
* user_name ----> user_name
*
* @param camelCaseStr 驼峰字符串
* @return 带下滑线的String
*/
public static String toUnderlineCase(String camelCaseStr) {
if (camelCaseStr == null) {
return null;
}
// 将驼峰字符串转换成数组
char[] charArray = camelCaseStr.toCharArray();
StringBuffer buffer = new StringBuffer();
//处理字符串
for (int i = 0, l = charArray.length; i < l; i++) {
if (charArray[i] >= 65 && charArray[i] <= 90) {
buffer.append("_").append(charArray[i] += 32);
} else {
buffer.append(charArray[i]);
}
}
return buffer.toString();
}
public static void Generator() throws SQLException, FileNotFoundException, ClassNotFoundException {
System.out.println("=== initialization Generator ===");
DatabaseUtil instance = DatabaseUtil.getInstance();
List<String> table = instance.getTable();
table.forEach(t -> {
System.out.println("<<<<< table" + t + " >>>>>");
try {
List<Column> column = instance.getColumn(t);
generatorPo(column,t);
System.out.println(1);
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
});
}
/**
* 根据key获取类型
* @param key
* @return
*/
public static String getJavaType(String key) {
return SQL_TYPE_TO_JAVA_TYPE.getOrDefault(key,"Object");
}
/**
* 生成po实体
*/
public static void generatorPo(List<Column> list,String table) throws IOException, TemplateException {
//如果有前缀去除
String className = table;
if (StringUtils.isNotEmpty(CONFIG.getTablePrefix())){
className = formatTableName(table);
}
// 类名首字母大写
className = toUpperCaseFist(className);
Configuration configuration = new Configuration(Configuration.VERSION_2_3_0);
Template template = configuration.getTemplate("src/main/resources/template/po.ftl");
String path = package2Path("/" + CONFIG.getProjectName() + "-server/" + CONFIG.getPackageName() + "/infrastructure/persistence/po/");
String filepath = path + className + SUFFIX;
// 文件夹不存在创建
if(!new File(path).exists()){
if (new File(path).mkdirs()){
System.out.println("PO 文件夹创建成功");
}
if(new File(filepath).createNewFile()){
System.out.println("=== PO:["+ className +" ] 创建成功 ===");
}
}
HashMap<String, Object> data = new HashMap<>();
data.put("package",CONFIG.getPackageName() + ".infrastructure.persistence.po");
data.put("table_name",table);
data.put("class_name",className);
data.put("columns",list);
File file = new File(filepath);
template.process(data,new FileWriter(file));
}
/**
* 首字母大写
* @param str
* @return
*/
public static String toUpperCaseFist(String str){
char[] chars = str.toCharArray();
chars[0] = toUpperCase(chars[0]);
return String.valueOf(chars);
}
/**
* 字符转成大写
*
* @param chars
* @return
*/
public static char toUpperCase(char chars) {
if (97 <= chars && chars <= 122) {
chars ^= 32;
}
return chars;
}
/**
* 包名转路径
* @param packageName
* @return
*/
public static String package2Path(String packageName){
return "src/main/java/" + packageName.replace(".", "/");
}
public static String formatTableName(String str){
//todo 待优化
return str.replaceFirst(CONFIG.getTablePrefix(),"");
}
}

View File

@ -1,12 +0,0 @@
application:
generate:
# 驱动类
driver-class: org.
# 用户名
username: root
# 密码
password: 123456
# 库名
catalog: generate
# 数据库地址
url: jdbc:postgresql://db.timemail.email:5432/timemail

View File

@ -0,0 +1,17 @@
generate:
# 驱动类
driverClass: org.postgresql.Driver
# 用户名
username: postgres
# 密码
password: timemail.email
# 库名
catalog: generate
# 数据库地址
url: jdbc:postgresql://db.timemail.email:5432/timemail
# 包名
packageName: cn.timemail.email
# 项目名称
projectName: timemail
# 前缀
tablePrefix: tm_

View File

@ -0,0 +1,26 @@
package ${package};
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
/**
* ${table_name}
*
* @author rainerosion
* @date ${.now?datetime}
*/
@Data
@Table(name = "${table_name}")
@Entity(name = "${table_name}")
public class ${class_name} implements Serializable {
<#list columns as column>
/**
* ${column.remarks!'Todo Add comments'}
*/
private ${column.javaType} ${column.columnName};
</#list>
}