基本实现,还是继续改进,望各位大佬多提提意见,进行修改~
package cn.tedu.linli.util;
import org.apache.commons.dbcp2.BasicDataSource;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 通过set方法设置数据库连接信息(url,username,password,driver),
* 通过set方法设置要生成的实体类的包名(packageOutPath),
* 通过set方法设置实体类生成所在包的绝对路径(basePath),
* 通过set方法设置需要生成的表名(generateTables),若不设置,则默认为全部表
*/
public class MySqlGeneratorEntity {
//表名
private String tableName;
//列名数组
private String[] colNames;
//列名类型数组
private String[] colTypes;
//列名大小数组
private int[] colSizes;
//列名注释
private Map colNamesComment = new HashMap();
//是否需要导入包java.util.*
private boolean needUtil = false;
//是否需要导入包java.math.BigDecimal
private boolean needBigDecimal = false;
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final String SQL = "SELECT * FROM ";// 数据库操作
// 数据库配置信息
private String url = "jdbc:mysql://localhost:3306/linlidb?characterEncoding=utf8&serverTimezone=Asia/Shanghai";
private String username = "root";
private String password = "root";
private String driver = "com.mysql.jdbc.Driver";
//指定实体生成所在包的路径
private static String basePath = "F:/ideaProject/linli_clan/src/main/java/cn/tedu/linli/entity";
//指定包名
private String packageOutPath = "cn.tedu.linli.entity";
//作者名字
private String authorName = "何某人";
//指定需要生成的表的表名,全部生成设置为null
private String generateDataBase = null;
//主键
private static String pk;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getBasePath() {
return basePath;
}
public void setBasePath(String basePath) {
this.basePath = basePath;
}
public String getPackageOutPath() {
return packageOutPath;
}
public void setPackageOutPath(String packageOutPath) {
this.packageOutPath = packageOutPath;
}
public String getGenerateDataBase() {
return generateDataBase;
}
public void setGenerateDataBase(String generateDataBase) {
this.generateDataBase = generateDataBase;
}
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public MySqlGeneratorEntity() {
}
/**
* @description 生成class的所有内容
*/
private String parse() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("package " + packageOutPath + ";\r\n");//\r\n 回车换行
stringBuffer.append("\r\n");
// 判断是否导入工具包
stringBuffer.append("import java.io.Serializable" + ";\r\n");
if (needUtil == true) {
stringBuffer.append("import java.time.LocalDateTime;\r\n");
}
for (int i = 0; i < colNames.length; i++) {
String javaType = sqlTypeJavaType(colTypes[i]);
if (javaType == "BigDecimal" || "BigDecimal".equals(javaType)) {
needBigDecimal = true;
}
}
if (needBigDecimal) {
stringBuffer.append("import java.math.BigDecimal;\r\n");
}
stringBuffer.append("import java.util.Objects;\r\n");
// 注释部分
stringBuffer.append("/**\r\n");
stringBuffer.append(" * table name: " + tableName + "\r\n");
stringBuffer.append(" * author name: " + authorName + "\r\n");
stringBuffer.append(" * create time: " + SDF.format(new Date()) + "\r\n");
stringBuffer.append(" */ \r\n");
// 实体部分
String classImplements = " implements Serializable";
stringBuffer.append("public class " + underCamel(tableName, true) + classImplements + "{\r\n\r\n");
processAllAttrs(stringBuffer);// 属性
stringBuffer.append("\r\n");
processAllMethod(stringBuffer);// get set方法
processToString(stringBuffer);// toString方法
processEquals(stringBuffer);// equals方法
processHashCode(stringBuffer);// hashCode方法
stringBuffer.append("}\r\n");
return stringBuffer.toString();
}
/**
* @param stringBuffer
* @description 生成所有成员变量及注释
* @author paul
* @version V1.0
*/
private void processAllAttrs(StringBuffer stringBuffer) {
for (int i = 0; i < colNames.length; i++) {
if (colNamesComment.get(colNames[i]) != null && !"".equals(colNamesComment.get(colNames[i]))) {
stringBuffer.append("\t/**\r\n * " + colNamesComment.get(colNames[i]) + "\r\n */\r\n");
}
stringBuffer.append("\tprivate " + sqlTypeJavaType(colTypes[i]) + " " + colNames[i] + ";\r\n");
}
}
/**
* 重写toString()方法
*
* @param stringBuffer
*/
private void processToString(StringBuffer stringBuffer) {
stringBuffer.append("\t@Override\r\n\tpublic String toString() {\r\n");
stringBuffer.append("\t\treturn \"" + tableName + "[\" + \r\n");
for (int i = 0; i < colNames.length; i++) {
if (i != 0)
stringBuffer.append("\t\t\t\", ");
if (i == 0)
stringBuffer.append("\t\t\t\"");
stringBuffer.append(colNames[i] + "=\" + " + colNames[i]).append(" + \r\n");
if (i == colNames.length - 1) {
stringBuffer.append("\t\t\t\"]\";\r\n");
}
}
stringBuffer.append("\t}\r\n");
}
/**
* @param stringBuffer
* @description 生成equals()方法
* @author paul
* @version V1.0
*/
private void processEquals(StringBuffer stringBuffer) {
stringBuffer.append("\t@Override\r\n\tpublic boolean equals(Object o) {\r\n");
stringBuffer.append("\t\tif (this == o) return true;\r\n");
stringBuffer.append("\t\tif (o == null || getClass() != o.getClass()) return false;\r\n");
stringBuffer.append("\t\t" + underCamel(tableName, true) + " " + underCamel(tableName, true) + " = (" + underCamel(tableName, true) + ") o;\r\n");
stringBuffer.append("\t\treturn ");
for (int i = 0; i < colNames.length; i++) {
if (i != 0)
stringBuffer.append(" && ");
stringBuffer.append(colNames[i] + ".equals(" + underCamel(tableName, true) + "." + colNames[i] + ")");
}
stringBuffer.append(";\r\n");
stringBuffer.append("\t}\r\n");
}
/**
* @param stringBuffer
* @description 生成hashCode方法
* @author paul
* @version V1.0
*/
private void processHashCode(StringBuffer stringBuffer) {
stringBuffer.append("\t@Override\r\n\tpublic int hashCode() {\r\n");
stringBuffer.append("\t\treturn ");
stringBuffer.append("Objects.hash(");
for (int i = 0; i < colNames.length; i++) {
if (i != 0)
stringBuffer.append(" , ");
stringBuffer.append("" + colNames[i]);
}
stringBuffer.append(");\r\n");
stringBuffer.append("\t}\r\n");
}
/**
* @param stringBuffer
* @description 生成所有get/set方法
*/
private void processAllMethod(StringBuffer stringBuffer) {
for (int i = 0; i < colNames.length; i++) {
stringBuffer.append("\tpublic void set" + initCap(colNames[i]) + "(" + sqlTypeJavaType(colTypes[i]) + " "
+ colNames[i] + "){\r\n");
stringBuffer.append("\t\tthis." + colNames[i] + "=" + colNames[i] + ";\r\n");
stringBuffer.append("\t}\r\n");
stringBuffer.append("\tpublic " + sqlTypeJavaType(colTypes[i]) + " get" + initCap(colNames[i]) + "(){\r\n");
stringBuffer.append("\t\treturn " + colNames[i] + ";\r\n");
stringBuffer.append("\t}\r\n");
}
}
/**
* @param str 传入字符串
* @return
* @description 将传入字符串的首字母转成大写
*/
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 s
* @param fistCharToUpperCase 首字母是否大写
* @return
*/
private String underCamel(String s, boolean fistCharToUpperCase) {
String separator = "_";
String under = "";
s = s.toLowerCase().replace(separator, " ");
String sarr[] = s.split(" ");
for (int i = 0; i < sarr.length; i++) {
String w = sarr[i].substring(0, 1).toUpperCase() + sarr[i].substring(1);
under += w;
}
if (!fistCharToUpperCase) {
under = under.substring(0, 1).toLowerCase() + under.substring(1);
}
return under;
}
/**
* @return
* @description 查找sql字段类型所对应的Java类型
*/
private String sqlTypeJavaType(String sqlType) {
if (sqlType.equalsIgnoreCase("bit")) {
return "boolean";
} else if (sqlType.equalsIgnoreCase("tinyint")) {
return "byte";
} else if (sqlType.equalsIgnoreCase("smallint")) {
return "short";
} else if (sqlType.equalsIgnoreCase("int")) {
return "Integer";
} else if (sqlType.equalsIgnoreCase("bigint")) {
return "Long";
} else if (sqlType.equalsIgnoreCase("float")) {
return "float";
} else if (sqlType.equalsIgnoreCase("numeric")
|| sqlType.equalsIgnoreCase("real")
|| sqlType.equalsIgnoreCase("money")
|| sqlType.equalsIgnoreCase("smallmoney")) {
return "double";
} else if (sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("char")
|| sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nchar")
|| sqlType.equalsIgnoreCase("text") || sqlType.equalsIgnoreCase("longtext")) {
return "String";
} else if (sqlType.equalsIgnoreCase("datetime")) {
return "LocalDateTime";
} else if (sqlType.equalsIgnoreCase("image")) {
return "Blod";
} else if (sqlType.equalsIgnoreCase("decimal")) {
return "BigDecimal";
}
return null;
}
/**
* 功能:获取并创建实体所在的路径目录
*
* @return
*/
private static String pkgDirName() {
String dirName = basePath;
File dir = new File(dirName);
if (!dir.exists()) {
dir.mkdirs();
System.out.println("mkdirs dir 【" + dirName + "】");
}
return dirName;
}
/**
* @description 生成方法
*/
public void generate() throws Exception {
//与数据库的连接
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = null;
System.out.println("connect database success..." + connection);
//获取数据库的元数据
DatabaseMetaData db = connection.getMetaData();
//是否有指定生成表,有指定则直接用指定表,没有则全表生成
List<String> tableNames = new ArrayList<>();
//tableNames的初始化;
//从元数据中获取到所有的表名(catalog属性:限制目录, schemaPattern, tableNamePattern)
ResultSet resultSetDatabase= db.getTables(generateDataBase, null, null, new String[]{"TABLE"});
while (resultSetDatabase.next()) {
tableNames.add(resultSetDatabase.getString(3));
}
String tableSql;//查询表的sql
PrintWriter printWriter = null;
for (int j = 0; j < tableNames.size(); j++) {
tableName = tableNames.get(j);
tableSql = SQL + tableName;
System.out.println("tableSql:" + tableSql);
preparedStatement = connection.prepareStatement(tableSql);
ResultSetMetaData resultSetMetaData = preparedStatement.getMetaData();
ResultSet resultSet = connection.getMetaData().getPrimaryKeys(connection.getCatalog().toLowerCase(), null, tableName);
if (resultSet.next()) {
String primaryKey = resultSet.getString("COLUMN_NAME");
pk = primaryKey;
}
//获取表的元数据
int size = resultSetMetaData.getColumnCount();
//获取表的所有字段
colNames = new String[size];
//获取表的所有字段类型
colTypes = new String[size];
//获取表的所有字段注释
colSizes = new int[size];
//获取所需的信息
for (int i = 0; i < size; i++) {
colNames[i] = underCamel(resultSetMetaData.getColumnName(i + 1), false);//字段名改为驼峰命名
colTypes[i] = resultSetMetaData.getColumnTypeName(i + 1);
if (colTypes[i].equalsIgnoreCase("datetime")){
//判断是否为时间类型
needUtil = true;
}
colSizes[i] = resultSetMetaData.getColumnDisplaySize(i + 1);
}
//获取字段注释
ResultSet rsComment = preparedStatement.executeQuery("show full columns from " + tableName);
while (rsComment.next()) {
colNamesComment.put(underCamel(rsComment.getString("Field"), false), rsComment.getString("Comment"));
}
//解析生成实体java文件的所有内容
String content = parse();
//输出生成文件
String dirName = MySqlGeneratorEntity.pkgDirName();
String javaPath = dirName + "/" + underCamel(tableName, true) + ".java";
FileWriter fw = new FileWriter(javaPath);
printWriter = new PrintWriter(fw);
printWriter.println(content);
printWriter.flush();
System.out.println("create class 【" + tableName + "】");
}
if (printWriter != null)
printWriter.close();
}
}