数据库字段转Java实体类/支持lombok/支持swagger/支持mybatis
深圳的开发者
数据库表字段转Java类
工具类/Lombok/Swagger/MybatisPlus
JDBC连接数据库->根据库名->查询所有表信息->查询所有表字段信息->组装数据
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 数据库实体类
* jdbc查询数据库信息 用Stringbuild组装实体类数据
* @author luokangtao
* @create 2021-03-30 15:42
*/
@Slf4j
public class TableToPoUtil {
// 是否需要导入包java.util.Date
private boolean fUtil = false;
// 是否需要导入包java.math.BigDecimal
private boolean fMath = false;
// 是否用到lombok
private boolean fLombok = false;
//是否用到swagger
private boolean fSwagger = false;
//是否用到mybatisplus注解
private boolean fMybatisPlus = false;
//下载地址
private String url;
/**
* 数据库生成实体类
*
* @param ip ip地址
* @param port 端口号
* @param databaseName 数据库名
* @param username 帐号
* @param password 密码
* @param fLombok 是否启用lombok注解
* @param fSwagger 是否启用swagger注解
*/
public TableToPoUtil(String ip, String port, String databaseName, String username,
String password, boolean fLombok, boolean fSwagger,boolean fMybatisPlus,String url) {
//1.创建数据库连接
JdbcTemplate jdbcTemplate = init(ip, port, databaseName, username, password);
//2.查询当前库所有的表
List<Table> tableList = getTableNames(databaseName, jdbcTemplate);
if (!tableList.isEmpty()) {
//3.查询所有的字段名称/字段类型/字段备注 key:表名 value:表字段所有信息
Map<String, List<TableField>> tableFieldMaps = getTableFields(databaseName, jdbcTemplate, tableList);
this.fLombok = fLombok;
this.fSwagger = fSwagger;
this.fMybatisPlus = fMybatisPlus;
this.url = url;
//4.生成实体类
parse(databaseName,tableList, tableFieldMaps);
}
}
/**
* 解析处理(生成实体类主体代码)
*
* @param databaseName
* @param tableList 表集合
* @param tableFieldMaps 表字段
*/
private void parse(String databaseName, List<Table> tableList, Map<String, List<TableField>> tableFieldMaps) {
for (Map.Entry<String, List<TableField>> entry : tableFieldMaps.entrySet()) {
String tableName = entry.getKey();
List<TableField> fieldList = entry.getValue();
StringBuilder sb = new StringBuilder();
fUtil = fieldList.stream().anyMatch(f -> "datetime".equalsIgnoreCase(f.getTableFieldType())
|| "date".equalsIgnoreCase(f.getTableFieldType())
|| "smalldatetime".equalsIgnoreCase(f.getTableFieldType())
|| "time".equalsIgnoreCase(f.getTableFieldType()));
fMath = fieldList.stream().anyMatch(f -> "money".equalsIgnoreCase(f.getTableFieldType())
|| "decimal".equalsIgnoreCase(f.getTableFieldType())
|| "smallmoney".equalsIgnoreCase(f.getTableFieldType())
|| "numeric".equalsIgnoreCase(f.getTableFieldType()));
//1.导包
importPackage(sb);
//2.注解
processAnnotation(sb, tableList, tableName);
//开始语句
sb.append("public class ").append(initcap(underline2Camel(tableName))).append(" {\r\n");
//组装字段
processAllAttrs(sb, fieldList);
//组装属性
processAllMethod(sb, fieldList);
//结束语句
sb.append("}\r\n");
log.info(sb.toString()+"\r\n");
//导出数据
exportContent(sb.toString(),databaseName,tableName);
}
}
//导出java类
private void exportContent(String content,String databaseName, String tablename) {
String fileUrl = this.url + "//" + databaseName + "//";
File file = new File(fileUrl);
if( ! file.exists()){
log.info("======> 当前路径不存在:[{}] ,进行创建操作",fileUrl);
file.mkdirs();
}
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(fileUrl + initcap(underline2Camel(tablename)) + ".java");
} catch (IOException e) {
log.error("======> 导出异常IOException:{} ",e.getMessage());
}
PrintWriter pw = new PrintWriter(fileWriter);
pw.println(content);
pw.flush();
pw.close();
}
//2.注解
private void processAnnotation(StringBuilder sb, List<Table> tableList, String tableName) {
if (this.fLombok) {
sb.append("@Data\r\n");
}
if (this.fSwagger) {
String tableComment = "";
for (Table table : tableList) {
if (table.getTableName().equals(tableName)) {
tableComment = table.tableComment;
break;
}
}
sb.append("@ApiModel(description = \"")
.append(tableComment)
.append("\")\r\n");
}
if(this.fMybatisPlus){
sb.append("@TableName(value = \"")
.append(tableName)
.append("\")\r\n");
}
}
//1.导包
private void importPackage(StringBuilder sb) {
if (this.fUtil) {
sb.append("import java.util.Date;\r\n");
}
if (this.fMath) {
sb.append("import java.math.BigDecimal;\r\n");
}
if (this.fSwagger) {
sb.append("import io.swagger.annotations.ApiModel;\r\n");
sb.append("import io.swagger.annotations.ApiModelProperty;\r\n");
}
if (this.fMybatisPlus) {
sb.append("import com.baomidou.mybatisplus.annotation.TableField;\r\n");
sb.append("import com.baomidou.mybatisplus.annotation.TableName;\r\n");
}
if (this.fLombok) {
sb.append("import lombok.Data;\r\n\r\n");
}
}
/**
* 生成所有的方法
*
* @param sb
* @param fieldList
*/
private void processAllMethod(StringBuilder sb, List<TableField> fieldList) {
if (!this.fLombok) {
for (TableField tableField : fieldList) {
String tableFieldType = tableField.tableFieldType;
String tableFieldName = tableField.getTableFieldName();
sb.append("\tpublic ")
.append(sqlType2JavaType(tableFieldType))
.append(" get")
.append(initcap(tableFieldName))
.append("(){\r\n");
sb.append("\t\treturn ")
.append(tableFieldName)
.append(";\r\n");
sb.append("\t}\r\n");
sb.append("\tpublic void set")
.append(initcap(tableFieldName))
.append("(")
.append(sqlType2JavaType(tableFieldType))
.append(" ")
.append(tableFieldName)
.append("){\r\n");
sb.append("\t\tthis.")
.append(tableFieldName)
.append("=")
.append(tableFieldName)
.append(";\r\n");
sb.append("\t}\r\n");
}
}
}
/**
* 解析输出属性
* @return
*/
private void processAllAttrs(StringBuilder sb, List<TableField> fieldList) {
for (TableField tableField : fieldList) {
String tableFieldName = tableField.getTableFieldName();
String tableFieldType = tableField.getTableFieldType();
String tableFieldComment = tableField.getTableFieldComment();
if(this.fMybatisPlus){
sb.append("\t@TableField(value = \"")
.append(tableFieldName)
.append("\")\r\n");
}
if (this.fSwagger) {
sb.append("\t@ApiModelProperty(value = \"")
.append(tableFieldComment)
.append("\")\r\n");
}
sb.append("\tprivate ")
.append(sqlType2JavaType(tableFieldType))
.append(" ")
.append(underline2Camel(tableFieldName))
.append(";\r\n");
}
}
/**
* sql的类型 转成 java类型
*
* @param sqlType sql类型
* @return java类型
*/
private String sqlType2JavaType(String sqlType) {
if ("bit".equalsIgnoreCase(sqlType)) {
return "Boolean";
} else if ("binary".equalsIgnoreCase(sqlType)
|| "image".equalsIgnoreCase(sqlType)
|| "varbinary".equalsIgnoreCase(sqlType)) {
return "Byte[]";
} else if ("smallint".equalsIgnoreCase(sqlType)
|| "tinyint".equalsIgnoreCase(sqlType)) {
return "Short";
} else if ("int".equalsIgnoreCase(sqlType)
|| "mediumint".equals(sqlType)) {
return "Integer";
} else if ("bigint".equalsIgnoreCase(sqlType)) {
return "Long";
} else if ("real".equalsIgnoreCase(sqlType)
|| "float".equalsIgnoreCase(sqlType)) {
return "Double";
} else if ("money".equalsIgnoreCase(sqlType)
|| "decimal".equalsIgnoreCase(sqlType)
|| "smallmoney".equalsIgnoreCase(sqlType)
|| "numeric".equalsIgnoreCase(sqlType)) {
return "BigDecimal";
} else if ("varchar".equalsIgnoreCase(sqlType)
|| "char".equalsIgnoreCase(sqlType)
|| "nvarchar".equalsIgnoreCase(sqlType)
|| "nchar".equalsIgnoreCase(sqlType)
|| "text".equalsIgnoreCase(sqlType)
|| "mediumtext".equalsIgnoreCase(sqlType)
|| "ntext".equalsIgnoreCase(sqlType)
|| "uniqueidentifier".equalsIgnoreCase(sqlType)
|| "set".equalsIgnoreCase(sqlType)) {
return "String";
} else if (
"timestamp".equalsIgnoreCase(sqlType)
|| "date".equalsIgnoreCase(sqlType)
|| "smalldatetime".equalsIgnoreCase(sqlType)
|| "datetime".equalsIgnoreCase(sqlType)) {
return "Date";
} else if ("time".equalsIgnoreCase(sqlType)) {
return "Time";
} else {
log.info("============> 特殊的字段类型:{} \r\n ",sqlType);
}
return null;
}
/**
* 把输入字符串的首字母改成大写
*
* @param str 需要转的字符串
* @return 首字母大写
*/
private String initcap(String str) {
char[] ch = str.toCharArray();
if (ch[0] >= 'a' && ch[0] <= 'z') {
ch[0] = (char) (ch[0] - 32);
}
return new String(ch);
}
/**
* 下划线转换为驼峰
*
* @param line 下划线字符串
* @param firstIsUpperCase 首字母是否转换为大写
* @return 驼峰
*/
private String underline2Camel(String line, boolean... firstIsUpperCase) {
String str = "";
if (line == null || "".equals(line)) {
return str;
} else {
StringBuilder sb = new StringBuilder();
String[] strArr;
// 不包含下划线,且第二个参数是空的
if (!line.contains("_") && firstIsUpperCase.length == 0) {
sb.append(line.substring(0, 1).toLowerCase()).append(line.substring(1));
str = sb.toString();
} else if (!line.contains("_") && firstIsUpperCase.length != 0) {
if (!firstIsUpperCase[0]) {
sb.append(line.substring(0, 1).toLowerCase()).append(line.substring(1));
str = sb.toString();
} else {
sb.append(line.substring(0, 1).toUpperCase()).append(line.substring(1));
str = sb.toString();
}
} else if (line.contains("_") && firstIsUpperCase.length == 0) {
strArr = line.split("_");
for (String s : strArr) {
sb.append(s.substring(0, 1).toUpperCase()).append(s.substring(1));
}
str = sb.toString();
str = str.substring(0, 1).toLowerCase() + str.substring(1);
} else if (line.contains("_") && firstIsUpperCase.length != 0) {
strArr = line.split("_");
for (String s : strArr) {
sb.append(s.substring(0, 1).toUpperCase()).append(s.substring(1));
}
if (!firstIsUpperCase[0]) {
str = sb.toString();
str = str.substring(0, 1).toLowerCase() + str.substring(1);
} else {
str = sb.toString();
}
}
}
return str;
}
/**
* 查询所有字段信息
*
* @param databaseName 数据库名
* @param jdbcTemplate 数据库驱动
* @param tableList 表数据
* @return
*/
private Map<String, List<TableField>> getTableFields(String databaseName, JdbcTemplate jdbcTemplate, List<Table> tableList) {
Map<String, List<TableField>> maps = new HashMap<>();
for (Table table : tableList) {
StringBuilder sql = new StringBuilder();
sql.append(" SELECT ")
.append(" COLUMN_NAME AS tableFieldName , DATA_TYPE AS tableFieldType , COLUMN_COMMENT AS tableFieldComment ")
.append(" FROM ")
.append(" information_schema.columns ")
.append(" WHERE table_schema = '")
.append(databaseName)
.append("'")
.append("AND table_name = '")
.append(table.tableName)
.append("'");
List<TableField> fieldList = jdbcTemplate.query(sql.toString(), (resultSet, i) -> new TableField(resultSet.getString(1)
, resultSet.getString(2)
, resultSet.getString(3)));
maps.put(table.tableName, fieldList);
}
return maps;
}
/**
* 查询所有表信息
*
* @param databaseName 库名
* @param jdbcTemplate 连接驱动
* @return
*/
private List<Table> getTableNames(String databaseName, JdbcTemplate jdbcTemplate) {
StringBuilder sql = new StringBuilder();
sql.append(" SELECT ")
.append(" TABLE_NAME AS tableName , TABLE_COMMENT AS tableComment ")
.append(" FROM ")
.append(" information_schema.TABLES ")
.append(" WHERE TABLE_SCHEMA = '")
.append(databaseName)
.append("'");
return jdbcTemplate.query(sql.toString(), (resultSet, i) -> new Table(resultSet.getString(1)
, resultSet.getString(2)));
}
//表信息
@Data
private class Table {
public Table(String tableName, String tableComment) {
this.tableName = tableName;
this.tableComment = tableComment;
}
//表名
private String tableName;
//表注释
private String tableComment;
}
//表字段信息
@Data
private class TableField {
public TableField(String tableFieldName, String tableFieldType, String tableFieldComment) {
this.tableFieldName = tableFieldName;
this.tableFieldType = tableFieldType;
this.tableFieldComment = tableFieldComment;
}
//表字段名
private String tableFieldName;
//表字段类型
private String tableFieldType;
//表字段注释
private String tableFieldComment;
}
/**
* 初始化JdbcTemplate
* @return 数据库jdbc连接
*/
public JdbcTemplate init(String ip, String port, String databaseName, String username, String password) {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://" + ip + ":" + port + "/" + databaseName);
dataSource.setUsername(username);
dataSource.setPassword(password);
return new JdbcTemplate(dataSource);
}
}
调用案例 (图)
@PostConstruct
public void tableToPo(){
//1.数据库地址 2.数据库端口号 3.数据库名 4.数据库帐号 5.数据库密码
//6.开启lombok注解 7.开启swagger注解 8.开启mybatisplus注解 9.java类存放地址
new TableToPoUtil("122.**.**.117",
"3306",
"fengtaokeji",
"root",
"*********",
true,
true,
true,
"d://test");
}
按照这种思路还可以写转xml/service/controller
有时间的话作者会去写下,方便于开发者快速开发