自定義一個簡單的jdbc框架,包含增加,修改,刪除,查詢方法,增,刪改,比較簡單 傳入要執行的sql 和(prepareStatement)預編譯 是需要的參數,本例子中使用可變參數 傳入,通過下面代碼設置預編譯時需要的參數。 查詢方法,將查詢的的結果封裝成相應的一個個對象,再將對象放入list返回。
// 設置參數 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, obj[i - 1]); } stmt.execute();
查詢方法主要是將結果集封裝成一個個javaBean 具體操作如下:
1 用rs.getMetaData();方法獲得結果集元數據 ResultSetMetaData 結果集元數據 ---- 獲得結果集列名稱、數量、類型*/
ResultSetMetaData resultSetMetaData=rs.getMetaData();
2 獲得總列數
int count =resultSetMetaData.getColumnCount();
3 內省技術獲得類 要求要傳入相應的 類.class */
BeanInfo beanInfo = Introspector.getBeanInfo(domainClass);
4 利用內省技術獲得類中所有屬性
PropertyDescriptor[] propertyDescriptors=beanInfo.getPropertyDescriptors();
5 遍歷結果集
《1》 遍歷所有的列
《2》 將所有的屬性和每一列的字段比較 ,如果屬性名和列的字段名相同 利用反射技術將該列的的值賦給和該列名字相同的屬性。
內省:
內省(Introspector)是Java語言對JavaBean類屬性、事件的處理方法
例如類User中有屬性name,那么必定有getName,setName方法,我們可以通過他們來獲取或者設置值,這是常規操作。
Java提供了一套API來訪問某個屬性的getter/setter方法,這些API存放在java.beans中
反射:
Java反射機制是在運行中,對任意一個類,能夠獲取得到這個類的所有屬性和方法;
對於任意一個對象,都能夠調用它的任意一個方法;
這種動態獲取類信息以及動態調用類對象方法的功能叫做Java語言的反射機制
/*1 ResultSetMetaData 結果集元數據 ---- 獲得結果集列名稱、數量、類型*/ ResultSetMetaData resultSetMetaData=rs.getMetaData(); /*2 獲得總列數*/ int count =resultSetMetaData.getColumnCount(); /*3 內省技術獲得類 要求要傳入相應的 類.class */ BeanInfo beanInfo = Introspector.getBeanInfo(domainClass); /*4 獲得所有屬性*/ PropertyDescriptor[] propertyDescriptors=beanInfo.getPropertyDescriptors(); /*5 遍歷結果集*/ while(rs.next()){ /*<1> 獲取泛型實例對象*/ T t=domainClass.newInstance(); /*<2>遍歷每一個數據庫中的字段 看是否與屬性名字匹配 如果匹配就將 數據庫中的取得的字段值放入屬性中*/ for(int i=1;i<=count;i++){ //獲得列名 String columnName=resultSetMetaData.getColumnName(i); for(PropertyDescriptor pd:propertyDescriptors){ /*屬性名字和數據庫中的名字匹配的時候為屬性賦值*/ if(columnName.equals(pd.getName())){ /*username public void com.goke.User.setUsername(java.lang.String)pd.getWriteMethod() userpwd public void com.goke.User.setUserpwd(java.lang.String)pd.getWriteMethod() userdesc public void com.goke.User.setUserdesc(java.lang.String)pd.getWriteMethod() id 沒有set 方法則顯示 */ //獲得對應的set 方法 Method setMethod=pd.getWriteMethod(); setMethod.invoke(t, new Object[]{rs.getObject(columnName)}); } } } list.add(t); }
詳細代碼如下:
package com.goke; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.ParameterMetaData; 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.rl.JDBCUtil; public class JDBCIfram { public static void main(String[] args) { BeanHanderInterface<User> beanHander=new BeanHanderImpl<>(User.class); /*String sqlInsert="insert into user (username,userpwd) values(?,?)"; Object [] obje={"liming","liming"}; insert(sqlInsert, obje); String sql="delete from user where username=? and userpwd=?"; //Object [] obj={"zhang","lei"}; delete(sql, new Object[]{"zhang","lei"}); */ String sql="select * from user"; System.out.println(query(sql, beanHander, null)); } /*查詢*/ public static <T> List<T> query(String sql, BeanHanderInterface<T> beanHander,Object ...arg){ T obj = null; List<T> list=new ArrayList<>(); Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(sql); // 設置參數 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, arg[i - 1]); } rs = stmt.executeQuery(); list = beanHander.hander(rs); } catch (SQLException e) { e.printStackTrace(); } finally { //JDBCUtil.colseResource(conn, stmt, rs); } return list; } /*插入*/ public static void insert(String sql ,Object[] obj){ Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(sql); // 設置參數 ParameterMetaData parameterMetaData=stmt.getParameterMetaData(); int count =parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, obj[i - 1]); } stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.colseResource(conn, stmt, rs); } } /*修改*/ public static void update(String sql ,Object[] obj){ Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(sql); // 設置參數 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, obj[i - 1]); } stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.colseResource(conn, stmt, rs); } } /*刪除*/ public static void delete(String sql ,Object[] obj){ Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(sql); // 設置參數 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, obj[i - 1]); } stmt.execute(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.colseResource(conn, stmt, rs); } } } /*創建 封裝查詢結果為實體類的接口*/ interface BeanHanderInterface<T> { public List<T> hander(ResultSet rs);//將結果集傳過來 封裝成T實體類 } /*接口實現類*/ class BeanHanderImpl<T> implements BeanHanderInterface<T>{ private Class<T> domainClass; public BeanHanderImpl(Class<T> domainClass) { super(); this.domainClass = domainClass; } @Override public List<T> hander(ResultSet rs) { List<T> list=new ArrayList<>(); try { /*1 ResultSetMetaData 結果集元數據 ---- 獲得結果集列名稱、數量、類型*/ ResultSetMetaData resultSetMetaData=rs.getMetaData(); /*2 獲得總列數*/ int count =resultSetMetaData.getColumnCount(); /*3 內省技術獲得類 要求要傳入相應的 類.class */ BeanInfo beanInfo = Introspector.getBeanInfo(domainClass); /*4 獲得所有屬性*/ PropertyDescriptor[] propertyDescriptors=beanInfo.getPropertyDescriptors(); /*5 遍歷結果集*/ while(rs.next()){ /*<1> 獲取泛型實例對象*/ T t=domainClass.newInstance(); /*<2>遍歷每一個數據庫中的字段 看是否與屬性名字匹配 如果匹配就將 數據庫中的取得的字段值放入屬性中*/ for(int i=1;i<=count;i++){ //獲得列名 String columnName=resultSetMetaData.getColumnName(i); for(PropertyDescriptor pd:propertyDescriptors){ /*屬性名字和數據庫中的名字匹配的時候為屬性賦值*/ if(columnName.equals(pd.getName())){ /*username public void com.goke.User.setUsername(java.lang.String)pd.getWriteMethod() userpwd public void com.goke.User.setUserpwd(java.lang.String)pd.getWriteMethod() userdesc public void com.goke.User.setUserdesc(java.lang.String)pd.getWriteMethod() id 沒有set 方法則顯示 */ //獲得對應的set 方法 Method setMethod=pd.getWriteMethod(); setMethod.invoke(t, new Object[]{rs.getObject(columnName)}); } } } list.add(t); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IntrospectionException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } return list; } }
本列中簡單實現了增加,刪除,修改,和查詢方法, 在查詢中將結果封裝成類時是考慮數據庫字段和屬性名相同的情況,沒有對數據庫字段和屬性名不同的情況做處理, 如 數據庫字段為user_name 屬性字段為username