版權(quán)聲明:本文為小斑馬偉原創(chuàng)文章,轉(zhuǎn)載請注明出處!
通用的查詢方法:可以根據(jù)傳入的 SQL、Class 對象返回 SQL 對應(yīng)的記錄的對象。
查詢(要求:列的別名要和 Class 對應(yīng)的類的屬性名相同)锨络,得到 ResultSet 對象,得到 ResultSetMetaData 對象:可以知道 SQL 語句中查詢了哪些列狼牺,以及列的別名都是什么羡儿,反射創(chuàng)建Class 對應(yīng)的類對象,為對應(yīng)的屬性賦值是钥。
實(shí)現(xiàn)查詢到的數(shù)據(jù)列表信息與DAO對象綁定
主要步驟 |
---|
1.先利用 SQL 進(jìn)行查詢掠归,得到結(jié)果集 |
2.利用反射創(chuàng)建實(shí)體類的對象:創(chuàng)建 Student 對象 |
3.獲取結(jié)果集的列的別名:idCard、studentName |
4.再獲取結(jié)果集的每一列的值悄泥, 結(jié)合 3 得到一個 Map虏冻,鍵:列的別名,值:列的值:{flowId:5, type:6, idCard: xxx ……} |
5.再利用反射為 2 的對應(yīng)的屬性賦值:屬性即為 Map 的鍵弹囚,值即為 Map 的值 |
/**
* 通用的查詢方法:可以根據(jù)傳入的 SQL厨相、Class 對象返回 SQL 對應(yīng)的記錄的對象
* @param clazz: 描述對象的類型
* @param sql: SQL 語句∨葛模可能帶占位符
* @param args: 填充占位符的可變參數(shù)蛮穿。
* @return
*/
public <T> T get(Class<T> clazz, String sql, Object... args) {
T entity = null;
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//1. 得到 ResultSet 對象
connection = JDBCTools.getConnection();
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i + 1, args[i]);
}
resultSet = preparedStatement.executeQuery();
//2. 得到 ResultSetMetaData 對象
ResultSetMetaData rsmd = resultSet.getMetaData();
//3. 創(chuàng)建一個 Map<String, Object> 對象, 鍵: SQL 查詢的列的別名,
//值: 列的值
Map<String, Object> values = new HashMap<>();
//4. 處理結(jié)果集. 利用 ResultSetMetaData 填充 3 對應(yīng)的 Map 對象
if(resultSet.next()){
for(int i = 0; i < rsmd.getColumnCount(); i++){
String columnLabel = rsmd.getColumnLabel(i + 1);
Object columnValue = resultSet.getObject(i + 1);
values.put(columnLabel, columnValue);
}
}
//5. 若 Map 不為空集, 利用反射創(chuàng)建 clazz 對應(yīng)的對象
if(values.size() > 0){
entity = clazz.newInstance();
//5. 遍歷 Map 對象, 利用反射為 Class 對象的對應(yīng)的屬性賦值.
for(Map.Entry<String, Object> entry: values.entrySet()){
String fieldName = entry.getKey();
Object value = entry.getValue();
ReflectionUtils.setFieldValue(entity, fieldName, value);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(resultSet, preparedStatement, connection);
}
return entity;
}
@Test
public void testGet() {
String sql = "SELECT id, name, email, birth "
+ "FROM customers WHERE id = ?";
Customer customer = get(Customer.class, sql, 5);
System.out.println(customer);
sql = "SELECT flow_id flowId, type, id_card idCard, "
+ "exam_card examCard, student_name studentName, "
+ "location, grade " + "FROM examstudent WHERE flow_id = ?";
Student stu = get(Student.class, sql, 5);
System.out.println(stu);
}
反射的 Utils 函數(shù)集合 提供訪問私有變量, 獲取泛型類型 Class, 提取集合中元素屬性等 Utils 函數(shù)。
/**
* 反射的 Utils 函數(shù)集合
* 提供訪問私有變量, 獲取泛型類型 Class, 提取集合中元素屬性等 Utils 函數(shù)
* @author weiwei
*
*/
public class ReflectionUtils {
/**
* 通過反射, 獲得定義 Class 時聲明的父類的泛型參數(shù)的類型
* 如: public EmployeeDao extends BaseDao<Employee, String>
* @param clazz
* @param index
* @return
*/
@SuppressWarnings("unchecked")
public static Class getSuperClassGenricType(Class clazz, int index){
Type genType = clazz.getGenericSuperclass();
if(!(genType instanceof ParameterizedType)){
return Object.class;
}
Type [] params = ((ParameterizedType)genType).getActualTypeArguments();
if(index >= params.length || index < 0){
return Object.class;
}
if(!(params[index] instanceof Class)){
return Object.class;
}
return (Class) params[index];
}
/**
* 通過反射, 獲得 Class 定義中聲明的父類的泛型參數(shù)類型
* 如: public EmployeeDao extends BaseDao<Employee, String>
* @param <T>
* @param clazz
* @return
*/
@SuppressWarnings("unchecked")
public static<T> Class<T> getSuperGenericType(Class clazz){
return getSuperClassGenricType(clazz, 0);
}
/**
* 循環(huán)向上轉(zhuǎn)型, 獲取對象的 DeclaredMethod
* @param object
* @param methodName
* @param parameterTypes
* @return
*/
public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){
for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
try {
//superClass.getMethod(methodName, parameterTypes);
return superClass.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e) {
//Method 不在當(dāng)前類定義, 繼續(xù)向上轉(zhuǎn)型
}
//..
}
return null;
}
/**
* 使 filed 變?yōu)榭稍L問
* @param field
*/
public static void makeAccessible(Field field){
if(!Modifier.isPublic(field.getModifiers())){
field.setAccessible(true);
}
}
/**
* 循環(huán)向上轉(zhuǎn)型, 獲取對象的 DeclaredField
* @param object
* @param filedName
* @return
*/
public static Field getDeclaredField(Object object, String filedName){
for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
try {
return superClass.getDeclaredField(filedName);
} catch (NoSuchFieldException e) {
//Field 不在當(dāng)前類定義, 繼續(xù)向上轉(zhuǎn)型
}
}
return null;
}
/**
* 直接調(diào)用對象方法, 而忽略修飾符(private, protected)
* @param object
* @param methodName
* @param parameterTypes
* @param parameters
* @return
* @throws InvocationTargetException
* @throws IllegalArgumentException
*/
public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
Object [] parameters) throws InvocationTargetException{
Method method = getDeclaredMethod(object, methodName, parameterTypes);
if(method == null){
throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
}
method.setAccessible(true);
try {
return method.invoke(object, parameters);
} catch(IllegalAccessException e) {
System.out.println("不可能拋出的異常");
}
return null;
}
/**
* 直接設(shè)置對象屬性值, 忽略 private/protected 修飾符, 也不經(jīng)過 setter
* @param object
* @param fieldName
* @param value
*/
public static void setFieldValue(Object object, String fieldName, Object value){
Field field = getDeclaredField(object, fieldName);
if (field == null)
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
makeAccessible(field);
try {
field.set(object, value);
} catch (IllegalAccessException e) {
System.out.println("不可能拋出的異常");
}
}
/**
* 直接讀取對象的屬性值, 忽略 private/protected 修飾符, 也不經(jīng)過 getter
* @param object
* @param fieldName
* @return
*/
public static Object getFieldValue(Object object, String fieldName){
Field field = getDeclaredField(object, fieldName);
if (field == null)
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
makeAccessible(field);
Object result = null;
try {
result = field.get(object);
} catch (IllegalAccessException e) {
System.out.println("不可能拋出的異常");
}
return result;
}
}