IDEA 2019.2.2
Java 8
根据不同的数据库数据去创建实体类,就要提取每个实体类的共同的特征,也就是先把它们共同的代码部分写出来,而需要更改的部分用一个不同的标记去进行替换。比如如下两个类:
package cn.hp.entity;
public class Role {
private Integer id;
private String roleType;
}
package cn.hp.entity;
public class User {
private String uusername;
private String upassword;
}
共同特征是
package cn.hp.entity;
public class 类名 {
多个属性
}
因为不同的项目包名可能不一样,所以包名也要更改,修改如下
package 包名.entity;
public class 类名 {
多个属性
}
好了,可以根据这个特征创建一个模板代码,这就需要有标记去替换要进行变化的代码部分,使用 ${} 方式去标记特定部分,做成模板如下:
package {packName}.entity;
public class{className} {
${propertyList}
}
根据 SQL 查询的内容去生成对应的实体类,就得获取到对应的字段名,在老师发的项目里的 DBUtil
类中的 query
方法中有这个关键的一条语句: ResultSetMetaData metaData = rst.getMetaData();
,rst
为 ResultSet
类型,获取结果集的元数据,里边有列名数据。在下面 query
方法代码中间的 while 语句块部分代码,代码内容如下:
public static List<Map> query(String sql, Object... obj) {
getConn();
try {
pst = conn.prepareStatement(sql);
System.out.println(sql);
for (int i = 0; i < obj.length; i++) {
System.out.println(obj[i]);
pst.setObject(i + 1, obj[i]);
}
rst = pst.executeQuery();
// 获取元数据
ResultSetMetaData metaData = rst.getMetaData();
List<Map> list = new ArrayList<>();
while (rst.next()) {
Map map = new HashMap();
// 获取查询的元数据的总列数
int count = metaData.getColumnCount();
// 列数是从1开始
for (int i = 1; i <= count; i++) {
// 获取当前列的列名
String key = metaData.getColumnLabel(i);
// 获取记录的值
Object value = rst.getObject(key);
map.put(key, value);
}
list.add(map);
}
return list;
} catch (SQLException e) {
e.printStackTrace();
} finally {
close();
}
return null;
}
有了这个方法,下面这条 SQL 语句获取表中所有表的字段名、类型等数据。
select TABLE_NAME tableName,COLUMN_NAME columnName,DATA_TYPE dataType,COLUMN_COMMENT columnComment from information_schema.`COLUMNS` where TABLE_SCHEMA = ? and TABLE_NAME=?
现在开始写反向创建实体类的代码部分,功能请看注释
/**
* 生成代码
*
* @param packName 包名
* @param dbName 数据库名
* @param tableName 表名
*/
public static String generate(String packName, String dbName, String tableName){
// 实体类模板
String classTemplate = "package {packName}.entity;\n" +
"\n" +
"public class{className} {\n" +
" {propertyList}\n" +
"}";
// 查询表结构
List<Map> list = DBUtil.query("select TABLE_NAME tableName,COLUMN_NAME columnName,DATA_TYPE dataType,COLUMN_COMMENT columnComment from information_schema.`COLUMNS` where TABLE_SCHEMA = ? and TABLE_NAME=?", dbName, tableName);
// 根据查询到的表结构,获取字段名、字段类型
// 进行生成拼接实体类的属性
StringBuffer propertyList = new StringBuffer();
for (Map map : list) {
// 数据类型
String type = map.get("dataType").toString();
// 属性名
String property = (String) map.get("columnName");
propertyList.append("\tprivate " + convertDataType(type) + " " + property + ";\n");
}
// 把模板的对应的标签代码替换成生成的Java代码
classTemplate = classTemplate.replace("{packName}", packName)
.replace("{className}", toUpper(tableName))
.replace("{propertyList}", propertyList.toString());
// 返回生成代码
return classTemplate;
}
/**
* 转化数据类型(将SQL中的数据类型转为Java的数据类型)
*
* @param dataType SQL中的数据类型
* @return
*/
public static String convertDataType(String dataType) {
switch (dataType) {
case "varchar":
case "longtext":
case "text":
return "String";
case "double":
return "Double";
case "int":
case "tinyint":
return "Integer";
case "bigint":
return "Long";
case "datetime":
case "timestamp":
case "Date":
return "Date";
case "decimal":
return "BigDecimal";
default:
return "";
}
}
/**
* 开头字母转为大写
*
* @param s1
* @return
*/
public static String toUpper(String s1) {
String r = "";
//以_为分隔符,将单词分开
String[] a = s1.split("_");
String[] b = new String[a.length + 1];
for (int i = 0; i < a.length; i++) {
//substring(0,1)首字母,toUpperCase()大写
b[i] = a[i].substring(0, 1).toUpperCase() + a[i].substring(1, a[i].length());
r = r + b[i];
}
return r;
}
以上关键功能已经做好了,主要开始保存生成的代码了
public static void main(String[] args) {
String packName = "cn.hp";
String dbName = "test";
String tableName = "userinfo";
// 生成 test 数据库中的 userinfo 表的实体类代码
String code = generate(packName, dbName, tableName);
// 保存文件
saveFile(code, toUpper(tableName).concat(".java"));
}
/**
* 保存文件
*
* @param text 文件内容
* @param path 文件路径
*/
public static void saveFile(String text, String path) {
PrintWriter pw = null;
try {
// 保存成 utf-8 格式文件
pw = new PrintWriter(path, "UTF-8");
pw.write(text);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (pw != null) {
pw.close();
}
}
}
运行生成代码,生成实体类 .java 文件
《Java 中反向生成实体类思路和步骤》有1条评论