1. 程式人生 > 實用技巧 >JAVA實現DAO基本層CRUD操作(轉)

JAVA實現DAO基本層CRUD操作(轉)

轉載:https://www.cnblogs.com/yxwkf/p/4643483.html

以下詳細講講通過我自己的方式對有關DAO層資料庫基本CRUD操作的JAVA實現(此處已MySQL為例,其它資料庫僅僅需做部分改動就可以)。

備註:若要試用本演示樣例,僅僅需依照給出的順序依次複製程式碼建立對應的類就可以。另外。在專案lib資料夾下增加mysql連結jar包。

(1)定義資料來源常量類

package com.jkitn.jkits.common;

/**
 * 定義資料來源常量類
 * @author xdweleven
 * @version 1.0
 */
public class JdbcConfig {
	 /** 資料庫驅動 */
	 public static final String DRIVERCLASSNAME = "com.mysql.jdbc.Driver";
	 /** 資料庫URL */
	 public static final String URL = "jdbc:mysql://localhost:3306/app_jkit";
	 /** 資料庫username */
	 public static final String USERNAME = "root";
	 /** 資料庫password */
	 public static final String PASSWORD = "root";
}

(2)定義結果集(ResultSet)到pojo物件的對映

package com.jkitn.jkits.dao.common;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 說明:實現結果集到pojo物件的對映
 * @author xdweleven
 * @version 1.0 
 */
public class RowMapper<T>{
	private Class<T> objectClass;
	
	public RowMapper(Class<T> objectClass) {
		this.objectClass = objectClass;
	}
	
