在做毕业设计的时候封装dbutils做持久化,而对于实体类不知是要做组合关联还是直接根据数据库表直接生成。最后因为抛弃了外键的使用,所以就直接生成实体类了,在程序中自己控制数据冗余。因为实体类的属性和数据库表的字段一样,所以就写了一个工具类,直接生成需要的实体类。源码如下:
package com.entity.tool;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class DBEntityTool {
private final static Logger logger = LogManager
.getLogger(DBEntityTool.class);
private static DBEntityTool tool;
private Connection connection;
private Map types;
public static DBEntityTool getInstance(){
if(tool == null)
tool = new DBEntityTool();
return tool;
}
public DBEntityTool buildConnection(String url, String driver, String username,
String password) {
if(connection != null){
logger.error("已经buildConnection");
return null;
}
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
String message = "没有找到类:" + driver;
logger.error(message);
throw new RuntimeException(message);
}
try {
connection = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
String message = "数据库连接失败";
logger.error(message);
throw new RuntimeException(message);
}
return tool;
}
public DBEntityTool toEntity(String storePath, String pack) {
if(connection == null){
logger.error("未建立连接");
return null;
}else if(types == null){
logger.error("未加载properties文件");
return null;
}
try {
DatabaseMetaData meta = connection.getMetaData();
ResultSet tabSet = meta.getTables(null, null, null,
new String[] { "TABLE" });
while (tabSet.next()) {
String table = tabSet.getString("TABLE_NAME");
ResultSet columnSet = meta.getColumns(null, null, table, null);
Map attrs = new HashMap();
while (columnSet.next()) {
String columnName = columnSet.getString("COLUMN_NAME");
String sqlType = columnSet.getString("TYPE_NAME");
attrs.put(columnName, sqlType);
}
table = table.substring(0, 1).toUpperCase()+table.substring(1, table.length());
String content = toEntityContent(pack, table, attrs);
String filePath = storePath + "\\" + table + ".java";
toFile(filePath, content);
}
} catch (SQLException e) {
String message = "无法生成实例对象";
logger.error(message);
throw new RuntimeException(message);
}
return tool;
}
public DBEntityTool loadProperties(String loadPath) {
if(types != null){
logger.error("已经加载过properties文件");
return null;
}
Properties properties = new Properties();
InputStream fis = null;
try {
fis = new FileInputStream(loadPath);
properties.load(fis);
} catch (IOException e) {
String message = "properties文件加载失败";
logger.error(message);
throw new RuntimeException(message);
}finally{
if(fis != null){
try {
fis.close();
} catch (IOException e) {
String message = "关闭输入流失败";
logger.error(message);
throw new RuntimeException(message);
}
}
}
types = new HashMap();
Set keys = properties.keySet();
Iterator it = keys.iterator();
while (it.hasNext()) {
String sqlType = it.next();
String javaType = properties.getProperty(sqlType);
types.put(sqlType, javaType);
}
return tool;
}
private String toEntityContent(String pack, String tab, Map attrs) {
Iterator it = attrs.keySet().iterator();
StringBuilder sb = new StringBuilder();
sb.append("package ").append(pack).append(";").append("\n\n");
sb.append("public class ").append(tab).append(" {").append("\n");
StringBuilder methods = new StringBuilder();
while (it.hasNext()) {
String attrName = it.next();
String attrType = attrs.get(attrName);
String type = types.get(attrType);
sb.append("\t").append("private ").append(type).append(" ").append(attrName)
.append(";").append("\n");
String methodName = attrName.substring(0, 1).toUpperCase()
+ attrName.substring(1, attrName.length());
methods.append("\t").append("public ").append(type).append(" get")
.append(methodName).append("(){").append("\n");
methods.append("\t\t").append("return this.").append(attrName).append(";").append("\n");
methods.append("\t").append("}").append("\n");
methods.append("\t").append("public void ").append("set").append(methodName)
.append("(").append(type).append(" ").append(attrName)
.append("){").append("\n");
methods.append("\t\t").append("this.").append(attrName).append("=")
.append(attrName).append(";").append("\n");
methods.append("\t").append("}").append("\n");
}
sb.append(methods.toString());
sb.append("}").append("\n");
return sb.toString();
}
private void toFile(String filePath, String content) {
OutputStream os = null;
try {
os = new FileOutputStream(filePath);
os.write(content.getBytes());
} catch (Exception e) {
String message = "无法保存数据到" + filePath;
logger.error(message);
throw new RuntimeException(message);
} finally {
if (os != null){
try {
os.close();
} catch (IOException e) {
String message = "关闭输出流失败";
logger.error(message);
throw new RuntimeException(message);
}
}
}
}
}
在生成过程中,需要用到数据库和java类型的对应表,下面是mysql和java的类型对应,写在mysql.properties中
VARCHAR=String
CHAR=String
BLOB=BLOB
TEXT=String
INTEGER=Long
TINYINT=Integer
SMALLINT=Integer
MEDIUMINT=Integer
BIT=Boolean
BIGINT=BigInteger
FLOAT=Float
DOUBLE=Double
DECIMAL=BigDecimal
BOOLEAN=Integer
ID=Long
DATE=Date
TIME=Time
DATETIME=Timestamp
TIMESTAMP=Timestamp
YEAR=Date
main方法测试
public static void main(String[] args) {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://127.0.0.1/ddeer";
String username = "root";
String password = "123";
String path = "D://db";
String pack = "com.ddeer.entity";
String propertiesPath = "E:\\EclipseWorkspace\\BS\\DDeer\\src\\main\\java\\com\\ddeer\\entity\\tool\\mysql.properties";
DBEntityTool tool = DBEntityTool.getInstance();
tool.buildConnection(url, driver, username, password)
.loadProperties(propertiesPath).toEntity(path, pack);
}