簡析DBHelper
阿新 • • 發佈:2019-01-14
package com.hjb.dao; import java.lang.reflect.Method; import java.sql.Blob; 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.HashMap; import java.util.List; import java.util.Map; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; public class DBHelper { /** * 獲取連線 * * @return */ private Connection getConnection() { Connection con = null; try { DataSource ds = (DataSource) new InitialContext().lookup("java:comp/env/yc"); con = ds.getConnection(); } catch (NamingException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return con; } /** * 關閉資源 * * @param con * @param pstmt * @param rs */ private void close(Connection con, PreparedStatement pstmt, ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (con != null) { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } } /** * 給預編譯語句中的佔位符賦值 * * @param pstmt * @param params */ public void setParams(PreparedStatement pstmt, Object... params) { if (params != null && params.length > 0) { for (int i = 0, len = params.length; i < len; i++) { try { pstmt.setObject(i + 1, params[i]); } catch (SQLException e) { System.out.println("第" + (i + 1) + "個注值失敗..." + e.getMessage()); e.printStackTrace(); } } } } /** * 給預編譯語句中的佔位符賦值 * * @param pstmt * @param params */ public void setParams(PreparedStatement pstmt, List<Object> params) { if (params != null && params.size() > 0) { for (int i = 0, len = params.size(); i < len; i++) { try { pstmt.setObject(i + 1, params.get(i)); } catch (SQLException e) { System.out.println("第" + (i + 1) + "個注值失敗..." + e.getMessage()); e.printStackTrace(); } } } } /** * 獲取結果集中的列名 * * @param rsmd * @param count * @return */ public String[] getColumnNames(ResultSetMetaData rsmd, int count) { String[] colNames = null; if (rsmd != null) { colNames = new String[count]; try { for (int i = 0; i < count; i++) { colNames[i] = rsmd.getColumnName(i + 1).toLowerCase(); } } catch (SQLException e) { e.printStackTrace(); } } return colNames; } /** * 獲取結果集中的列名 * * @param rs * @return * @throws Exception */ public String[] getColumnNames(ResultSet rs) throws Exception { ResultSetMetaData rsmd = rs.getMetaData(); int len = rsmd.getColumnCount(); // 獲取結果集中列 的數量 String[] colNames = new String[len]; // 迴圈取出每個列的列名存放到colNames陣列中 for (int i = 0; i < len; i++) { colNames[i] = rsmd.getColumnName(i + 1).toLowerCase(); // 將每個列名全部轉化為小寫字母 } return colNames; } /** * 新增操作 * * @param sql * @param params * @return */ public int update(String sql, Object... params) { int result = 0; Connection con = null; PreparedStatement pstmt = null; try { // 獲取連線 con = this.getConnection(); // 執行預編譯語句 pstmt = con.prepareStatement(sql); // 給預編譯的SQL語句賦值 this.setParams(pstmt, params); // 執行語句 result = pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { this.close(con, pstmt, null); } return result; } /** * 新增操作 * * @param sql * @param params * @return */ public int update(String sql, List<Object> params) { int result = 0; Connection con = null; PreparedStatement pstmt = null; try { // 獲取連線 con = this.getConnection(); // 執行預編譯語句 pstmt = con.prepareStatement(sql); // 給預編譯的SQL語句賦值 this.setParams(pstmt, params); // 執行語句 result = pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { this.close(con, pstmt, null); } return result; } /** * 新增操作 * @param sqls * @param params * @return */ public boolean updates(List<String> sqls,List<List<Object>> params){ boolean bl=false; Connection con=null; PreparedStatement pstmt=null; try { if (sqls!=null && sqls.size()>0) { con=this.getConnection(); //關閉事務的自動提交 con.setAutoCommit(false); for(int i=0,len=sqls.size();i<len;i++){ pstmt=con.prepareStatement(sqls.get(i)); this.setParams(pstmt, params.get(i)); pstmt.executeUpdate(); } //如果所有語句執行完成都沒有錯誤,則提交事務 con.commit(); return true; } } catch (SQLException e) { try { con.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { try { con.setAutoCommit(true); } catch (SQLException e) { e.printStackTrace(); } this.close(con, pstmt, null); } return bl; } /** * 查詢 * * @param sql * @param params * @return */ public List<Map<String, Object>> find(String sql, Object... params) { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { // 獲取連線 con = this.getConnection(); // 執行預編譯語句 pstmt = con.prepareStatement(sql); // 給預編譯語句中的佔位符賦值 this.setParams(pstmt, params); // 獲取結果集 rs = pstmt.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int colCount = rsmd.getColumnCount(); String[] colNames = this.getColumnNames(rsmd, colCount); Map<String, Object> map = null; Object obj = null; String colType = null; while (rs.next()) { //// 每迴圈一次就是一行記錄,我們需要將這行記錄中的值存到一個map中,以列名為鍵,以當前列的值為值 map = new HashMap<String, Object>(); for (String col : colNames) { obj = rs.getObject(col); // 判斷當前這個列的值的型別 if (obj != null) { colType = obj.getClass().getSimpleName(); if ("BLOB".equals(colType)) { Blob blob = rs.getBlob(col); // 將Blob變成一個位元組陣列 byte[] bt = blob.getBytes(1, (int) blob.length()); map.put(col, bt); } else { map.put(col, obj); } } else { map.put(col, obj); } } // 當for迴圈結束,說明這一行資料已經讀完並存到了map中,接下來我們需要將這行資料存到list中 list.add(map); map = null; } } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { this.close(con, pstmt, rs); } return list; } /** * 查詢 * * @param sql * @param params * @return */ public List<Map<String, String>> findStr(String sql, Object... params) { List<Map<String, String>> list = new ArrayList<Map<String, String>>(); Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { // 獲取連線 con = this.getConnection(); // 執行預編譯語句 pstmt = con.prepareStatement(sql); // 給預編譯語句中的佔位符賦值 this.setParams(pstmt, params); // 獲取結果集 rs = pstmt.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int colCount = rsmd.getColumnCount(); String[] colNames = this.getColumnNames(rsmd, colCount); Map<String, String> map = null; while (rs.next()) { //// 每迴圈一次就是一行記錄,我們需要將這行記錄中的值存到一個map中,以列名為鍵,以當前列的值為值 map = new HashMap<String, String>(); for (String col : colNames) { map.put(col, rs.getString(col)); } // 當for迴圈結束,說明這一行資料已經讀完並存到了map中,接下來我們需要將這行資料存到list中 list.add(map); map = null; } } catch (SQLException e) { e.printStackTrace(); } finally { this.close(con, pstmt, rs); } return list; } /** * 查詢 * * @param sql * @param params * @return */ public List<Map<String, Object>> find(String sql, List<Object> params) { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { // 獲取連線 con = this.getConnection(); // 執行預編譯語句 pstmt = con.prepareStatement(sql); // 給預編譯語句中的佔位符賦值 this.setParams(pstmt, params); // 獲取結果集 rs = pstmt.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); int colCount = rsmd.getColumnCount(); String[] colNames = this.getColumnNames(rsmd, colCount); Map<String, Object> map = null; Object obj = null; String colType = null; while (rs.next()) { //// 每迴圈一次就是一行記錄,我們需要將這行記錄中的值存到一個map中,以列名為鍵,以當前列的值為值 map = new HashMap<String, Object>(); for (String col : colNames) { obj = rs.getObject(col); // 判斷當前這個列的值的型別 if (obj != null) { colType = obj.getClass().getSimpleName(); if ("BLOB".equals(colType)) { Blob blob = rs.getBlob(col); // 將Blob變成一個位元組陣列 byte[] bt = blob.getBytes(1, (int) blob.length()); map.put(col, bt); } else { map.put(col, obj); } } else { map.put(col, obj); } } // 當for迴圈結束,說明這一行資料已經讀完並存到了map中,接下來我們需要將這行資料存到list中 list.add(map); map = null; } } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { this.close(con, pstmt, rs); } return list; } /** * 查詢單行資料 * * @param sql * @param params * @return */ public Map<String, Object> findSingle(String sql, Object... params) { Map<String, Object> map = null; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { // 獲取連線 con = this.getConnection(); // 執行預編譯語句 pstmt = con.prepareStatement(sql); // 給預編譯語句中的佔位符賦值 this.setParams(pstmt, params); // 獲取結果集 rs = pstmt.executeQuery(); if (rs.next()) { ResultSetMetaData rsmd = rs.getMetaData(); int colCount = rsmd.getColumnCount(); String[] colNames = this.getColumnNames(rsmd, colCount); map = new HashMap<String, Object>(); Object obj = null; String colType = null; for (String col : colNames) { obj = rs.getObject(col); // 判斷當前這個列的值的型別 if (obj != null) { colType = obj.getClass().getSimpleName(); if ("BLOB".equals(colType)) { Blob blob = rs.getBlob(col); // 將Blob變成一個位元組陣列 byte[] bt = blob.getBytes(1, (int) blob.length()); map.put(col, bt); } else { map.put(col, obj); } } else { map.put(col, obj); } } } } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { this.close(con, pstmt, rs); } return map; } /** * 查詢單行資料,用字串儲存 * * @param sql * @param params * @return */ public Map<String, String> findSingleByStr(String sql, Object... params) { Map<String, String> map = null; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { // 獲取連線 con = this.getConnection(); // 執行預編譯語句 pstmt = con.prepareStatement(sql); // 給預編譯語句中的佔位符賦值 this.setParams(pstmt, params); // 獲取結果集 rs = pstmt.executeQuery(); if (rs.next()) { ResultSetMetaData rsmd = rs.getMetaData(); int colCount = rsmd.getColumnCount(); String[] colNames = this.getColumnNames(rsmd, colCount); map = new HashMap<String, String>(); String obj = null; String colType = null; for (String col : colNames) { obj = rs.getString(col); // 判斷當前這個列的值的型別 if (obj != null) { colType = obj.getClass().getSimpleName(); if ("BLOB".equals(colType)) { Blob blob = rs.getBlob(col); // 將Blob變成一個位元組陣列 byte[] bt = blob.getBytes(1, (int) blob.length()); map.put(col, String.valueOf(bt)); } else { map.put(col, obj); } } else { map.put(col, obj); } } } } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { this.close(con, pstmt, rs); } return map; } /** * 查詢 * @param sql * @param c * @param params * @return */ public <T> List<T> find(String sql, Class<T> c, Object ...params){ List<T> list=new ArrayList<T>(); Connection con=null; PreparedStatement pstmt=null; ResultSet rs=null; try { con=this.getConnection(); pstmt=con.prepareStatement(sql); this.setParams(pstmt,params); rs=pstmt.executeQuery(); //獲取結果集中的列名 String[] colNames = this.getColumnNames(rs); //取出給定類所有settet方法 List<Method> methods=this.getSetter(c); T t=null; Object obj; String colName=null; //資料庫中的列名 String mname=null; //方法名 String typeName=null; //型別名 while(rs.next()){ t=c.newInstance(); //new UserInfo(); for(String col:colNames){ colName="set"+col; //setusid for(Method m:methods){ mname=m.getName(); //setUsid if(mname.equalsIgnoreCase(colName)){ //說明找到了對應的方法 obj=rs.getObject(col); if(obj!=null){ //如果不為空,則獲取這個物件的型別,如果為空則說明這個屬性為空,不需要管 typeName=obj.getClass().getSimpleName(); if("BigDecimal".equals(typeName)){ //number(8) number(10,2) try{ //啟用這個方法注值 m.invoke(t, rs.getInt(col)); }catch(Exception e){ m.invoke(t, rs.getDouble(col)); } }else if("Integer".equals(typeName)){ m.invoke(t, rs.getInt(col)); }else{ m.invoke(t, String.valueOf(obj)); } } break; } } } list.add(t); } } catch (SQLException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally{ this.close(con, pstmt, rs); } return list; } /** * 查詢 * @param sql * @param c * @param params * @return */ public <T> List<T> find(String sql, Class<T> c,List<Object> params){ List<T> list=new ArrayList<T>(); Connection con=null; PreparedStatement pstmt=null; ResultSet rs=null; try { con=this.getConnection(); pstmt=con.prepareStatement(sql); this.setParams(pstmt,params); rs=pstmt.executeQuery(); //獲取結果集中的列名 String[] colNames = this.getColumnNames(rs); //取出給定類所有settet方法 List<Method> methods=this.getSetter(c); T t=null; Object obj; String colName=null; //資料庫中的列名 String mname=null; //方法名 String typeName=null; //型別名 while(rs.next()){ t=c.newInstance(); //new UserInfo(); for(String col:colNames){ colName="set"+col; //setusid for(Method m:methods){ mname=m.getName(); //setUsid if(mname.equalsIgnoreCase(colName)){ //說明找到了對應的方法 obj=rs.getObject(col); if(obj!=null){ //如果不為空,則獲取這個物件的型別,如果為空則說明這個屬性為空,不需要管 typeName=obj.getClass().getSimpleName(); if("BigDecimal".equals(typeName)){ //number(8) number(10,2) try{ //啟用這個方法注值 m.invoke(t, rs.getInt(col)); }catch(Exception e){ m.invoke(t, rs.getDouble(col)); } }else if("Integer".equals(typeName)){ m.invoke(t, rs.getInt(col)); }else{ m.invoke(t, String.valueOf(obj)); } } break; } } } list.add(t); } } catch (SQLException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally{ this.close(con, pstmt, rs); } return list; } /** * 獲取指定類所有setter方法 * @param c * @return */ public List<Method> getSetter(Class<?> c){ Method[] methods=c.getMethods(); List<Method> list=new ArrayList<Method>(); for(Method method:methods){ if(method.getName().startsWith("set")){ list.add(method); } } return list; } /** * 獲取記錄數 * @param sql * @param params * @return */ public int getTotal(String sql,Object ...params){ Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; int result=0; try { // 獲取連線 con = this.getConnection(); // 執行預編譯語句 pstmt = con.prepareStatement(sql); // 給預編譯語句中的佔位符賦值 this.setParams(pstmt, params); // 獲取結果集 rs = pstmt.executeQuery(); if (rs.next()) { result=rs.getInt("total"); } } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { this.close(con, pstmt, rs); } return result; } }