1. 程式人生 > >懶人系列——增刪改查封裝(一)

懶人系列——增刪改查封裝(一)

作為一個懶人就不廢話了,新入職的一個小公司資料庫表不復雜,查詢也基本是單表,但是表的欄位很長(想象一下專案就幾張表,分表不均)。對於資料庫的操作第一個想到的是hibernate,mybatis這些框架(別問我為什麼,懶啊),但是想想又沒對就幾張表的事你給我加個框架???(據說要求jdbc的效能)。用原生的jdbc,意味著大量的程式碼,意味著。。。最終想起似乎有個叫DBUtils東東據說效能約等於jdbc??(關於DBUtils本人瞭解其實也不多,畢竟以前都是ORM框架搞事。。。)嗯,選它 了。最後連線池配好走起。

但是,很快問題就來了。十多個欄位啊!問號數得我腦袋暈+_+,SQL語句寫到一半(我剛剛寫到那個屬性了來著?心裡想著物件操作的好啊!)忍無可忍又無法改資料庫的情況下,開始想懶辦法了(咳咳,好像繞多了,畢竟第一次寫博文有點小緊張)

直接來程式碼好了:

	/**
	 * 更新任意物件(表記錄)的所有列(屬性)
	 * @param obj 要更新的記錄物件(表名)
	 * @return res 影響的列
	 */
	public static int newUpdate(Object obj,String sigin){
		int res = 0;
		
		System.out.println("更新 中.......");
		int num = 0;
		StringBuffer sqlbuffer =  new StringBuffer();
		//用於儲存欄位值
		//StringBuffer valuebuffer = new StringBuffer();
		ArrayList<String> valuelist = new ArrayList<String>();
		sqlbuffer.append("UPDATE ");
		String signvalue = null;
		try {
			Class tableclass = Class.forName(obj.getClass().getName());
			sqlbuffer.append(tableclass.getSimpleName().toLowerCase()+" SET ");//linux下MySql預設區分大小寫
			Field[] fields = tableclass.getDeclaredFields();
			for(int i = 0; i < fields.length; i++){
				fields[i].setAccessible(true);
				if(sigin.equals(fields[i].getName())){
					signvalue = fields[i].get(obj) + "";
				}
				sqlbuffer.append(fields[i].getName() + " = ");
				if(i < fields.length - 1){
					valuelist.add(toString(fields[i].get(obj)));
				//valuebuffer.append(fields[i].get(obj));
				sqlbuffer.append("? , ");
				}else{
					//valuebuffer.append(fields[i].get(obj));
					valuelist.add(toString(fields[i].get(obj)));
					sqlbuffer.append("?");
				}
			}
			String sql = sqlbuffer.toString() + " where "+ sigin +" =  ? ";
			
			//valuebuffer.toString();
//			
//			Object[] param = new Object[valuebuffer.length() + 2];
//			for(int i = 0; i < param.length; i++){
//				if(i < valuebuffer.length()){
//			//	param[i] = valuebuffer.;
//				
//				}
//			}
//			param[valuebuffer.length()] = sigin;
//			param[valuebuffer.length() + 1] = signvalue;
			
			String[] params = new String[valuelist.size() + 1];
			for(int i = 0; i < valuelist.size(); i++){
				params[i] = valuelist.get(i);
			}
			params[valuelist.size()] = signvalue;
		
			QueryRunner qr = new QueryRunner();
			res = qr.update(connection, sql, params);
			System.out.println(sql);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("影響的行:" + res);
		return res;
	}
/**
	 * toString防止空指標
	 */
	public static String toString(Object obj){
		String message = null == obj ? "null" : obj + "";
		return message;
	}

當然程式碼還有很大的優化空間(比如那個Class.forname。。。以及儲存和迴圈)。整個程式碼說起來也簡單,通過傳入任意對映物件Object,通過class獲取其屬性列表和值最後和sql進行拼接,第二個引數相當於sql語句中的where 判斷,從而完成傳入任意對映物件,對資料庫對應記錄的修改功能(其他的邏輯是一樣的就不列舉了)

當然,上面的程式碼肯定只適合單表。那麼多表又怎麼辦呢?其實也很簡單,只要排除常規型別獲取屬性和加join就可以了,這裡就不列舉了,給個片段就行了(我才不會說是我懶沒完善。。。)

for(Field field : fields){
			field.setAccessible(true);
			System.out.println(field.getName());
			System.out.println(field.getType());
			field.getType().toString();
			try {
				
				Class childc = field.get(obj).getClass();
				if(childc.getPackage().getName().indexOf("java.lang") < 0){	
				System.out.println("找到關聯的類:" + childc.getSimpleName());
				 Field[] fds = childc.getDeclaredFields();
//......