用反射写出与apache的增删改查框架差不多的框架,优化了上次写的代码
package top.yibobo.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
public class ResultSetHandler {
private ResultSetHandler(){}
/**
* 一个工具
* 将一个对象和ResultSet结果集传入进来
* 可以实现将当前结果集所查询的一行映射到传入的对象中
*
* @param t
* @param rs
* @return 将映射完毕的对象返回
*/
public static <T> T getQueryObject(T t,ResultSet rs){
Class<ResultSet> rsclass = ResultSet.class;
Field[] fields = t.getClass().getDeclaredFields();
for(Field f:fields){
//获取set方法名
String fieldName = "set"+f.getName().substring(0,1).toUpperCase()
+f.getName().substring(1);
//获取ResultSet要使用的get方法名
String rsFieldName = "get"+f.getType().getSimpleName().substring(0,1).toUpperCase()
+f.getType().getSimpleName().substring(1);
System.out.println(rsFieldName);
try {
//给对象赋值的set方法
Method m = t.getClass().getMethod(fieldName, f.getType());
//rs要用的get方法
Method m2 = rsclass.getMethod(rsFieldName, String.class);
Object obj = m2.invoke(rs, f.getName());
m.invoke(t, obj);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return t;
}
}
这回增删改都有啦,除了上次写的那个返回一个集合的以外,还加了个查询单条数据只返回一个对象的重载方法
增删改倒是挺简单的
package top.yibobo.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class QueryUtil {
private static QueryUtil INSTANCE = null;
private QueryUtil(){}
public static QueryUtil getInstance(){
if(INSTANCE == null){
synchronized (QueryUtil.class) {
if(INSTANCE == null){
INSTANCE = new QueryUtil();
}
}
}
return INSTANCE;
}
/**
* 此方法使用反射将type中的成员变量与方法进行动态获取
* 并且通过反射将成员变量的类型动态提取出来从而实现ResultSet中getXXX的动态获取
* 方法运行结果为将所查询数据表中的每一行保存为对象,并在查询完毕后将包含所有对象的集合返回
* @author pyb
* @param connection
* @param sql
* @param type
* @return sql语句查询出来的对象结果集合
*/
public <T> List<T> query(Connection connection,String sql,Class<T> type){
List<T> list = new ArrayList<T>();
Field[] field = type.getDeclaredFields();//获得class中所有的成员属性
try {
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next()){//遍历结果集
//通过传入的class获取此class所代表的类的实例
Constructor c = type.getConstructor(null);
//c.newInstance等同于new出来的实例
T t = (T) ResultSetHandler.getQueryObject(c.newInstance(null), rs);
list.add(t);
}
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
/**
* 此方法实现将sql语句查询的一行数据保存为相应的对象并返回
* @param connection
* @param sql
* @param type
* @param objs
* @return 与数据表中的一行数据映射的对象
*/
public <T> T query(Connection connection,String sql,Class<T> type,Object[] objs){
Field[] fields = type.getDeclaredFields();
T t = null;
PreparedStatement pr;
try {
//创建完整的PrepareStatement,给?赋值
pr = connection.prepareStatement(sql);
for(int i = 0;i<objs.length;i++){
pr.setObject(i+1, objs[i]);
}
ResultSet rs = pr.executeQuery();
if(rs.next()){//调用ResultSetHandler方法获得一个对象
Constructor<T> c = type.getConstructor(null);
t = ResultSetHandler.getQueryObject(c.newInstance(null), rs);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return t;
}
/**
* 此方法实现增删改的功能
* @param connection
* @param sql
* @param objs
* @return
*/
public int update(Connection connection,String sql,Object[] objs){
int row = 0;
try {
PreparedStatement ps = connection.prepareStatement(sql);
for(int i = 0 ; i < objs.length ; i++){
ps.setObject(i+1, objs[i]);
}
row = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
return row;
}
}
