懶人系列——增刪改查封裝(一)
阿新 • • 發佈:2019-02-17
作為一個懶人就不廢話了,新入職的一個小公司資料庫表不復雜,查詢也基本是單表,但是表的欄位很長(想象一下專案就幾張表,分表不均)。對於資料庫的操作第一個想到的是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();
//......