用反射寫的BaseDao

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.bjsxt.wuye.util.DBUtil;
import com.bjsxt.wuye.util.GetNameUtil;
import com.bjsxt.wuye.util.PageUtil;

@SuppressWarnings("unchecked")
public class BaseDao{
	/**
	 * 拼接oracle  分頁sql語句
	 * @param sql
	 * @return
	 */
	public String getOraclePageSql(String sql){
		StringBuffer sqlBuffer = new StringBuffer("select * from (select a_tab_01.*,rownum a_row_num_r  from (");
		sqlBuffer.append(sql);
		sqlBuffer.append("	) a_tab_01 where rownum<=?) b_tab_02 where a_row_num_r>=?");
		return sqlBuffer.toString();
	}
	/**
	 * 單表 等值查詢   分頁
	 * @param objVo
	 * @param pageNumStr
	 * @param pageSize
	 * @return
	 */
	public PageUtil queryListByPage(Object objVo,String pageNumStr,String pageSize) 
	throws ClassNotFoundException, SQLException, SecurityException, 
	IllegalArgumentException, InstantiationException, 
	IllegalAccessException, NoSuchFieldException, 
	NoSuchMethodException, InvocationTargetException{
		List  sqlAndParamList = getSqlAndParam(objVo, "");
		if(sqlAndParamList != null&&sqlAndParamList.size()>0){
			StringBuffer sql = (StringBuffer) sqlAndParamList.get(0);
			List paramList = (List) sqlAndParamList.get(1);
			return queryListByPage(sql.toString(),objVo.getClass(),pageNumStr,pageSize,paramList.toArray());
		}
		return null;
	}
	/**分頁查詢
	 * @param sql
	 * @param c
	 * @param pageNumStr
	 * @param pageSize
	 * @param param
	 * @return
	 */
	public PageUtil queryListByPage(String sql,Class c,String pageNumStr,String pageSize,Object...param) 
	throws ClassNotFoundException, SQLException, SecurityException, 
	IllegalArgumentException, InstantiationException, 
	IllegalAccessException, NoSuchFieldException, 
	NoSuchMethodException, InvocationTargetException{
		if(c!=null){
			String totalSql = "select count(*)  from "+sql.split("from")[1];//獲取統計記錄總數的sql語句
			int totalCount = getTotalCount(totalSql,param);
			//建立 PageUtil對象
			PageUtil pageUtil = new PageUtil(pageSize,pageNumStr,totalCount);
			//獲取鏈接
			Connection conn = DBUtil.getConn();
			//獲取Oracle 分頁的查詢語句
			sql = getOraclePageSql(sql);
			//預處理sql語句
			PreparedStatement ps = conn.prepareStatement(sql);
			//填坑
			setPsValue(ps, param);
			//把分頁條件 從第幾條記錄到第幾條記錄數據補充到PreparedStatement對象
			ps.setObject(param==null?1:param.length+1, pageUtil.getRowEnd());
			ps.setObject(param==null?2:param.length+2, pageUtil.getRowStart());
			//獲取結果集
			ResultSet rs = ps.executeQuery();
			//將結果集放入vo,再放入list容器
			List resultList = addList(rs, c);
			//關閉對象
			DBUtil.close(conn, ps, rs);
			pageUtil.setList(resultList);
			return pageUtil;
		}else{
			System.out.println("反射對象不能爲null");
			return null;
		}
	}

	/**
	 * 查詢並返回對象結果集 
	 * @param sql  輸入的sql語句
	 * @param c   相對應的類
	 * @param param  準備填坑的參數
	 * @return  返回查詢到的對象結果集List
	 */
	public List queryList(String sql,Class c,Object...param) throws ClassNotFoundException, 
			SQLException, InstantiationException, IllegalAccessException, 
			SecurityException, NoSuchFieldException, NoSuchMethodException,
			IllegalArgumentException, InvocationTargetException {
		if(c != null){
			//第一步:  獲取鏈接
			Connection conn = DBUtil.getConn();
			//第二步:  sql 語句 挖坑    預處理sql語句
			PreparedStatement  ps  = conn.prepareStatement(sql);
			//第三步:  給sql語句填坑
			setPsValue(ps,param);
			//第四步: 執行查詢
			ResultSet  rs = ps.executeQuery();
			//根據輸入的sql語句和對應的填坑參數返回查詢到的對象List
			List resultList = addList(rs, c);  
			DBUtil.close(conn, ps, rs);  //關閉與數據庫的連接
			return resultList;
		}else{
			System.out.println("反射對象不能爲null");
			return null;
		}
    }
	
	/**
	 * 填坑
	 * @param ps 預處理對象
	 * @param param  準備填坑的參數
	 */
	private void setPsValue(PreparedStatement ps,Object...param) throws SQLException{
		if(param !=null&&param.length>0){
			for(int i = 0;i<param.length;i++){
				ps.setObject(i+1,param[i]);
			}
		}
	}

