1、原理:反射+內省
2、反射:動態建立物件
3、內省:動態處理物件的屬性值
4、結果集處理:
(1)把結果集中的一行資料,封裝成一個物件,專門針對結果集中只有一行資料的情況。
(2)處理結果集--多行資料,封裝成多個物件(list)
✿ 專門針對結果集中只有一行資料的情況(把結果集中的一行資料,封裝成一個物件) BeanHandler
public class BeanHandler<T> implements IResultHandler2<T> {
private Class<T> classType; //因為需要把結果集的一行封裝成一個物件【❀ 則需要有物件的存在】,通過反射技術,動態編譯是才傳入具體型別的物件
public BeanHandler(Class<T> classType) { //通過構造器,傳入具體的型別的,以便後邊通過反射獲取到對應型別的具體物件
this.classType = classType;
}
@Override
public T handle(ResultSet rs) throws Exception {
//1、建立對應的類的一個物件
T obj = classType.newInstance();
//2、取出結果集中當前游標所在行的某一列的資料
BeanInfo beanInfo = Introspector.getBeanInfo(classType, Object.class);
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
if(rs.next()) {
for(PropertyDescriptor pd : pds) {
//獲取物件的屬性名【屬性名和列名相同】
String columnName = pd.getName();
Object val = rs.getObject(columnName);
//3、呼叫該物件的setter方法,把某一列的資料設定進去
pd.getWriteMethod().invoke(obj, val);
}
}
return obj;
}
}
✿ 針對結果集中多行資料的情況(把結果集中的每一行資料,封裝成一個物件) BeanHandler
public class BeanListHandler<T> implements IResultHandler2<List<T>> {
//利用反射技術,先擁有類
private Class<T> classType;
public BeanListHandler(Class<T> classType) {
this.classType = classType;
}
@Override
public List<T> handle(ResultSet rs) throws Exception {
List<T> list = new ArrayList<>();
while(rs.next()) {
T obj = classType.newInstance();
BeanInfo benInfo = Introspector.getBeanInfo(classType, Object.class);
PropertyDescriptor[] pds = benInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : pds) {
String columnName = pd.getName();
Object value = rs.getObject(columnName);
//設定物件屬性值
pd.getWriteMethod().invoke(obj, value);
}
list.add(obj);
}
return list;
}
}