java 數據庫表批量,或者單個轉換成javaBean對象工具

把數據庫錶轉成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;
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章