	/**
	 * 實現單條記錄到物件的對映
	 * @param rs 結果集
	 * @param rowNum 當前行數
	 * @return
	 * @throws SQLException
	 */
	public T mapRow(ResultSet rs, int rowNum) throws SQLException {
		try {
			T object = objectClass.newInstance(); 
			// 得到結果集的欄位集合
			ResultSetMetaData metaData = rs.getMetaData();
			int columnNum = metaData.getColumnCount();
			Field[] fields = object.getClass().getDeclaredFields();
			// 設定物件屬性的值。若不存在。則設定為null.
			for (int i = 0; i < fields.length; i++) {
				Field field = fields[i];
				int flag = 0;
				for (int j = 1; j <= columnNum; j++) {
					if (metaData.getColumnName(j).toLowerCase().equals(field.getName().toLowerCase())) {
						flag = 1;
						break;
					}
				}
				field.setAccessible(true);
				if (flag == 1) {
					this.typeMapper(field, object, rs);
				}else {
					field.set(object, null);
				}	
				field.setAccessible(false);
			}
			return object;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 實現多條記錄到結果集的對映
	 * @param rs
	 * @return
	 */
	public List<T> mapRows(ResultSet rs){
		int rowNum = 0;
		List<T> objList = new ArrayList<T>();
		try {
			while(rs.next()){
				objList.add(this.mapRow(rs, rowNum++));
			}
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return objList;
	}
	
	
	/**
	 * 型別的對映
	 * @param field
	 * @param obj
	 * @param rs
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws SQLException
	 */
	private void typeMapper(Field field, Object obj, ResultSet rs) {
		String typeName = field.getType().getName(); // 得到欄位型別
		try {
			if (typeName.equals("java.lang.String")) {
				field.set(obj, rs.getString(field.getName()));
			} else if (typeName.equals("int")
					|| typeName.equals("java.lang.Integer")) {
				field.set(obj, rs.getInt(field.getName()));
			} else if (typeName.equals("long")
					|| typeName.equals("java.lang.Long")) {
				field.set(obj, rs.getLong(field.getName()));
			} else if (typeName.equals("float")
					|| typeName.equals("java.lang.Float")) {
				field.set(obj, rs.getFloat(field.getName()));
			} else if (typeName.equals("double")
					|| typeName.equals("java.lang.Double")) {
				field.set(obj, rs.getDouble(field.getName()));
			} else if (typeName.equals("boolean")
					|| typeName.equals("java.lang.Boolean")) {
				field.set(obj, rs.getBoolean(field.getName()));
			} else if (typeName.equals("java.util.Date")) {
				field.set(obj, rs.getTimestamp(field.getName()));
			} else {
			}
		} catch (IllegalArgumentException e) {			
			e.printStackTrace();
		} catch (IllegalAccessException e) {			
			e.printStackTrace();
		} catch (SQLException e) {			
			e.printStackTrace();
		}
	}
}

(3)定義資料庫連線輔助類DBConn

package com.jkitn.jkits.common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import com.jkitn.jkits.dao.common.RowMapper;

/**
 * 定義資料庫連線輔助類DBConn
 * @author xdweleven
 * @version 1.0 
 */
public class DBConn {
    private Connection conn = null;
    private PreparedStatement pstmt = null;
    private ResultSet rs = null; 
    
    /**
     * 建立資料庫的連線
     * @return 返回資料庫連線物件
     */
    public Connection getConn(){        
        try {                     
			// 載入資料庫驅動
            Class.forName(JdbcConfig.DRIVERCLASSNAME);
            // 建立Connection介面物件。用於獲取MySQL資料庫的連線物件
            conn = DriverManager.getConnection(JdbcConfig.URL, JdbcConfig.USERNAME, JdbcConfig.PASSWORD);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }    
        return conn;
    }

	/**
	 * 更新資料庫操作(包含增刪改操作)
	 * @param sql  待執行sql語句
	 * @param objs 用於設定預編譯語句中帶入的引數
	 * @return null
	 * @throws Exception 
	 */
	public int execUpdate(String sql, Object ...objs) throws Exception{
			// 獲取預編譯環境
			pstmt = this.getConn().prepareStatement(sql);
			if(objs != null && objs.length > 0){
				for(int i = 0; i < objs.length; i++){
					pstmt.setObject(i+1, objs[i]);
				}
			}
			// 執行更新語句
			int result = pstmt.executeUpdate();
			// 斷開連線。釋放資源
			this.close(rs, pstmt, conn);
			return result;
	}

	/**
	 * 資料庫查詢操作
	 * @param sql 待執行sql語句
	 * @param objs 用於設定預編譯語句中帶入的引數
	 * @return 類T的List資料型別,即返回查詢到的全部資料資訊
	 * @throws Exception 
	 */
	public <T> List<T> execQuery(String sql, RowMapper<T> mapper, Object ...objs) throws Exception{
		// 獲取預編譯環境
		pstmt = this.getConn().prepareStatement(sql);
		if(objs != null && objs.length > 0){
			for(int i = 0; i < objs.length; i++){
				pstmt.setObject(i+1, objs[i]);
			}
		}
		// 執行更新語句
		rs = pstmt.executeQuery();
		// 執行關係到物件的對映
		List<T> result = mapper.mapRows(rs);
		// 斷開連線。釋放資源
		this.close(rs, pstmt, conn);
		return result;
	}	
	
	/**
	 * 執行執行的SQL語句並返回結果集
	 * @param sql SQL語句
	 * @param params 引數
	 * @return 返回結果集
	 */
	public ResultSet queryForResultSet(String sql, Object... objs) throws Exception{
		// 獲取預編譯環境
		pstmt = conn.prepareStatement(sql);
		if(objs != null && objs.length > 0){
			for(int i = 0; i < objs.length; i++){
				pstmt.setObject(i+1, objs[i]);
			}
		}
		// 執行更新語句
		rs = pstmt.executeQuery();
		// 斷開連線,釋放資源
		this.close(null, pstmt, conn);
		return rs;
	}
	
	/**
	 * 關閉資料庫連線,釋放所佔的系統資源
	 * @param rs結果集、ppst預編譯命令、conn資料庫
	 * @return null
	 * @throws Exception 
	 */
	public void close(ResultSet rs, PreparedStatement ppst, Connection conn) throws Exception{
		if(rs != null){
			rs.close();
		}
		if(ppst != null){ 
			ppst.close();
		}
		if(conn != null){
			conn.close();
		}
	}
}

(4)定義通用分頁查詢實體類

package com.jkitn.jkits.common;

import java.util.List;

/**
 * 說明:實現通用分頁查詢實體類
 * @author xdweleven
 * @version 1.0
 */
public class PageBean<T> {
	private int totalRows; // 總記錄數
	private int totalPages; // 總頁數
	private int curPage; // 當前頁碼
	private int prePage; // 上一頁頁碼
	private int nextPage; // 下一頁頁碼
	private int rowsPerPage; // 每頁顯示的記錄數 
	private List<T> pageList; // 當前頁的資料集
	
    /**
     * 初始化分頁bean物件
     * @param totalRows 總記錄數
     * @param rowsPerPage 每頁顯示的記錄數
     */
	public void initPageBean(int totalRows, int rowsPerPage){
		this.rowsPerPage = rowsPerPage;
		this.totalRows = totalRows;
		this.totalPages = (this.totalRows-1)/this.rowsPerPage + 1;
		// 設定上一頁
		if(this.curPage == 1){
			this.setPrePage(1);
		}else{
			this.setPrePage(this.curPage-1);
		}
		// 設定下一頁
		if(this.curPage == this.totalPages){
			this.setNextPage(this.totalPages);
		}else{
			this.setNextPage(this.curPage + 1);
		}
	}
	
	/**
	 * 生成SQLServer的分頁查詢語句
	 * @param sql 原始sql語句
	 * @param curPage 第幾頁
	 * @param rowsPerPage 每頁多少行 
	 */
	public String getPageSQLServer(String sql, int curPage, int rowsPerPage){
		String afterFrom = sql.toLowerCase().substring(sql.indexOf("from"));
		String pageSql = null;
		if(afterFrom.indexOf("where") == -1){
			 pageSql = "select top "+ rowsPerPage + " * "+afterFrom
			+" where id not in(select top "+rowsPerPage*(curPage-1)+" id "
			+afterFrom+" order by id desc)"+"order by id desc";
		}else{
			pageSql = "select top "+ rowsPerPage + " * "+afterFrom
			+" and id not in(select top "+rowsPerPage*(curPage-1)+" id "
			+afterFrom+" order by id desc)"+"order by id desc";
		}
		return pageSql;
	}
	
	/**
	 * 生成MySql分頁sql語句
	 * @param sql 原始sql語句
	 * @param curPage 第幾頁
	 * @param rowsPerPage 每頁多少行 
	 * @return 返回分頁SQL語句
	 */
	public String getPageMySQL(String sql, int curPage, int rowsPerPage){
		String pageSql = sql+" limit "+ (curPage-1)*rowsPerPage+","+rowsPerPage;
		return pageSql;
	}
	
	/**
	 * 生成Oracle分頁查詢語句
	 * @param sql 原始sql語句
	 * @return 返回分頁SQL語句
	 */
	public String getOrclPageSql(String sql){
		int begin = (curPage - 1) * rowsPerPage;
		int end = begin + rowsPerPage;
		StringBuffer pagingSelect = new StringBuffer(300);
		pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
		pagingSelect.append(sql);
		pagingSelect.append(" ) row_ where rownum <= "+end+") where rownum_ > "+begin);
		return pagingSelect.toString();
	}
	
	public List<T> getPageList() {
		return pageList;
	}

	public void setPageList(List<T> pageList) {
		this.pageList = pageList;
	}
	public int getTotalRows() {
		return totalRows;
	}

	public void setTotalRows(int totalRows) {
		this.totalRows = totalRows;
	}

	public int getTotalPages() {
		return totalPages;
	}

	public void setTotalPages(int totalPages) {
		this.totalPages = totalPages;
	}

	public int getCurPage() {
		return curPage;
	}

	public void setCurPage(int curPage) {
		this.curPage = curPage;
	}

	public int getPrePage() {
		return prePage;
	}

	public void setPrePage(int prePage) {
		this.prePage = prePage;
	}

	public int getNextPage() {
		return nextPage;
	}

	public void setNextPage(int nextPage) {
		this.nextPage = nextPage;
	}

	public int getRowsPerPage() {
		return rowsPerPage;
	}

	public void setRowsPerPage(int rowsPerPage) {
		this.rowsPerPage = rowsPerPage;
	}
}
(5)定義SQL語句的經常用法工具類


package com.jkitn.jkits.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 說明:自己主動生成物件的增刪改查SQL語句的通用方法工具類
 * @author xdweleven
 * @version 1.0 
 */
public class SQLUtil {	
	/**
	 * 自己主動生成插入指定物件的SQL語句,不包括物件屬性的值為空的欄位
	 * @param obj 待生成插入SQL語句的物件
	 * @param tableName 待插入語句相應的資料庫表的名稱
	 * @return 返回一個包括SQL語句、SQL語句引數值及引數值型別的Map物件
	 */
	public static Map<String, Object> generateInsertExceptNull(Object obj, String tableName) {
		StringBuffer columnStrBuf = new StringBuffer(); // 記錄資料表的欄位名稱
		StringBuffer paramStrBuf = new StringBuffer(); // 記錄SQL語句相應插入的佔位符
		List<Object> paramValues = new ArrayList<Object>(); // 記錄物件引數值
		List<Integer> paramsType = new ArrayList<Integer>(); // 記錄引數值型別
		// 查詢待插入物件的屬性值不為空的屬性名稱
		List<Object> fieldList = ReflectionUtil.getNotNullField(obj);
		try {
			for (int i = 0; i < fieldList.size(); i++) {
				Field field = (Field) fieldList.get(i);
				field.setAccessible(true);
				// 記錄物件屬性名稱
				columnStrBuf.append(field.getName());
				if (i != fieldList.size() - 1) {
					columnStrBuf.append(",");
				}
				
				// 記錄插入SQL語句的引數佔位符
				if("class java.util.Date".equals(field.getType().toString())
						&& field.get(obj) != null){
					String timeStr = DateUtil.formatDate((Date)field.get(obj), "yyyy-MM-dd HH:mm:ss");
					paramStrBuf.append("to_date(?, 'yyyy-MM-dd HH24:mi:ss')");
					paramValues.add(timeStr);
					// 記錄物件屬性的資料型別
					paramsType.add(getOrclDataType(field.getType().toString()));
				}else{
					paramStrBuf.append("?");
					paramValues.add(field.get(obj));
					// 記錄物件屬性的資料型別
					paramsType.add(getOrclDataType(field.getType().toString()));
				}
				
				if (i != fieldList.size() - 1) {
					paramStrBuf.append(",");
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		// 生成插入操作的SQL語句
		StringBuffer sb = new StringBuffer();
		sb.append("insert into ");
		sb.append(tableName);
		sb.append(" (");
		sb.append(columnStrBuf);
		sb.append(") ");
		sb.append("values");
		sb.append(" (");
		sb.append(paramStrBuf);
		sb.append(")");
		// 將生成的SQL語句、SQL語句引數值及各引數值的資料型別用map儲存並返回
		Map<String, Object> sqlMap = new HashMap<String, Object>();
		sqlMap.put("sql", sb.toString());
		sqlMap.put("paramsValues", paramValues.toArray());
		sqlMap.put("paramsTypes", paramsType.toArray());
		return sqlMap;
	}

	/**
	 * 自己主動生成插入指定物件的SQL語句,包括物件屬性的值為空的欄位,不包括自增長主鍵,若不存在,呼叫時直接置為null.
	 * @param obj 待生成插入SQL語句的物件
	 * @param tableName 待插入語句相應的資料庫表的名稱
	 * @param keyColumn 資料表主鍵名稱
	 * @return 返回一個包括SQL語句、SQL語句引數值及引數值型別的Map物件
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	public static Map<String, Object> generateInsertWithNull(Object obj, 
			String tableName, String keyColumn) throws IllegalArgumentException, IllegalAccessException {
		StringBuffer columnStrBuf = new StringBuffer(); 
		StringBuffer paramStrBuf = new StringBuffer(); // 記錄SQL語句相應插入的佔位符
		List<Object> columnNameList = new ArrayList<Object>(); // 記錄資料表的欄位名稱
		List<Object> paramValues = new ArrayList<Object>(); // 記錄物件引數值
		List<Integer> paramsType = new ArrayList<Integer>(); // 記錄引數值型別
		Field[] fields = obj.getClass().getDeclaredFields();
		for(int i = 0; i < fields.length; i++){
			fields[i].setAccessible(true);
			// 記錄物件屬性名稱
			if(!fields[i].getName().equalsIgnoreCase(keyColumn)){ // 非主鍵列記錄插入SQL語句的引數佔位符
				columnStrBuf.append(fields[i].getName());
				columnNameList.add(fields[i].getName());
				if (i != fields.length - 1) {
					columnStrBuf.append(",");
				}
				if("class java.util.Date".equals(fields[i].getType().toString())
						&& fields[i].get(obj) != null){
					String timeStr = DateUtil.formatDate((Date)fields[i].get(obj), "yyyy-MM-dd HH:mm:ss");
					paramStrBuf.append("to_date(?
, 'yyyy-MM-dd HH24:mi:ss')");
					paramValues.add(timeStr);
					// 記錄物件屬性的資料型別
					paramsType.add(getOrclDataType(fields[i].getType().toString()));
				}else{
					paramStrBuf.append("?");
					paramValues.add(fields[i].get(obj));
					// 記錄物件屬性的資料型別
					paramsType.add(getOrclDataType(fields[i].getType().toString()));
				}
				if (i != fields.length - 1) {
					paramStrBuf.append(",");
				}
			}
		}
		// 生成插入操作的SQL語句
		StringBuffer sb = new StringBuffer();
		sb.append("insert into ");
		sb.append(tableName);
		sb.append(" (");
		sb.append(columnStrBuf);
		sb.append(") ");
		sb.append("values");
		sb.append(" (");
		sb.append(paramStrBuf);
		sb.append(")");
		// 將生成的SQL語句、SQL語句的列名稱用map儲存並返回
		Map<String, Object> sqlMap = new HashMap<String, Object>();
		
	/*		
		System.out.println(sb.toString());
		System.out.println(columnNameList.toString());
		System.out.println(paramValues.toString());
		System.out.println(paramsType.toString());
	*/		
		sqlMap.put("sql", sb.toString());
		sqlMap.put("columnNameList", columnNameList.toArray());
		sqlMap.put("paramsValues", paramValues.toArray());
		sqlMap.put("paramsTypes", paramsType.toArray());
		return sqlMap;
	}
	
	
	/**
	 * 自己主動生成更新指定物件的SQL語句
	 * @param obj 待生成更新SQL語句的物件
	 * @param tableName 待更新語句相應的資料庫表的名稱
	 * @param keyColumn 待更新記錄的限定欄位
	 * @return 返回一個包括SQL語句及引數值的陣列
	 */
	public static Object[] generateUpdate(Object obj, String tableName, String keyColumn) {
		StringBuffer columnSB = new StringBuffer();
		List<Object> params = new ArrayList<Object>();
		Object keyValue = null;
		// 獲取屬性值不為空的資料表字段名稱
		List<Object> fieldList = ReflectionUtil.getNotNullField(obj);
		try {
			for (int i = 0; i < fieldList.size(); i++) {
				Field field = (Field) fieldList.get(i);
				field.setAccessible(true);

				if (field.getName().equalsIgnoreCase(keyColumn)) {
					keyValue = field.get(obj);
				} else {
					columnSB.append(field.getName());	
					if("class java.util.Date".equals(field.getType().toString())
							&& field.get(obj) != null){
						String timeStr = DateUtil.formatDate((Date)field.get(obj), "yyyy-MM-dd HH:mm:ss");
						columnSB.append("=to_date(?, 'yyyy-MM-dd HH24:mi:ss')");
						params.add(timeStr);
					}else{
						columnSB.append("=?");
						params.add(field.get(obj));
					}
					if (i != fieldList.size() - 1) {
						columnSB.append(",");
					}
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		if (keyValue == null) {
			throw new IllegalArgumentException("資料表 [" + tableName+ "] 中的欄位'"+keyColumn+"'的值不能為空.");
		}else{
			params.add(keyValue);
		}
		StringBuffer sb = new StringBuffer();
		sb.append("update ");
		sb.append(tableName);
		sb.append(" set ");
		if(columnSB.length() >= 0){
			sb.append(columnSB);
		}else{
			sb.append(keyColumn);
			sb.append("=? ");
			params.add(keyValue);
		}		
		sb.append(" where ");
		sb.append(keyColumn);
		sb.append("=?

 ");
		return new Object[] { sb.toString(), params.toArray() };
	}
	
	/**
	 * 返回java資料型別相應的Oracle資料庫的資料型別值
	 * @param javaType java資料型別
	 * @return 返回Oracle資料表的欄位資料型別
	 */
	public static int getOrclDataType(String javaType){
		if("class java.lang.String".equals(javaType)){
			return java.sql.Types.VARCHAR;
		}else if("class java.lang.Integer".equals(javaType) || "int".equals(javaType)){
			return java.sql.Types.INTEGER;
		}else if("class java.lang.Double".equals(javaType) || "double".equals(javaType)){
			return java.sql.Types.DOUBLE;
		}else if("class java.lang.Float".equals(javaType) || "float".equals(javaType)){
			return java.sql.Types.FLOAT;
		}else if("char".equals(javaType)){
			return java.sql.Types.CHAR;
		}else if("class java.lang.Long".equals(javaType) || "long".equals(javaType)){
			return java.sql.Types.NUMERIC;
		}else if("class java.util.Date".equals(javaType)){
			return java.sql.Types.DATE;
		}else{
			return java.sql.Types.VARCHAR;
		}
	}

	/**
	 * 生成SQL語句中的where子句及where子句中引數值
	 * @param obj where條件子句的物件
	 * @return 返回條件不為空的where子句
	 * @throws Exception 
	 * @throws  
	 */
	public static Map<String, Object> generateWhereStr(Object obj) throws  Exception{
		StringBuffer whereStrBuf = new StringBuffer(); // where子句
		List<Object> whereParamValues = new ArrayList<Object>(); // where子句中的引數值
		whereStrBuf.append("  where 1 = 1 ");
		if(obj != null){
			Field[] fields = obj.getClass().getDeclaredFields();
			for(int i = 0; i < fields.length; i++){
				fields[i].setAccessible(true);
				Object columnName = fields[i].get(obj);
				if(columnName != null && !"".equals(columnName)){
					whereStrBuf.append(" and ");
					whereStrBuf.append(fields[i].getName());
					whereStrBuf.append("=?");
					whereParamValues.add(columnName);
				}
			}			
		}
		Map<String, Object> whereMap = new HashMap<String, Object>();
		
/*		System.out.println(whereStrBuf.toString());
		System.out.println(whereParamValues);
		*/
		whereMap.put("whereStr", whereStrBuf.toString());
		whereMap.put("whereParamValues", whereParamValues.toArray());
		return whereMap;
	}

}

  

(6)擴充套件JAVA物件的反射工具類

package com.jkitn.jkits.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * 說明:擴充套件JAVA物件的反射機制
 * @author xdweleven
 * @version 1.0 
 */
public class ReflectionUtil {

    /**
     * 設定物件的指定屬性名稱的屬性值
     * @param obj 待設定的物件
     * @param fieldName 物件屬性名稱
     * @param value 屬性值
     */
    public static void setFieldValue(Object obj, String fieldName, Object value) {
        Class<? extends Object> c = obj.getClass();
        try {
            Field field = null;
            Field[] fields = c.getDeclaredFields();
            for(int i = 0; i < fields.length; i++){
                String fieldNameTemp = fields[i].getName();
                if(fieldNameTemp.equalsIgnoreCase(fieldName)){
                    field = c.getDeclaredField(fieldNameTemp);
                    field.setAccessible(true);
                    field.set(obj, value);
                    return;
                }
            }    
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 獲取物件的指定屬性名稱的屬性值
     * @param obj 待設定的物件
     * @param fieldName 物件屬性名稱
     */
    public static Object getFieldValue(Object obj, String fieldName) {
        Class<? extends Object> c = obj.getClass();
        Field[] fields = c.getDeclaredFields();
        try {
            for(int i = 0; i < fields.length; i++){
                if(fields[i].getName().equalsIgnoreCase(fieldName)){
                    fields[i].setAccessible(true);
                    return fields[i].get(obj);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    /**
     * 獲取物件的屬性值不為空的屬性名稱
     * @param obj 待獲取的物件
     * @return 返回屬性值不為空的物件的屬性名稱列表
     */
    public static List<Object> getNotNullField(Object obj) {
        Class<? extends Object> c = obj.getClass();
        List<Object> list = new ArrayList<Object>();
        try {
            Field[] fields = c.getDeclaredFields();
            for(int i = 0; i < fields.length; i++){
                fields[i].setAccessible(true);
                if(fields[i].get(obj) != null){
                    list.add(fields[i]);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return list;
    }     
}
 (7)定義實現資料庫的CRUD基本操作BaseDao

package com.jkitn.jkits.dao.common;

import java.io.Serializable;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;

import com.jkitn.jkits.common.DBConn;
import com.jkitn.jkits.common.PageBean;
import com.jkitn.jkits.util.ReflectionUtil;
import com.jkitn.jkits.util.SQLUtil;

/**
 * 說明:封裝實現資料庫的CRUD相關的底層操作。
 * @author xdweleven
 * @version 1.0 
 */
public class BaseDao{
    // 獲取資料庫連結例項
    private DBConn dbconn = new DBConn();
    /** 資料庫表的字首  */
    public static final String TB_PREFIX = "tb_jkit_";
    /** 資料庫表的查詢字首  */
    public static final String SELECT_TB_PREFIX = "select * from tb_jkit_";
    /** 升序排列  */
    public static final String ASC = "asc";
    /** 降序排列 */
    public static final String DESC = "desc";

    /**
     * 依據ID查詢物件 
     * @param classType 物件型別
     * @param columnName 編號欄位名稱
     * @param id 物件編號
     * @return 返回實體物件
     */
    public <T> T queryById(Class<T> classType, String columnName, Serializable id) 
            throws Exception{
        StringBuffer sqlBuffer = new StringBuffer();
        sqlBuffer.append(SELECT_TB_PREFIX);
        sqlBuffer.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
        sqlBuffer.append(" where ");
        sqlBuffer.append(columnName);
        sqlBuffer.append(" = ? ");
        this.showSQL(sqlBuffer.toString());
        return dbconn.execQuery(sqlBuffer.toString(), new RowMapper<T>(classType),
                    new Object[]{id}).get(0);
    }
    
    /**
     * 查詢全部指定class型別的物件資訊
     * @param classType 物件型別
     * @return 返回實體物件列表
     */
    public <T> List<T> queryAll(Class<T> classType) throws Exception{
        String sql = SELECT_TB_PREFIX + this.toLowerCaseFirstOne(classType.getSimpleName());
        this.showSQL(sql);
        return dbconn.execQuery(sql, new RowMapper<T>(classType));
    }
    
     /**
     * 查詢指定物件型別的物件資訊,並依照指定的排序欄位進行升序或降序排序
     * @param classType 物件型別
     * @param orderColumn 排序欄位
     * @param ascOrDesc 降序或升序:asc表示升序。desc表示降序
     * @return 返回實體物件列表
     */
    public <T> List<T> queryAllWithOrder(Class<T> classType, String orderColumn, 
            String ascOrDesc) throws Exception{
        StringBuffer sqlBuffer = new StringBuffer();
        sqlBuffer.append(SELECT_TB_PREFIX);
        sqlBuffer.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
        sqlBuffer.append(" order by ");
        sqlBuffer.append(orderColumn);
        sqlBuffer.append(" ");
        sqlBuffer.append(ascOrDesc);
        this.showSQL(sqlBuffer.toString());
        return dbconn.execQuery(sqlBuffer.toString(), new RowMapper<T>(classType));
    }
    
    /**
     * 查詢指定SQL語句的物件資訊列表
     * @param sql 查詢語句
     * @param classType 物件型別
     * @param params SQL語句引數
     * @return 返回實體物件列表
     */
    public <T> List<T> query(String sql, Class<T> classType, Object... params) 
              throws Exception{
        this.showSQL(sql);
        return dbconn.execQuery(sql, new RowMapper<T>(classType), params);
    }
    
    /**
     * 查詢指定SQL語句的物件資訊列表
     * @param sql 查詢語句
     * @param classType 物件型別
     * @param params SQL語句引數
     * @return 返回實體物件列表
     */
    public <T> T queryForObj(String sql, Class<T> classType, Object... params) 
            throws Exception{
        this.showSQL(sql);
        return dbconn.execQuery(sql, new RowMapper<T>(classType), params).get(0);
    }
    
    /**
     * 分頁查詢實體物件列表資訊
     * @param sql 原始的SQL語句
     * @param classType 物件型別
     * @param curPage 當前頁碼
     * @param rowsPerPage 每頁顯示的記錄數
     * @param params SQL語句引數
     * @return 返回當前頁碼的分頁物件
     */
    public <T> PageBean<T> queryByPage(String sql, Class<T> classType, int curPage, 
            int rowsPerPage, Object... params) throws Exception{
         // 獲取記錄總數
         int totalRows = this.getTotalRows(sql, params);
         PageBean<T> pageBean = new PageBean<T>();
         pageBean.setCurPage(curPage); // 設定當前頁碼
         pageBean.initPageBean(totalRows, rowsPerPage); // 初始化分頁物件的相關屬性
         // 生成當前分頁查詢語句(MySql)
         String pageSql = pageBean.getPageMySQL(sql, curPage, rowsPerPage);
         this.showSQL(pageSql);
         // 執行查詢操作
         pageBean.setPageList(dbconn.execQuery(sql, new RowMapper<T>(classType), params));
         return pageBean;
    }
    
     /**
     * 儲存物件到資料庫中,若資料庫中的使用者表有自增序列,則須要指出表中自增列的欄位名稱,另外,
     * 資料庫中相應的自增序列的名稱需按例如以下格式取名:class名稱_自增列欄位名稱_SEQ,
     * 比如使用者的class為Users,自增序列欄位名稱為id,則資料庫中的自增序列的名稱取名為USERS_ID_SEQ.
     * @param obj 實體物件
     * @param sequenceKeyColumn 資料表自增序列的欄位名稱,若不存在。則置為null。

     * @return 返回被更新的記錄數
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     */
    public <T> int insert(T obj, String sequenceKeyColumn) throws Exception{
        String tableName = TB_PREFIX + this.toLowerCaseFirstOne(obj.getClass().getSimpleName());
        // 自己主動生成物件的無自增序列插入SQL語句及其相關插入的引數值和型別
        Map<String, Object> sqlMap = SQLUtil.generateInsertWithNull(obj, tableName, sequenceKeyColumn);
        String sql = sqlMap.get("sql").toString(); // SQL語句
        Object[] paramsValues = (Object[])sqlMap.get("paramsValues"); // SQL語句的引數值
        // int[] paramsTypes = this.parseArrayToInt((Object[])sqlMap.get("paramsTypes")); // 引數值型別
        this.showSQL(sql);
        return dbconn.execUpdate(sql, paramsValues);
    }
    
    /**
     * 更新物件
     * @param obj 待更新的實體物件
     * @param keyColumn 更新物件的限定條件欄位名稱
     * @return 返回被更新的記錄數
     */
    public <T> int update(T obj, String keyColumn) throws Exception{
        String tableName = TB_PREFIX + this.toLowerCaseFirstOne(obj.getClass().getSimpleName());
        // 自己主動生成物件的更新操作的SQL語句及其引數值
        Object[] updateSql = SQLUtil.generateUpdate(obj, tableName, keyColumn);
        this.showSQL(updateSql[0].toString());
        return dbconn.execUpdate(updateSql[0].toString(), (Object[])updateSql[1]);
    }
    
    /**
     * 刪除物件
     * @param obj 待更新的實體物件
     * @param keyColumn 刪除的限定條件欄位
     * @return 返回被刪除的記錄數
     */
    public <T> int delete(T obj, String keyColumn) throws Exception{
        // 獲取限定條件的值
        Object keyValue = ReflectionUtil.getFieldValue(obj, keyColumn);
        if(keyValue == null){
            throw new RuntimeException("["+obj.getClass()+"]中不存在屬性'"+keyColumn+"'或屬性值為空.");
        }
        StringBuffer sqlBuffer = new StringBuffer();
        sqlBuffer.append("delete from ");
        sqlBuffer.append(TB_PREFIX);
        sqlBuffer.append(this.toLowerCaseFirstOne(obj.getClass().getSimpleName()));
        sqlBuffer.append(" where ");
        sqlBuffer.append(keyColumn);
        sqlBuffer.append(" = ? ");
        this.showSQL(sqlBuffer.toString());
        return dbconn.execUpdate(sqlBuffer.toString(), keyValue.toString());
    }
    
    /**
     * 刪除指定編號的實體物件
     * @param classType 物件型別
     * @param keyColumn ID相應的資料表列名稱
     * @param id 實體物件編號
     * @return 返回刪除的記錄數
     */
    public <T> int deleteById(Class<T> classType, String keyColumn, Serializable id) 
            throws Exception{
        StringBuffer sqlBuffer = new StringBuffer();
        sqlBuffer.append("delete from ");
        sqlBuffer.append(TB_PREFIX);
        sqlBuffer.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
        sqlBuffer.append(" where ");
        sqlBuffer.append(keyColumn);
        sqlBuffer.append(" = ? ");
        this.showSQL(sqlBuffer.toString());
        return dbconn.execUpdate(sqlBuffer.toString(), id);
    }
    
     /**
     * 批量刪除指定編號的實體物件
     * @param classType 物件型別
     * @param idColumnName 編號欄位名稱 
     * @param ids 待刪除物件的編號陣列
     */
    public <T> int deleteByIds(Class<T> classType, String idColumnName,
            Serializable[] ids) throws Exception{
        StringBuffer sqlBuffer = new StringBuffer();
        sqlBuffer.append("delete from ");
        sqlBuffer.append(TB_PREFIX);
        sqlBuffer.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
        sqlBuffer.append(" where ");
        sqlBuffer.append(idColumnName);
        sqlBuffer.append(" = ? ");
        this.showSQL(sqlBuffer.toString());
        int rowNums = 0; // 刪除的記錄數
        for(int i = 0; i < ids.length; i++){
            rowNums += this.deleteById(classType, idColumnName, ids[i]);
        }
        return rowNums;
    }
    
    /**
     * 更新操作
     * @param sql 刪除操作的SQL語句
     * @param params SQL語句中的引數值
     * @return 返回刪除的記錄數
     */
    public int update(String sql, Object... params) throws Exception{
        this.showSQL(sql);
        return dbconn.execUpdate(sql, params);
    }
    
    /**
     * 批量更新物件
     * @param objs 待更新的實體物件列表
     * @param keyColumn 主鍵欄位名稱
     */
    public <T> int batchUpdate(List<T> objs, String keyColumn) throws Exception{
        if(objs == null || objs.isEmpty()){
            return 0;
        }
        int updateNum = 0;
        // 自己主動生成物件的更新操作的SQL語句及其引數值
        for(int i = 0; i < objs.size(); i++){
            T obj = objs.get(i);
            updateNum += this.update(obj, keyColumn);
        }
        return updateNum;
    }
    
     /**
     * 批量插入物件
     * @param objs 待新增的實體物件列表
     * @param keyColumn 資料表主鍵列名稱
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     */
    public <T> int batchInsert(List<T> objs, String keyColumn) throws Exception {
        if(objs == null || objs.isEmpty()){
            return 0;
        }
        int updateNum = 0;
        // 自己主動生成物件的更新操作的SQL語句及其引數值
        for(int i = 0; i < objs.size(); i++){
            T obj = objs.get(i);
            updateNum += this.insert(obj, keyColumn);
        }
        return updateNum;
    }
    
    /**
     * 統計指定統計數量的SQL語句
     * @param sql 待執行的SQL語句
     * @param params SQL語句引數值
     * @return 返回記錄總數
     * @throws Exception
     */
    public int getTotalRows(String sql, Object... params) throws Exception{
        String totalRowsSql = "select count(*) totalRows from ( "+sql+" )";
        this.showSQL(totalRowsSql);
        ResultSet rs = dbconn.queryForResultSet(totalRowsSql, params);
        while(rs.next()){
            return rs.getInt("totalRows");
        }
        return 0;
    }
    
    /**
     * 刪除操作
     * @param sql 刪除操作的SQL語句
     * @param params SQL語句中的引數值
     * @return 返回刪除的記錄數
     */
    public int delete(String sql, Object... params) throws Exception{
        this.showSQL(sql);
        return dbconn.execUpdate(sql, params);
    }
    
    /**
     * 獲取下一個指定自增序列的值(MySql)
     * @param classType 物件型別
     * @param seqColName 自增欄位名稱
     * @return 返回指定表的主鍵自增序列的最新值
     */
    public <T> int getNextAutoIncrementVal(Class<T> classType, String seqColName) throws Exception{
        StringBuffer sqlBuf = new StringBuffer();
        sqlBuf.append("select max(");
        sqlBuf.append(seqColName);
        sqlBuf.append(")+1 nextId from ");
        sqlBuf.append(TB_PREFIX);
        sqlBuf.append(this.toLowerCaseFirstOne(classType.getSimpleName()));
        this.showSQL(sqlBuf.toString());
        ResultSet rs = dbconn.queryForResultSet(sqlBuf.toString());
        if(rs.next()){
            return rs.getInt("nextId");
        }else{
            return 0;
        }
    }    

    /**
     * 首字母轉小寫
     * @param str 待轉換的字元創
     * @return 返回首字母小寫後的字串
     */
    public String toLowerCaseFirstOne(String str){
         if(Character.isLowerCase(str.charAt(0))){
              return str;
         }else{
             return (new StringBuilder()).append(Character.toLowerCase(str.charAt(0))).
                     append(str.substring(1)).toString();
         }
    }
    
    /**
     * 首字母轉大寫
     * @param str 待轉換的字串
     * @return 返回首字母大寫的字串
     */
    public String toUpperCaseFirstOne(String str){
         if(Character.isUpperCase(str.charAt(0))){
             return str;
         }else{
             return (new StringBuilder()).append(Character.toUpperCase(str.charAt(0))).
                     append(str.substring(1)).toString();
         }
    }

    /**
     * 列印SQL語句
     * @param sql
     */
    public void showSQL(String sql){
        System.out.println(sql);
    }
    
}