	/**
	 * 查詢並返回對象結果集 
	 * @param rs  查詢到的結果集
	 * @param c   結果集要賦值給的相關類
	 * @return  返回查詢到的對象List
	 */
	public List addList(ResultSet rs,Class c) throws SQLException, InstantiationException, 
	IllegalAccessException, SecurityException, NoSuchFieldException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException{
		List resultList  = new ArrayList();
		//遍歷rs中的結果集
		while(rs.next()){
			//把rs結果集賦給對應的類對象,而後獲取相對應的類對象
			Object obj = setObjectFieldValue(rs,c);
			resultList.add(obj);  
		}
		return resultList;
	}
	
	/**
	 * 給vo對象屬性賦值
	 * @param rs  查詢到的結果集
	 * @param c  結果集要插入的對應類
	 * @return  獲取對應的類對象
	 */
	private Object setObjectFieldValue(ResultSet rs,Class c) throws SQLException, SecurityException, NoSuchFieldException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException{
		ResultSetMetaData rsmd = rs.getMetaData();  //獲取rs中的元數據
		int colCount = rsmd.getColumnCount();   //獲取rs中有多少列
		Object obj = c.newInstance();          //建立vo對象
		for(int i = 1;i<=colCount;i++){
			String colName = rsmd.getColumnName(i);  //獲取sql語句中字段名
			if(!colName.toLowerCase().equals("a_row_num_r")){
				String fieldName = GetNameUtil.getFieldNameByColName(colName);  //根據sql語句中字段名獲取屬性名
				String setter = GetNameUtil.getSetter(fieldName);  //經過屬性名獲取設定器名
				Field field = c.getDeclaredField(fieldName);   //獲取VO類中的屬性名
				//獲取設定器對應的映射方法
				Method m = c.getDeclaredMethod(setter, field.getType());
				Object value = rs.getObject(i);  //獲取rs中查詢到和屬性名對應的值
				//調用設定器
				invokeSetter(value,field,m,obj);
			}
		}
		return obj;
	}
	
	/**
	 * 不一樣類型下調用設定器
	 * @param value  屬性名對應的值
	 * @param field  屬性名
	 * @param m  和屬性嗎對應的方法
	 * @param obj  和屬性名對應的類對象
	 */
	private void invokeSetter(Object value,Field field,Method m,Object obj) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException{
		if(value !=null){
			if(value.getClass()==BigDecimal.class){//判斷 字段結果類型是不是BigDecimal
				BigDecimal bd = (BigDecimal)value;  //強制類型轉換
				if(field.getType()==Integer.class||field.getType()==int.class){//屬性類型是Integer
					m.invoke(obj, bd.intValue());
				}else if(field.getType()==Double.class||field.getType()==double.class){
					m.invoke(obj, bd.doubleValue());
				}else if(field.getType()==Float.class||field.getType()==float.class){
					m.invoke(obj, bd.floatValue());
				}else if(field.getType()==Byte.class||field.getType()==byte.class){
					m.invoke(obj, bd.byteValue());
				}else if(field.getType()==long.class||field.getType()==Long.class){
					m.invoke(obj, bd.longValue());
				}else if(field.getType()==Short.class||field.getType()==short.class){
					m.invoke(obj, bd.shortValue());
				}
			}else{
				m.invoke(obj,value);
			}
		}
	}
	
	/**
	 * 根據條件進行單表查詢 
	 * @param objVo  類對象
	 * @return 獲得查詢到的對象結果集
	 */
	public List queryList(Object objVo) throws SecurityException, NoSuchMethodException,
	IllegalArgumentException, IllegalAccessException,
	InvocationTargetException, ClassNotFoundException, 
	SQLException, InstantiationException, NoSuchFieldException{
		//獲取sql語句和參數聚合集
		List sqlAndParamList = getSqlAndParam(objVo,"");
		if(sqlAndParamList != null&&sqlAndParamList.size()>0){
			String sql = sqlAndParamList.get(0).toString();
			List paramList = (List) sqlAndParamList.get(1);
			//調用  查詢結果集的方法
			return queryList(sql,objVo.getClass(),paramList.toArray());
		}
		return null;
	}
	/**
	 * 獲取屬性值
	 * @param field 屬性名
	 * @param objVo 屬性名對應類對象
	 * @return  獲得獲取的屬性值
	 */
	private  Object getFieldValue(Field field,Object objVo) throws SecurityException, 
			NoSuchMethodException, IllegalArgumentException, 
			IllegalAccessException, InvocationTargetException{
		String getter = GetNameUtil.getGetter(field);   //獲取取值器名
		Method m = objVo.getClass().getDeclaredMethod(getter);  //獲取取值器
		Object value = m.invoke(objVo);
		return value;
	}
	
