import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 反向生成Mysql数据库表到Java实体
* @author
*
*/
public class GenerateEntityMysql {
private static final Logger log = LoggerFactory.getLogger(GenerateEntityMysql.class);
/*
* 注意:需要同时生成 Mapper 时,请先 refresh F5 实体包,然后再 refresh F5 Mapper 包,不然可能出现报错(找不到实体文件)!!!
*
* */
private String packagePath = "com.demo.entity.test"; // 指定实体生成所在包的路径,例如:com.demo.entity
private String mapperPackagePath = "com.demo.mapper.test"; // 指定实体对应 Mapper 接口所在包的路径,例如:com.demo.mapper
private boolean mapperFlag = true; // 是否同时生成 Mapper 接口文件,默认为是
private String authorName = "test"; // 作者名
private String[] tableNames = {"t_user"}; // null 时,生成所有表的实体类;也可以指定生成某些表的实体类,例如:{"t_user", "t_user", ...}
// 数据库连接
private static final String URL = "jdbc:mysql://127.0.0.1:3306/demo";
private static final String NAME = "root";
private static final String PASS = "root";
private static final String DRIVER = "com.mysql.jdbc.Driver";
private Connection conn;
private PreparedStatement ps;
private ResultSetMetaData rsmd;
private DatabaseMetaData dmd;
private ResultSet rs;
public GenerateEntityMysql() {
String[] colNames; // 列名数组
String[] colTypes; // 列名类型数组
int[] colSizes; // 列名大小数组
boolean i_util = false; // 是否需要导入包java.util.*
boolean i_sql = false; // 是否需要导入包java.sql.*
boolean i_auto_increment = false; // 自增长
String primary = ""; // 主键字段
try {
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL, NAME, PASS);
if (CommUtils.isNull(tableNames)) {
dmd = conn.getMetaData();
rs = dmd.getTables(null, "%", "%", new String[] { "TABLE" });
List<String> list = new ArrayList<String>();
while (rs.next()) {
list.add(rs.getString("TABLE_NAME"));
}
tableNames = list.toArray(new String[]{});
}
if (CommUtils.isNull(tableNames)) {
log.info("没有找到任何相关的表");
}else{
for (String tableName : tableNames) {
String sql = "select * from " + tableName;
ps = conn.prepareStatement(sql);
rsmd = ps.getMetaData();
int size = rsmd.getColumnCount(); // 统计列
colNames = new String[size];
colTypes = new String[size];
colSizes = new int[size];
for (int i = 0; i < size; i++) {
colNames[i] = rsmd.getColumnName(i + 1);
colTypes[i] = rsmd.getColumnTypeName(i + 1);
if (rsmd.isAutoIncrement(i + 1)) {
i_auto_increment = true;
primary = rsmd.getColumnName(i + 1);
}
if (colTypes[i].equalsIgnoreCase("datetime")) {
i_util = true;
}
if (colTypes[i].equalsIgnoreCase("image") || colTypes[i].equalsIgnoreCase("text")) {
i_sql = true;
}
colSizes[i] = rsmd.getColumnDisplaySize(i + 1);
}
String content = parse(tableName, colNames, colTypes, colSizes, i_util, i_sql, i_auto_increment, primary);
generateEntity(tableName, content);
if(mapperFlag){
String mapperContent = parseMapper(tableName);
generateMapper(tableName, mapperContent);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(ps != null){
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn != null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 生成实体
*
* @author
*
*/
private void generateEntity(String tableName, String content) {
try {
File directory = new File("");
// log.info("绝对路径:"+directory.getAbsolutePath());
// log.info("相对路径:"+directory.getCanonicalPath());
// String path = this.getClass().getResource("").getPath();
File dir = new File(directory.getAbsolutePath() + "/src/main/java/" + this.packagePath.replace(".", "/"));
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(directory.getAbsolutePath() + "/src/main/java/" + this.packagePath.replace(".", "/") + "/"
+ upperCamelCase(tableName) + ".java");
if (!dir.exists()) {
dir.createNewFile();
}
log.info(tableName + " 表对应实体文件路径:" + file);
PrintWriter pw = new PrintWriter(file);
pw.println(content);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 生成 Mapper 接口文件
*
* @author
*
*/
private void generateMapper(String tableName, String content) {
try {
File directory = new File("");
File dir = new File(directory.getAbsolutePath() + "/src/main/java/" + this.mapperPackagePath.replace(".", "/"));
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(directory.getAbsolutePath() + "/src/main/java/" + this.mapperPackagePath.replace(".", "/") + "/I" + upperCamelCase(tableName) + "Mapper.java");
if (!dir.exists()) {
dir.createNewFile();
}
log.info(tableName + " 表对应Mapper文件路径:" + file);
PrintWriter pw = new PrintWriter(file);
pw.println(content);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 分析数据,生产文件所需内容
*
* @author
*
*/
private String parse(String tableName, String[] colNames, String[] colTypes, int[] colSizes, boolean i_util,
boolean i_sql, boolean i_auto_increment, String primary) {
StringBuffer sb = new StringBuffer();
sb.append("package ").append(this.packagePath).append(";\n\n");
sb.append("import java.io.Serializable;\n\n");
// 判断是否导入工具包
if (i_util) {
sb.append("import java.util.Date;\n");
}
if (i_sql) {
sb.append("import java.sql.*;\n");
}
if (i_auto_increment) {
sb.append("import javax.persistence.GeneratedValue;\n");
sb.append("import javax.persistence.GenerationType;\n");
sb.append("import javax.persistence.Id;\n\n");
}
// 注释部分
sb.append("/**\n * \n * ")
.append(tableName)
.append(" 实体类\n")
.append(" *\n * @date ")
.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS ").format(new Date()))
.append("\n * @author ")
.append(this.authorName)
.append("\n")
.append(" */ \n");
// 实体部分
sb.append("public class ")
.append(upperCamelCase(tableName))
.append(" implements Serializable {\n\n")
.append("\tprivate static final long serialVersionUID = 1L;\n\n");
processAllAttrs(colNames, colTypes, primary, sb); // 属性
sb.append("\n");
processAllMethod(colNames, colTypes, sb); // get/set方法
sb.append("}");
return sb.toString();
}
/**
* 生产文件所需内容
*
* @author
*
*/
private String parseMapper(String tableName) {
StringBuffer sb = new StringBuffer();
sb.append("package ").append(this.mapperPackagePath).append(";\n\n");
sb.append("import ").append(this.packagePath).append(".").append(upperCamelCase(tableName)).append(";\n\n");
// 导入相关包
sb.append("import tk.mybatis.mapper.common.Mapper;\n");
sb.append("import tk.mybatis.mapper.common.MySqlMapper;\n\n");
// 注释部分
sb.append("/**\n * \n * ")
.append("I")
.append(upperCamelCase(tableName))
.append("Mapper 接口\n")
.append(" *\n * @date ")
.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS ").format(new Date()))
.append("\n * @author ")
.append(this.authorName)
.append("\n")
.append(" */ \n");
// 实体部分
sb.append("public interface I")
.append(upperCamelCase(tableName))
.append("Mapper extends Mapper<")
.append(upperCamelCase(tableName))
.append(">, MySqlMapper<")
.append(upperCamelCase(tableName))
.append("> {\n\n");
sb.append("}");
return sb.toString();
}
/**
* 生产所有属性
*
* @author
* @param colNames
* 列名数组
* @param colTypes
* 列名类型数组
* @param primary
* 主键字段
* @param sb
* 存放内容
* @return 所有属性内容
*/
private void processAllAttrs(String[] colNames, String[] colTypes, String primary, StringBuffer sb) {
for (int i = 0; i < colNames.length; i++) {
if (primary.equals(colNames[i])) {
sb.append("\t@Id\r\n");
sb.append("\t@GeneratedValue(strategy = GenerationType.IDENTITY)\r\n");
}
sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + lowerCamelCase(colNames[i]) + ";\r\n");
}
}
/**
* 生产所有set/get方法
*
* @author
* @param colNames
* 列名数组
* @param colTypes
* 列名类型数组
* @param sb
* 存放内容
* @return 所有set/get方法内容
*/
private void processAllMethod(String[] colNames, String[] colTypes, StringBuffer sb) {
for (int i = 0; i < colNames.length; i++) {
sb.append("\tpublic void set" + upperCamelCase(colNames[i]) + "(" + sqlType2JavaType(colTypes[i]) + " "
+ lowerCamelCase(colNames[i]) + "){\r\n");
sb.append("\t\tthis." + lowerCamelCase(colNames[i]) + " = " + lowerCamelCase(colNames[i]) + ";\r\n");
sb.append("\t}\r\n");
sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + upperCamelCase(colNames[i]) + "(){\r\n");
sb.append("\t\treturn " + lowerCamelCase(colNames[i]) + ";\r\n");
sb.append("\t}\r\n");
}
}
/**
* 大驼峰命名法
*
* @author
*
*/
public String upperCamelCase(String str) {
str = str.toLowerCase();
String result = "";
String[] names = str.split("_");
for (int i = 0; i < names.length; i++) {
result += names[i].substring(0, 1).toUpperCase() + names[i].substring(1);
}
return result;
}
/**
* 小驼峰命名法
*
* @author
*
*/
public String lowerCamelCase(String str) {
str = str.toLowerCase();
String result = "";
String[] names = str.split("_");
for (int i = 0; i < names.length; i++) {
if (i == 0)
result += names[i].substring(0, 1).toLowerCase() + names[i].substring(1);
else
result += names[i].substring(0, 1).toUpperCase() + names[i].substring(1);
}
return result;
}
/**
* 将SQL数据类型转换为Java数据类型
*
* @author
* @param sqlType
* SQL字段类型
* @return Java数据类型
*/
private String sqlType2JavaType(String sqlType) {
if (sqlType.equalsIgnoreCase("bit")) {
return "Boolean";
} else if (sqlType.equalsIgnoreCase("tinyint")) {
return "Integer";
} 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("decimal") || 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")) {
return "String";
} else if (sqlType.equalsIgnoreCase("datetime")) {
return "Date";
} else if (sqlType.equalsIgnoreCase("image")) {
return "Blod";
}
return null;
}
public static void main(String[] args) {
log.info(String.format("[%s] 开始生成实体类", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
long start = System.currentTimeMillis();
new GenerateEntityMysql();
long end = System.currentTimeMillis();
log.info(String.format("[%s] 结束生成实体类,耗时:%s毫秒", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), (end - start)));
}
}
反向生成Mysql数据库表到Java实体
最新推荐文章于 2023-10-08 09:44:06 发布