自定義一個簡單的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