	/**
	 * 獲取sql語句和參數聚合集
	 * @param objVo  sql語句對應的類對象
	 * @return 獲得sql語句和參數聚合集
	 */
	private List  getSqlAndParam(Object objVo,String remark) throws SecurityException, 
			NoSuchMethodException, IllegalArgumentException,
			IllegalAccessException, InvocationTargetException{
		List resultList = new ArrayList();
		List paramList = new ArrayList();
		Class c = objVo.getClass();  //根據對象名獲取類名
		String tabName = GetNameUtil.getTabOrColName(c.getSimpleName());  //根據類名獲取代表
		String sqlPre = remark.equals("totalCount")?"select count(*) from  ":"select * from ";
		StringBuffer sql = new StringBuffer(sqlPre+"  "+tabName+"  t where 1=1");
		//獲取 參數對象屬性名數組
		Field[]  fieldArray = c.getDeclaredFields();  
		//遍歷屬性名數組獲取每一個屬性值
		for(int i = 0;i<fieldArray.length;i++){
			Object value = getFieldValue(fieldArray[i],objVo);  //獲取屬性值
			if(value!=null){
				if(value.getClass()!=String.class){
					sql.append("	and  t."+GetNameUtil.getTabOrColName(fieldArray[i].getName())+"=?");  //獲取列明
					paramList.add(value);
				}else{
					if(!((String)value).trim().equals("")){
						sql.append("	and  t."+GetNameUtil.getTabOrColName(fieldArray[i].getName())+"=?"); //獲取列明
						paramList.add(value);  //把參數置入參數聚合集
					}
				}
			}
		}
		resultList.add(sql);  //獲得sql語句
		resultList.add(paramList);  //將參數聚合集放入結果聚合集中
		return resultList;
	}

	/**
	 * 獲取記錄總數
	 * @param sql  輸入的sql語句
	 * @param param  參數集
	 * @return  獲得記錄總數
	 */
	private int getTotalCount(String sql,Object...param) throws ClassNotFoundException, SQLException{
		//獲取鏈接
		Connection conn = DBUtil.getConn();
		//預處理sql語句
		PreparedStatement ps = conn.prepareStatement(sql);
		//填坑
		setPsValue(ps, param);
		//獲取rs結果集
		ResultSet  rs = ps.executeQuery();
		//獲取記錄總數
		int count = rs.next()?rs.getInt(1):0;
		DBUtil.close(conn, ps, rs);
		return count;	
	}
	/**
	 * 獲取記錄總數
	 * @param objVo 類對象
	 * @return  獲得查詢記錄數
	 */
	public int getTotalCount(Object objVo) throws SecurityException, IllegalArgumentException,
	NoSuchMethodException, IllegalAccessException,
	InvocationTargetException, ClassNotFoundException, SQLException{
		List sqlAndParamList = getSqlAndParam(objVo,"totalCount");  //獲取sql語句和參數聚合集
		if(sqlAndParamList != null&&sqlAndParamList.size()>0){
			String sql = sqlAndParamList.get(0).toString();
			List paramList = (List) sqlAndParamList.get(1);
			//調用  查詢結果集的方法
			return getTotalCount(sql,paramList.toArray());
		}
		return 0;
	}
	
	/**
	 * 根據Id獲取單條記錄
	 * @param objVo  對象
	 * @return  獲得查詢到的對象
	 */
	public  Object queryObjectById(Object objVo) throws SecurityException, IllegalArgumentException,
	NoSuchMethodException, IllegalAccessException,
	InvocationTargetException, ClassNotFoundException, 
	SQLException, InstantiationException, 
	NoSuchFieldException{
		List list = queryList(objVo); //查詢到對應的對象結果集
		if(list!=null&&list.size()>0){
			return list.get(0);
		}
		return null;
	}
	
	/**
	 * 向數據庫中插入數據
	 * @param objVo  對應 插入數據的類對象
	 * @param preKeyField  sql語句中的對應相關表的主鍵
	 */
	public void  addVo(Object objVo,String preKeyField) throws SecurityException, 
	NoSuchMethodException, IllegalArgumentException, IllegalAccessException, 
	InvocationTargetException, ClassNotFoundException, SQLException{
			//建立裝參數的集合
			List paramList = new ArrayList();
			//獲取反射對象
		  	Class c = objVo.getClass();
			String tabName = GetNameUtil.getTabOrColName(c.getSimpleName());  //獲取表名
			StringBuffer sql = new StringBuffer("insert into "+tabName+"  values(");
			//獲取類對象中的屬性名數組
			Field[] fieldArray = c.getDeclaredFields();
			//遍歷屬性名
			for(int i = 0;i<fieldArray.length;i++){
				String fieldName = fieldArray[i].getName();
				if(!fieldName.equals(preKeyField)){
					sql.append("?,");
					Object value = getFieldValue(fieldArray[i], objVo);  //獲取屬性值
					paramList.add(value);  //把屬性值裝入參數聚合集
				} else{
					sql.append("seq_"+tabName+".nextval,");  //獲取sql語句中的遞增值
				}
			}
			sql.deleteCharAt(sql.length()-1);  //去掉sql語句中最後一個逗號
			sql.append(")");
			//添加數據
			modifyVo(sql.toString(),paramList.toArray());
	}
	
