java 通过jdbc生成java实体

平时开发中总是要根据别人建立好的数据库生成对应的实体,当然如果使用hibernate也可以用它自身的工具去生成或者通过实体反向生成对应的表结构,但是大部分都是根据数据库表去生成实体的,为了避免重复干这种活,抽空写了一段程序用于根据数据库表生成对应的实体,是通过jdbc生成的
数据库工具类<span style="font-family: monospace; line-height: 1.5; background-color: #fafafa;">DBUtil.java </span></p>
<pre name="code" class="java">/**
* @author caifan
*
* 2016年11月20日
* 获取数据库信息
*/
public class DBUtil {
private static ThreadLocal&lt;Connection&gt; localConnection = new ThreadLocal&lt;Connection&gt;();
/**
* 获取连接 将user password 存在property中, 如果是oracle数据库为了获取oracle字段的备注信息
* 2016年11月20日
* @param username
* @param psword
* @param url
* @return
*/
public static Connection getConn(String url, String username, String password, DBType dbtype){
Connection conn = localConnection.get();
Properties prop = new Properties();
prop.put("user", username);
prop.put("password", password);
if(dbtype.getName().equals("Oracle")) {
prop.put("remarksReporting", "true");
}

if(conn == null) {
try {
Class.forName(dbtype.getDriverName());
conn = DriverManager.getConnection(url, prop);
System.out.println("连接成功");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
localConnection.set(conn);
}
return conn;
}

/**
* 关闭连接
* 2016年11月20日
*/
public static void closeConnection() {
Connection conn = localConnection.get();
if(conn != null) {
try {
conn.close();
//ThreaLocal中清除Connection
localConnection.remove();
} catch (SQLException e) {
e.printStackTrace();
}

}
}

/**
* 关闭Statement(用于执行静态 SQL 语句并返回它所生成结果的对象。)
* 2016年11月20日
* @param pstmt
*/
    public static void close(PreparedStatement ps) { 
        if (ps != null) { 
            try { 
                ps.close(); 
            } catch (SQLException e) { 
                e.printStackTrace(); 
            } 
        } 
    } 
   
    /**
     * 关闭Statement(用于执行静态 SQL 语句并返回它所生成结果的对象。)
     * 2016年11月20日
     * @param pstmt
     */
    public static void close(Statement pstmt) { 
    if (pstmt != null) { 
    try { 
    pstmt.close(); 
    } catch (SQLException e) { 
    e.printStackTrace(); 
    } 
    } 
    } 
     
    /**
     * 关闭结果集 
     * 2016年11月20日
     * @param rs
     */
    public static void close(ResultSet rs ) { 
        if (rs != null) { 
            try { 
                rs.close(); 
            } catch (SQLException e) { 
                e.printStackTrace(); 
            } 
        } 
    } 
     
    /**
     * 开启事务 
     * 2016年11月20日
     * @param conn
     */
    public static void beginTransaction(Connection conn) { 
        try { 
            if (conn != null) { 
                if (conn.getAutoCommit()) { 
                    conn.setAutoCommit(false); //手动提交 
                } 
            } 
        }catch(SQLException e) {
        e.printStackTrace();
        } 
    } 
     
     
    /**
     * 提交事务 
     * 2016年11月20日
     * @param conn
     */
    public static void commitTransaction(Connection conn) { 
        try { 
            if (conn != null) { 
                if (!conn.getAutoCommit()) { 
                    conn.commit(); 
                } 
            } 
        }catch(SQLException e) {
        e.printStackTrace();
        } 
    } 
     
    /**
     * 回滚事务 
     * 2016年11月20日
     * @param conn
     */
    public static void rollbackTransaction(Connection conn) { 
        try { 
            if (conn != null) { 
                if (!conn.getAutoCommit()) { 
                    conn.rollback(); 
                } 
            } 
        }catch(SQLException e) {
        e.printStackTrace();
        } 
    } 


}</pre>
<p> 由于各数据库只是遵循了数据库 的标准,有些类型与java类型对应的关系可能不太一样所以我这里对不同的数据库类型使用的不同的存储,使用的map存储的映射关系</p>
<pre name="code" class="java">/**
* 配置数据库驱动和名称
* @author caifan
*
* 2016年12月10日
*/
public enum DBType {

MySQL {
@Override
public String getName() {
return "MySQL";
}

@Override
public String getDriverName() {
return "com.mysql.jdbc.Driver";
}

@Override
public Map&lt;String, String&gt; getFieldType() {
/**
* 类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int)
VARCHAR L+N VARCHAR java.lang.String 12
CHAR N CHAR java.lang.String 1
BLOB L+N BLOB java.lang.byte[] -4
TEXT 65535 VARCHAR java.lang.String -1
INTEGER 4 INTEGER UNSIGNED java.lang.Long 4
TINYINT 3 TINYINT UNSIGNED java.lang.Integer -6
SMALLINT 5 SMALLINT UNSIGNED java.lang.Integer 5
MEDIUMINT 8 MEDIUMINT UNSIGNED java.lang.Integer 4
BIT 1 BIT java.lang.Boolean -7
BIGINT 20 BIGINT UNSIGNED java.math.BigInteger -5
FLOAT 4+8 FLOAT java.lang.Float 7
DOUBLE 22 DOUBLE java.lang.Double 8
DECIMAL 11 DECIMAL java.math.BigDecimal 3
BOOLEAN 1 同TINYINT
ID 11 PK (INTEGER UNSIGNED) java.lang.Long 4
DATE 10 DATE java.sql.Date 91
TIME 8 TIME java.sql.Time 92
DATETIME 19 DATETIME java.sql.Timestamp 93
TIMESTAMP 19 TIMESTAMP java.sql.Timestamp 93
YEAR 4 YEAR java.sql.Date 91
*/
Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
map.put("VARCHAR", "String");
map.put("CHAR", "String");
map.put("BLOB", "byte[]");
map.put("TEXT", "String");
map.put("INTEGER", "Long");
map.put("TINYINT", "Integer");
map.put("SMALLINT", "Integer");
map.put("MEDIUMINT", "Integer");
map.put("BIT", "Boolean");
map.put("BIGINT", "BigInteger");
map.put("FLOAT", "Float");
map.put("DOUBLE", "Double");
map.put("DECIMAL", "BigDecimal");
map.put("BOOLEAN", "Integer");
map.put("ID", "Long");
map.put("DATE", "Date");
map.put("TIME", "Time");
map.put("DATETIME", "Timestamp");
map.put("TIMESTAMP", "Timestamp");
map.put("YEAR", "Date");
map.put("INT", "Integer");
return map;
}
},MariaDB {

@Override
public String getName() {
return "MariaDB";
}

@Override
public String getDriverName() {
return "org.mariadb.jdbc.Driver";
}

/**
* MariaDB暂时引用Mysql类型
*/
@Override
public Map&lt;String, String&gt; getFieldType() {
Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
map.put("VARCHAR", "String");
map.put("CHAR", "String");
map.put("BLOB", "byte[]");
map.put("TEXT", "String");
map.put("INTEGER", "Long");
map.put("TINYINT", "Integer");
map.put("SMALLINT", "Integer");
map.put("MEDIUMINT", "Integer");
map.put("BIT", "Boolean");
map.put("BIGINT", "BigInteger");
map.put("FLOAT", "Float");
map.put("DOUBLE", "Double");
map.put("DECIMAL", "BigDecimal");
map.put("BOOLEAN", "Integer");
map.put("ID", "Long");
map.put("DATE", "Date");
map.put("TIME", "Time");
map.put("DATETIME", "Timestamp");
map.put("TIMESTAMP", "Timestamp");
map.put("YEAR", "Date");
map.put("INT", "Integer");
return map;
}
}, Oracle {
@Override
public String getName() {
return "Oracle";
}

@Override
public String getDriverName() {
return "oracle.jdbc.driver.OracleDriver";
}

@Override
public Map&lt;String, String&gt; getFieldType() {
Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
map.put("BINARY_DOUBLE", "Double");
map.put("BINARY_FLOAT", "Float");
map.put("VARCHAR2", "String");
map.put("NVARCHAR2", "String");
map.put("CHAR", "String");
map.put("BLOB", "Blob");
map.put("CLOB", "Clob");
map.put("DATE", "Date");
map.put("LONG", "String");
map.put("NCLOB", "Clob");
map.put("NUMBER", "Float");
map.put("INTEGER", "Integer");
map.put("TIMESTAMP", "Date");
return map;
}
}, SQLServer {

@Override
public String getName() {
return "SQLServer";
}

@Override
public String getDriverName() {
return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
}

/*编号 数据库类型 JDBC类型 JDBC索引 描述
1 int java.lang.Integer 4
2 varchar java.lang.String 12
3 char java.lang.String 1
4 nchar java.lang.String 1
5 nvarchar java.lang.String 12
6 text java.lang.String -1
7 ntext java.lang.String -1
8 tinyint java.lang.Integer -6
11 smallint java.lang.Integer 5
12 bit java.lang.Boolean -7
13 bigint java.lang.Long -5
14 float java.lang.Double 6
15 decimal java.math.BigDecimal 3
16 money java.math.BigDecimal 3
17 smallmoney java.math.BigDecimal 3
18 numeric java.math.BigDecimal 2
19 real java.lang.Float 7
20 uniqueidentifier java.lang.String 1
21 smalldatetime java.sql.Timestamp 93
22 datetime java.sql.Timestamp 93
23 timestamp byte[] -2
24 binary byte[] -2
25 varbinary byte[] -3
26 image byte[] -4
27 sql_variant java.lang.String 12*/

@Override
public Map&lt;String, String&gt; getFieldType() {
Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
map.put("INT", "Integer");
map.put("VARCHAR", "String");
map.put("CHAR", "String");
map.put("NCHAR", "String");
map.put("NVARCHAR", "String");
map.put("TEXT", "String");
map.put("NTEXT", "String");
map.put("TINYINT", "Integer");
map.put("SMALLINT", "Integer");
map.put("BIT", "Boolean");
map.put("BIGINT", "Long");
map.put("FLOAT", "Double");
map.put("DECIMAL", "BigDecimal");
map.put("MONEY", "BigDecimal");
map.put("SMALLMONEY", "BigDecimal");
map.put("NUMERIC", "BigDecimal");
map.put("REAL", "Float");
map.put("UNIQUEIDENTIFIER", "String");
map.put("SMALLDATETIME", "Date");
map.put("DATETIME", "Date");
map.put("TIMESTAMP", "Date");
map.put("BINARY", "byte[]");
map.put("VARBINARY", "byte[]");
map.put("IMAGE", "byte[]");
map.put("SQL_VARIANT", "String");
return map;
}

}, Teradata {

@Override
public String getName() {
return "Teradata";
}

@Override
public String getDriverName() {
return "com.teradata.jdbc.TeraDriver";
}

@Override
public Map&lt;String, String&gt; getFieldType() {
return null;
}

};

public abstract String getName();
public abstract String getDriverName();
public abstract Map&lt;String, String&gt; getFieldType();
}
</pre>
<p> 主要做了mysql、oracle两种数据库的映射,其他的数据库使用的不多没有去映射,如有必要自己去映射一下就ok了</p>
<p>下面是一个生成代码</p>
<pre name="code" class="java">/**
* @author caifan
*
* 2016年11月20日
* 根据数据库生成实体
*
* 1.首先读取元数据获取所有的表名
* 2.读取表名获取该表对应的所有字段名、字段对应的类型、备注
* 3.根据对应的字段类型生成对应的字段名、和注释
*/
public class GenBean {

public static void main(String[] args) throws Exception {
Connection conn = DBUtil.getConn("jdbc:mysql://localhost:3306/learn", "root", "123456",DBType.MySQL);

DatabaseMetaData metaData = conn.getMetaData();

List&lt;String&gt; tables = getTables(conn);
for(String table : tables) {
getColumnsAndGenJava(conn, table, "D:/test", DBType.MySQL, false);
// dropTable(conn, table);
// truncateTable(conn, table);
}
}

/**
* 根据表名获取字段列信息
* 2016年12月11日
* @param conn
* @param tablename
* @param javaPath 生成java文件路径
* @param type 数据库类型
* @param anotation 是否支持注解(hibernate使用注解时设置true即可)
*/
public static void getColumnsAndGenJava(Connection conn, String tablename, String javaPath, DBType type, boolean anotation) {
StringBuffer buffer = new StringBuffer();//存放字段信息
StringBuffer gsField = new StringBuffer();//存放get set方法
//StringBuffer setField = new StringBuffer();//存放get方法
FileWriter fw = null;
if(anotation) {
buffer.append("@Entity(tableName=\"" + tablename + "\")\n");
}
buffer.append("public class " + getTransferName(tablename) + " implements Serializable {\n");
DatabaseMetaData metaData;
try {
File file = new File(javaPath + File.separator + getTransferName(tablename) + ".java");
if(file.exists()) {
file.delete();
}
fw = new FileWriter(file);

//获取类型
@SuppressWarnings("rawtypes")
Map map = type.getFieldType();
String javaType;
metaData = conn.getMetaData();
ResultSet columns = metaData.getColumns(null, "%", tablename, "%");
String columnName;//列名
String typeName;//类型名
String remarks;//备注
while(columns.next()) {
typeName = columns.getString("TYPE_NAME");//字段类型名称(例如:VACHAR2)
javaType = map.get(typeName.toUpperCase()).toString();
columnName = columns.getString("COLUMN_NAME");//列名
if (anotation) {
buffer.append("@Column(name=\""+columnName+"\")\n");
}
buffer.append("\tprivate ").append(javaType).append(" ");
buffer.append(getFirstNameLower(getTransferName(columnName)) +  ";");
//get方法
gsField.append("\tpublic ").append(javaType).append(" get" + getTransferName(columnName))
.append("() {\n\t\treturn " + getFirstNameLower(getTransferName(columnName)) + ";\n\t}\n");
//set方法
gsField.append("\tpublic void set" + getTransferName(columnName)).append("(").append(javaType).append(" ")
.append(getFirstNameLower(getTransferName(columnName))).append(") {\n")
.append("\t\tthis.").append(getFirstNameLower(getTransferName(columnName)))
.append(" = ").append(getFirstNameLower(getTransferName(columnName))).append(";\n\t}\n");
                remarks = columns.getString("REMARKS");//备注
                if(remarks != null) {
                buffer.append("//" + remarks + "\n");
                } else {
                buffer.append("\n");
                }
}
buffer.append(gsField);

buffer.append("}");
fw.write(buffer.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
if(fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

/**
* 获取表名
* 2016年11月20日
* @param tableSql
* @param conn
* @return
*/
private static List&lt;String&gt; getTables(Connection conn) {
List&lt;String&gt; tables = new ArrayList&lt;&gt;();
ResultSet rs = null;
try {
DatabaseMetaData metaData = conn.getMetaData();
rs = metaData.getTables(null, metaData.getUserName(), null, new String[]{"TABLE"});
while(rs.next()) {
tables.add(rs.getString("TABLE_NAME"));
}

} catch(Exception e) {
e.printStackTrace();
} finally {
try {
if(rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}

}
return tables;
}

/**
* 根据字段名字来生成驼峰式的名字,如果名字全大写或者全小写将字段转成除首字母大写其余小写,如果有_隔开的则将每个_前后的字符串转成首字母大写其余小写
* 2016年12月11日
* @param name
* @return
*/
public static String getTransferName (String name) {
String transferName = "";
if(name.indexOf("_") &gt; -1) {
String[] strs = name.split("_");
for (String str : strs) {
transferName += getFirstNameUpper(str);
}
} else {
transferName = getFirstNameUpper(name);
}
return transferName;
}

/**
* 将字符串转成首字母大写
* 2016年12月11日
* @param name
* @return
*/
private static String getFirstNameUpper(String name) {
String transferName = name.toLowerCase();
transferName = transferName.substring(0, 1).toUpperCase() + transferName.substring(1);
return transferName;
}

/**
* 将首字母转成小写
* 2016年12月14日
* @param name
* @return
*/
private static String getFirstNameLower(String name) {
return name.substring(0, 1).toLowerCase() + name.substring(1);
}

/**
* 清空表
* 2016年12月15日
* @param conn
* @param tableName
*/
private static void truncateTable(Connection conn, String tableName)  {
Statement stat = null;
try {
stat = conn.createStatement();
stat.execute("truncate table " + tableName);
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

/**
* 删除表
* 2016年12月15日
* @param conn
* @param tableName
*/
private static void dropTable(Connection conn, String tableName)  {
Statement stat = null;
try {
stat = conn.createStatement();
stat.execute("drop table " + tableName);
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}

这个里面含有删除表和清除表数据的方法,如果需要使用直接调用即可。
如果有更好的意见望提出
欢迎加入QQ 群513650703共同学习交流

猜你喜欢

转载自shareisattitude.iteye.com/blog/2345459
今日推荐