把數據庫錶轉成javaBean, 有人支持大小寫按java標準轉換, 個人經驗表明: 全部用數據庫大寫使用更方便, 不容易出錯.
本工具可以轉換成標準bean格式, 也可以數據庫字段原始的方式創建bean
使用本工具的前提: 必須提供 DataSource 數據源對象, 本代碼是從spring中獲取數據源, 兄弟們可以改寫這個代碼, 用自己的數據源.
BYTE,SHORT對象用INTEGE,不再區別處理.
FLOAT,DOUBLE對象用BIGDECIMAL,不再區別處理.
生成的屬性全部是對象,沒有使用 int, long 這類基本屬性.
生成的文件在工程目錄下面與src目錄平級.
全部代碼如下:
package com.test.util;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DataSourceUtils;
//此類請自己定義
import com.test.Const;
import com.test.ServiceLocator;
/**
* 數據庫錶轉換成javaBean對象工具,
* 1,bean屬性按原始數據庫字段經過去掉下劃線,並大寫處理首字母等等.
* 2,可以按原始表中的列名生成bean字段(大寫),不做任何修改.
* @author guishuanglin 2013-11-26
*/
public class TableToEntityUtils {
//BYTE,SHORT對象用INTEGE,不再區別處理.
//FLOAT,DOUBLE對象用BIGDECIMAL,不再區別處理.
private final int jINTEGER = 1;
private final int jLONG = 2;
private final int jDATE = 3;
private final int jSTRING = 4;
private final int jBIGDECIMAL = 5;
private final int jOBJECT = 6;
private final String sINTEGER ="Integer";
private final String sLONG = "Long";
private final String sDATE = "Date";
private final String sSTRING = "String";
private final String sBIGDECIMAL = "BigDecimal";
private final String sOBJECT = "Object";
//資料
private int dataBaseType =-1;
private String tablename = "";
private String beanName = "";
private int colCount;//列數
private String[] benFieldName;
private String[] benClassName;
private int[] benClassType;
private String[] colnames;
private String[] colTypes;//列類型名字.
private int[] colSizes; // 列字符大小
private int[] colScale; // 列小數精度
//引用包
private boolean importUtil = false; // 導入包java.util.*
private boolean importSql = false; // 包java.sql.*
private boolean importMath = false; // 包java.math.*
//控制變量
private boolean isConvertColName =true;//是否把列名轉成java規範的名字.
private boolean onlyCreateBean =true; //只生成Bean.
//類附加註釋
private SimpleDateFormat DateFormat = new SimpleDateFormat("yyyy-MM-dd");
private String strDate=null;
private String author="table tool";
/** 入口 */
public void execute(String dbTableName) {
if(dbTableName ==null) return;
if(strDate ==null)
strDate = DateFormat.format(new Date());
tablename = dbTableName;
beanName = this.firstUpperCase(this.toJavaName(dbTableName.toLowerCase()));
boolean b = processTableMetaData(dbTableName);
if(b){
//初始 bean字段數組.
benFieldName = new String[colCount];
benClassName = new String[colCount];
benClassType = new int[colCount];
//處理每列對應的bean屬性與java類型
this.processClassnames();
//生成實體 bean
b =tableToEntity(beanName);
}
}
/**
* 處理數表媒體數據, spring數據源名稱: dataSource0,dataSource1,dataSource2,dataSource3,dataSource4,dataSource5.
*/
private boolean processTableMetaData(String tName) {
boolean b =false;
// 請改成自己的數據源
DataSource ds = (DataSource) ServiceLocator.getService("dataSource0");
Connection conn = DataSourceUtils.getConnection(ds); // 得到數據庫連接
String strsql = "SELECT * FROM " + tablename;//+" WHERE ROWNUM=1";
try {
System.out.println("================ "+tName+" ================");
System.out.println(strsql);
this.dataBaseType =this.getDbType(conn);
PreparedStatement pstmt = conn.prepareStatement(strsql);
pstmt.executeQuery();
ResultSetMetaData rsmd = pstmt.getMetaData();
int size = rsmd.getColumnCount(); // 共有多少列
colCount = size;
colnames = new String[size];
colTypes = new String[size];
colSizes = new int[size];
colScale = new int[size];
for (int i = 0; i < rsmd.getColumnCount(); i++) {
colnames[i] = rsmd.getColumnName(i + 1).toLowerCase();
colTypes[i] = rsmd.getColumnTypeName(i + 1).toLowerCase();
colSizes[i] = rsmd.getPrecision(i + 1);
colScale[i] = rsmd.getScale(i + 1);
System.out.println(i+",columnType: "+rsmd.getColumnTypeName(i + 1)+", classType: "+rsmd.getColumnClassName(i + 1));
}
b =true;
} catch (SQLException e) {
e.printStackTrace();
} finally {
DataSourceUtils.releaseConnection(conn, ds);
}
return b;
}
/**
* 獲取主流數據庫類型.
* -1-未知,0-ORACLE,1-SYBASE,2-SQLSERVER,3-DB2,4-MYSQL
* @throws SQLException
*/
private int getDbType(Connection conn) {
if(conn == null) return -1;
int dbType = -1;//未知數據庫
try {
DatabaseMetaData dbMeta = conn.getMetaData();
System.out.println(dbMeta.getDatabaseProductName());
String dbName = dbMeta.getDatabaseProductName().toLowerCase();
String url = dbMeta.getURL().toLowerCase();
if (url != null) {
if(dbName.indexOf("oracle") >=0 ){
dbType = Const.DB_ORACLE;
}else if(dbName.indexOf("sybase") >=0 && dbName.indexOf("iq") >=0){
dbType = Const.DB_SYBASEIQ;
}else if(dbName.indexOf("sybase") >=0 ){
dbType = Const.DB_SYBASE;
}else if(dbName.indexOf("sqlserver") >=0 ){
dbType = Const.DB_SQLSERVER;
}else if(dbName.indexOf("ibm") >=0 ){
dbType = Const.DB_IBMDB2;
}else if(dbName.indexOf("mysql") >=0 ){
dbType = Const.DB_MYSQL;
}else if(dbName.indexOf("maria") >=0 ){
dbType = Const.DB_MARIA;
}else if(dbName.indexOf("dm dbms") >=0 ){
dbType = Const.DB_DAMENG;
}else{
System.out.println("警告: [不確定的數據庫類型]: "+url);
}
}else{
System.out.println("警告: [不確定的數據庫類型]: "+url);
}
System.out.println("[當前數據庫類型],USER:["+dbMeta.getUserName()+"], DB:["+dbName+"], URL:["+url+"]");
dbMeta = null;
} catch (Exception se) {
se.printStackTrace();
} finally {
}
return dbType;
}
//================================生成實體部分======================================
/**
* 根據文件名,代碼內容生成java代碼;
*/
private boolean fileWriter(String name, String javaCodeContent) {
boolean b =false;
try {//編碼根據項目本身要求的字符編碼修改.
FileOutputStream out = new FileOutputStream(name + ".java");
byte[] bytes = new byte[20480];//20k
byte[] inbytes = javaCodeContent.getBytes("utf-8");
ByteArrayInputStream in = new ByteArrayInputStream(inbytes);
int c;
while ((c = in.read(bytes)) != -1) {
out.write(bytes, 0, c);
}
in.close();
in = null;
bytes =null;
inbytes =null;
b =true;
System.out.println("生成================ "+name+" ================完成");
} catch (IOException e) {
e.printStackTrace();
System.out.println("生成================ "+name+" ================異常");
} finally {
javaCodeContent =null;
}
return b;
}
/**
* 生成實體類文件
* @param args
*/
private boolean tableToEntity(String tName) {
boolean b =false;
String content = buildEntityCode();
b=fileWriter(tName, content);
return b;
}
/**
* 1, 處理列名,把空格下劃線'_'去掉,同時把下劃線後的首字母大寫
* 要是整個列在3個字符及以內,則去掉'_'後,不把"_"後首字母大寫.
* 同時把數據庫列名,列類型寫到註釋中以便查看,
* 2, 處理bean字段的java類型
* -1-未知,0-ORACLE,1-SYBASE,2-SQLSERVER,3-DB2,4-MYSQL
* 3, java類型對應的數字常量.
*/
private void processClassnames() {
for (int i = 0; i < colnames.length; i++) {
//1
if(this.isConvertColName){
benFieldName[i] = this.toJavaName(colnames[i]);
}else{
benFieldName[i] = colnames[i].toUpperCase();
}
//2
if(this.dataBaseType ==0){
benClassName[i] = this.oracleTypeToJavaType(colTypes[i], colSizes[i], colScale[i]);
}else if(this.dataBaseType ==1){
benClassName[i] = this.sybaseTypeToJavaType(colTypes[i], colSizes[i], colScale[i]);
}else if(this.dataBaseType ==2){//暫用oralce類型
benClassName[i] = this.oracleTypeToJavaType(colTypes[i], colSizes[i], colScale[i]);
}else if(this.dataBaseType ==3){//暫用oralce類型
benClassName[i] = this.oracleTypeToJavaType(colTypes[i], colSizes[i], colScale[i]);
}else if(this.dataBaseType ==4){//暫用oralce類型
benClassName[i] = this.oracleTypeToJavaType(colTypes[i], colSizes[i], colScale[i]);
}else{//暫用oralce類型
benClassName[i] = this.oracleTypeToJavaType(colTypes[i], colSizes[i], colScale[i]);
}
//3 轉換類型對應的常量值,方便以後判斷處理.
if(benClassName[i].equals(this.sINTEGER)){
benClassType[i]=this.jINTEGER;
}else if(benClassName[i].equals(this.sLONG)){
benClassType[i]=this.jLONG;
}else if(benClassName[i].equals(this.sBIGDECIMAL)){
//bean是否用到Bigdecimal類型的包
importMath = true;
benClassType[i]=this.jBIGDECIMAL;
}else if(benClassName[i].equals(this.sSTRING)){
benClassType[i]=this.jSTRING;
}else if(benClassName[i].equals(this.sDATE)){
//bean是否用到Date類型的包
importUtil = true;
benClassType[i]=this.jDATE;
}else if(benClassName[i].equals(this.sOBJECT)){
benClassType[i]=this.jOBJECT;
}else{
benClassType[i]=this.jOBJECT;
}
}
}
/**
* 解析處理(生成實體類主體代碼)
*/
private String buildEntityCode() {
StringBuffer sb = new StringBuffer();
sb.append("\r\nimport java.io.Serializable;\r\n");
if (importUtil) {
sb.append("import java.util.Date;\r\n");
}
if (importSql) {
sb.append("import java.sql.*;\r\n\r\n");
}
if(importMath){
sb.append("import java.math.*;\r\n\r\n");
}
//表註釋
processNote(sb);
sb.append("public class " + this.beanName + " implements Serializable {\r\n");
processAllAttrs(sb);
processAllMethod(sb);
sb.append("}\r\n");
System.out.println(sb.toString());
return sb.toString();
}
/**
* 把數據庫列名,列類型,長度,精度寫到註釋中以便查看.
* (目前字段文本註釋暫不能處理)
* @param sb
*/
private void processNote(StringBuffer sb) {
//可增加類說明
sb.append("\r\n/** \r\n");
sb.append(" * "+tablename+":\r\n");
String colsiz="";
String colsca="";
for (int i = 0; i < colnames.length; i++) {
colsiz = colSizes[i]<=0? "" : (colScale[i]<=0? "("+colSizes[i]+")" : "("+colSizes[i]+","+colScale[i]+")");
sb.append("\t" + colnames[i].toUpperCase() +" "+colTypes[i].toUpperCase()+ colsiz+"\r\n");
}
//增加日期
sb.append(" * @author "+author+" "+this.strDate+"\r\n");
sb.append(" */\r\n");
}
/**
* 生成所有的方法
* @param sb
*/
private void processAllMethod(StringBuffer sb) {
for (int i = 0; i < colnames.length; i++) {
sb.append("\tpublic void set" + firstUpperCase(benFieldName[i]) + "("
+ benClassName[i] + " " + benFieldName[i]
+ "){\r\n");
sb.append("\t\tthis." + benFieldName[i] + "=" + benFieldName[i] + ";\r\n");
sb.append("\t}\r\n");
//
sb.append("\tpublic " + benClassName[i] + " get"
+ firstUpperCase(benFieldName[i]) + "(){\r\n");
sb.append("\t\treturn " + benFieldName[i] + ";\r\n");
sb.append("\t}\r\n");
}
}
/**
* 解析輸出屬性
*
* @return
*/
private void processAllAttrs(StringBuffer sb) {
sb.append("\tprivate static final long serialVersionUID = 1L;\r\n");
for (int i = 0; i < colnames.length; i++) {
sb.append("\tprivate " + benClassName[i] + " "
+ benFieldName[i] + ";\r\n");
}
sb.append("\r\n");
}
/**
* 把輸入字符串的首字母改成大寫,用作Bean的類名,方法名等.
*/
private String firstUpperCase(String name) {
char[] ch = name.toCharArray();
if (ch[0] >= 'a' && ch[0] <= 'z') {
ch[0] = (char) (ch[0] - 32);
}
return new String(ch);
}
/**
* 數據庫列名轉換成java規範的名字(當然也可以不轉).
* 處理列名,把空格下劃線'_'去掉,同時把下劃線後的首字母大寫
* 要是整個列在3個字符及以內,則去掉'_'後,不把"_"後首字母大寫.
*/
private String toJavaName(String name) {
char[] ch = name.toCharArray();
char c ='a';
if(ch.length>3){
for(int j=0;j <ch.length; j++){
c = ch[j];
if(c == '_'){
if (ch[j+1]>= 'a' && ch[j+1] <= 'z') {
ch[j+1]=(char) (ch[j+1]-32);
}
}
}
}
String str = new String(ch);
str = str.replaceAll("_", "");
return str;
}
/**
* Sybase
*/
private String sybaseTypeToJavaType(String sqlType, int size, int scale) {
if (sqlType.equals("int")
|| sqlType.equals("bit")
|| sqlType.equals("tinyint")
|| sqlType.equals("smallint")
) {
return this.sINTEGER;
} else if (sqlType.equals("bigint")) {
return this.sLONG;
} else if (sqlType.equals("float")
|| sqlType.equals("float precision")
|| sqlType.equals("double")
|| sqlType.equals("double precision")
|| sqlType.equals("money")
|| sqlType.equals("smallmoney")) {
return this.sBIGDECIMAL;
}else if (sqlType.equals("number")
||sqlType.equals("decimal")
|| sqlType.equals("numeric")
|| sqlType.equals("real")) {
return scale==0? (size<10? this.sINTEGER : this.sLONG) : this.sBIGDECIMAL;
}else if (sqlType.equals("varchar")
|| sqlType.equals("varchar2")
|| sqlType.equals("char")
|| sqlType.equals("nvarchar")
|| sqlType.equals("nchar")) {
return this.sSTRING;
} else if (sqlType.equals("datetime")
|| sqlType.equals("date")) {
return this.sDATE;
}else {
return this.sOBJECT;
}
}
/**
* Oracle
*/
private String oracleTypeToJavaType(String sqlType, int size, int scale) {
if (sqlType.equals("integer")) {
return this.sINTEGER;
} else if (sqlType.equals("long")) {
return this.sLONG;
} else if (sqlType.equals("float")
|| sqlType.equals("float precision")
|| sqlType.equals("double")
|| sqlType.equals("double precision")) {
return this.sBIGDECIMAL;
}else if (sqlType.equals("number")
||sqlType.equals("decimal")
|| sqlType.equals("numeric")
|| sqlType.equals("real")) {
return scale==0? (size<10? this.sINTEGER : this.sLONG) : this.sBIGDECIMAL;
}else if (sqlType.equals("varchar")
|| sqlType.equals("varchar2")
|| sqlType.equals("char")
|| sqlType.equals("nvarchar")
|| sqlType.equals("nchar")) {
return this.sSTRING;
} else if (sqlType.equals("datetime")
|| sqlType.equals("date")
|| sqlType.equals("timestamp")) {
return this.sDATE;
}else {
return this.sOBJECT;
}
}
public boolean isConvertColName() {
return isConvertColName;
}
public void setConvertColName(boolean isConvertColName) {
this.isConvertColName = isConvertColName;
}
public boolean isOnlyCreateBean() {
return onlyCreateBean;
}
public void setOnlyCreateBean(boolean onlyCreateBean) {
this.onlyCreateBean = onlyCreateBean;
}
/**
* @param args
*/
public static void main(String[] args) {
//HD_ELEC_D, M_DEPT, M_TRANS_STATION
TableToEntityUtils t = new TableToEntityUtils();
t.setConvertColName(false);
t.setOnlyCreateBean(true);
//指定表名, 批量生成
t.execute("INTERFACE_ID_MAPPING");
t.execute("INTERFACE_DICT_MAPPING");
System.exit(0);
}
}
以下是生成代碼樣本
InterfaceIdMapping.java 文件:
package com.test;
import java.io.Serializable;
/**
* INTERFACE_ID_MAPPING:
OTHER_ID VARCHAR(32)
OBJECT_TYPE DECIMAL(5)
DATA_FROM DECIMAL(5)
OBJECT_ID DECIMAL(10)
OBJECT_NO VARCHAR(32)
OBJECT_CODE VARCHAR(32)
OBJECT_NAME VARCHAR(128)
MEMO VARCHAR(128)
* @author table tool 2019-05-23
*/
public class InterfaceIdMapping implements Serializable {
private static final long serialVersionUID = 1L;
private String OTHER_ID;
private Integer OBJECT_TYPE;
private Integer DATA_FROM;
private Long OBJECT_ID;
private String OBJECT_NO;
private String OBJECT_CODE;
private String OBJECT_NAME;
private String MEMO;
public void setOTHER_ID(String OTHER_ID){
this.OTHER_ID=OTHER_ID;
}
public String getOTHER_ID(){
return OTHER_ID;
}
public void setOBJECT_TYPE(Integer OBJECT_TYPE){
this.OBJECT_TYPE=OBJECT_TYPE;
}
public Integer getOBJECT_TYPE(){
return OBJECT_TYPE;
}
public void setDATA_FROM(Integer DATA_FROM){
this.DATA_FROM=DATA_FROM;
}
public Integer getDATA_FROM(){
return DATA_FROM;
}
public void setOBJECT_ID(Long OBJECT_ID){
this.OBJECT_ID=OBJECT_ID;
}
public Long getOBJECT_ID(){
return OBJECT_ID;
}
public void setOBJECT_NO(String OBJECT_NO){
this.OBJECT_NO=OBJECT_NO;
}
public String getOBJECT_NO(){
return OBJECT_NO;
}
public void setOBJECT_CODE(String OBJECT_CODE){
this.OBJECT_CODE=OBJECT_CODE;
}
public String getOBJECT_CODE(){
return OBJECT_CODE;
}
public void setOBJECT_NAME(String OBJECT_NAME){
this.OBJECT_NAME=OBJECT_NAME;
}
public String getOBJECT_NAME(){
return OBJECT_NAME;
}
public void setMEMO(String MEMO){
this.MEMO=MEMO;
}
public String getMEMO(){
return MEMO;
}
}