	/**
	 * 更新數據庫相關記錄
	 * @param objVo    要修改的vo對象
	 * @param preKeyField   必寫   主鍵對應的屬性名
	 */
	public void updateVo(Object objVo,String... preKeyFields) throws SecurityException, 
			IllegalArgumentException, NoSuchMethodException,
			IllegalAccessException, InvocationTargetException, NoSuchFieldException,
			ClassNotFoundException, SQLException{
		List paramList = new ArrayList();  //建立裝參數的集合
	  	Class c = objVo.getClass();  //獲取反射對象
		String tabName = GetNameUtil.getTabOrColName(c.getSimpleName()); //獲取表名
		//拼接sql
		StringBuffer sql = new StringBuffer("update "+tabName+" t  set ");
		Field[] fieldArray = c.getDeclaredFields();  //獲取屬性名
		//遍歷屬性名數組
		for(int i = 0;i<fieldArray.length;i++){
			String fieldName = fieldArray[i].getName();
			int j =0 ;
			for (j = 0; j < preKeyFields.length; j++) {
				if(fieldName.equals(preKeyFields[j])){
					break;
				}	
			}
			Object value = getFieldValue(fieldArray[i], objVo);  //獲取屬性值
			if(j>=preKeyFields.length && null != value && !"".equals(value)){
				sql.append("t."+GetNameUtil.getTabOrColName(fieldName)+"=? ,");
					paramList.add(value);  //將獲得的屬性值裝入參數聚合集
			}
		}
		sql.deleteCharAt(sql.length()-1);
		sql.append(" where t."+GetNameUtil.getTabOrColName(preKeyFields[0])+"=? ");	
		for(int i=1; i<preKeyFields.length;i++){
			sql.append(" and "+GetNameUtil.getTabOrColName(preKeyFields[i])+"=? ");
		}
		System.out.println(sql);
		//根據傳進來的主鍵名字  獲取主鍵對應的屬性名 
		for(String preKeyField:preKeyFields){
			Field preKeyFieldObj = c.getDeclaredField(preKeyField);
			//獲取主鍵對應的屬性值
			Object keyValue = getFieldValue(preKeyFieldObj, objVo);
			//將主鍵的值裝入參數聚合
			paramList.add(keyValue);
			//修改信息	
		}
		modifyVo(sql.toString(),paramList.toArray());
	}
	/**
	 * 刪除數據庫單條記錄
	 * @param objVo  裝有主鍵參數值的對象
	 * @param preKeyField  主鍵對應的名字
	 */
	public void deleteVo(Object objVo,String preKeyField) throws SecurityException, NoSuchFieldException, 
	IllegalArgumentException, NoSuchMethodException,
	IllegalAccessException, InvocationTargetException, ClassNotFoundException, SQLException{
		//獲取反射對象
	  	Class c = objVo.getClass();
		String tabName = GetNameUtil.getTabOrColName(c.getSimpleName());//獲取表名
		//拼接sql
		StringBuffer sql = new StringBuffer("delete from "+tabName+" t  where t. "+GetNameUtil.getTabOrColName(preKeyField)+"=?");
		//根據傳進來的主鍵名字  獲取主鍵對應的對像中的屬性名
		Field preKeyFieldObj = c.getDeclaredField(preKeyField);
		//獲取主鍵對應的屬性值
		Object keyValue = getFieldValue(preKeyFieldObj, objVo);
		//刪除單條記錄
		modifyVo(sql.toString(),keyValue);
	}
	
	/**
	 * 增刪改公用的方法
	 * @param sql 輸入的sql語句
	 * @param param  參數聚合集
	 */
	private void modifyVo(String sql,Object...param) throws ClassNotFoundException, SQLException{
		//獲取鏈接
		Connection conn = DBUtil.getConn();
		//預處理sql語句
		PreparedStatement ps = conn.prepareStatement(sql);
		//填坑
		setPsValue(ps, param);
		//執行
		ps.executeUpdate();
		//關閉
		DBUtil.close(conn, ps, null);
	}
}
相關文章
相關標籤/搜索