ResultSet结果集映射给实体类集合
程序员文章站
2022-06-15 12:32:45
...
public static List<Object> handler(ResultSet rs, Class<?> clazz) {
List<Object> list = new ArrayList<>();
Object obj = null;
try {
while (rs.next()) {
// 创建一个clazz对象实例并将其赋给要返回的那个返回值。
obj = clazz.newInstance();
// 获取结果集的数据源
ResultSetMetaData rsmeta = rs.getMetaData();
// 获取结果集中的字段数
int count = rsmeta.getColumnCount();
// 循环取出个字段的名字以及他们的值并将其作为值赋给对应的实体对象的属性
for (int i = 0; i < count; i++) {
// 获取字段名
String name = rsmeta.getColumnName(i + 1);
// 利用反射将结果集中的字段名与实体对象中的属性名相对应,由于
// 对象的属性都是私有的所以要想访问必须加上getDeclaredField(name)和
Field f = obj.getClass().getDeclaredField(name);
f.setAccessible(true);
// 将结果集中的值赋给相应的对象实体的属性
f.set(obj, rs.getObject(name));
}
list.add(obj);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
//resultToList方法
public static <T> List<T> resultToList(ResultSet resultSet, Class<T> clazz) {
//创建一个 T 类型的数组
List<T> list = new ArrayList<>();
try {
//通过反射获取对象的实例
T t = clazz.getConstructor().newInstance();
//获取resultSet 的列的信息
ResultSetMetaData metaData = resultSet.getMetaData();
//遍历resultSet
while (resultSet.next()) {
//遍历每一列
for (int i = 0; i < metaData.getColumnCount(); i++) {
//获取列的名字
String fName = metaData.getColumnLabel(i + 1);
//因为列的名字和我们EMP中的属性名是一样的,所以通过列的名字获得其EMP中属性
Field field = clazz.getDeclaredField(fName.toLowerCase());
//因为属性是私有的,所有获得其对应的set 方法。set+属性名首字母大写+其他小写
String setName = "set" + fName.toUpperCase().substring(0, 1) + fName.substring(1).toLowerCase();
//因为属性的类型和set方法的参数类型一致,所以可以获得set方法
Method setMethod = clazz.getMethod(setName, field.getType());
//执行set方法,把resultSet中的值传入emp中, 再继续循环传值
setMethod.invoke(t, resultSet.getObject(fName));
}
//把赋值后的对象 加入到list集合中
list.add(t);
}
} catch (Exception e) {
e.printStackTrace();
}
// 返回list
return list;
}
public static List Populate(ResultSet rs,Class cc) throws SQLException, InstantiationException, IllegalAccessException{
//结果集 中列的名称和类型的信息
ResultSetMetaData rsm = rs.getMetaData();
int colNumber = rsm.getColumnCount();
List list = new ArrayList();
Field[] fields = cc.getDeclaredFields();
//遍历每条记录
while(rs.next()){
//实例化对象
Object obj = cc.newInstance();
//取出每一个字段进行赋值
for(int i=1;i<=colNumber;i++){
Object value = rs.getObject(i);
//匹配实体类中对应的属性
for(int j = 0;j<fields.length;j++){
Field f = fields[j];
if(f.getName().equals(rsm.getColumnName(i))){
boolean flag = f.isAccessible();
f.setAccessible(true);
f.set(obj, value);
f.setAccessible(flag);
break;
}
}
}
list.add(obj);
}
return list;
}
public static <T> ArrayList<T> putResult(ResultSet rs, Class<T> obj) throws FrameException {
try {
ArrayList<T> arrayList = new ArrayList<T>();
ResultSetMetaData metaData = rs.getMetaData();
//获取总列数,确定为对象赋值遍历次数
int count = metaData.getColumnCount();
while (rs.next()) {
// 创建对象实例
T newInstance = obj.newInstance();
// 开始为一个对象赋值
for (int i = 1; i <= count; i++) {
// 给对象的某个属性赋值
String name = metaData.getColumnName(i).toLowerCase();
// 改变列名格式成java命名格式
name = toJavaField(name);
// 首字母大写
String substring = name.substring(0, 1);
String replace = name.replaceFirst(substring, substring.toUpperCase());
// 获取字段类型
Class<?> type = obj.getDeclaredField(name).getType();
Method method = obj.getMethod("set" + replace, type);
//判断读取数据的类型
if (type.isAssignableFrom(String.class)) {
method.invoke(newInstance, rs.getString(i));
} else if (type.isAssignableFrom(int.class) || type.isAssignableFrom(Integer.class)) {
method.invoke(newInstance, rs.getInt(i));
} else if (type.isAssignableFrom(Boolean.class) || type.isAssignableFrom(boolean.class)) {
method.invoke(newInstance, rs.getBoolean(i));
} else if (type.isAssignableFrom(Date.class)) {
method.invoke(newInstance, rs.getDate(i));
} else if (type.isAssignableFrom(BigDecimal.class)) {
method.invoke(newInstance, rs.getBigDecimal(i));
}
}
arrayList.add(newInstance);
}
return arrayList;
} catch (Exception e) {
logger.error(e);
throw new FrameException("内部错误,请与管理员联系,对象赋值错误");
}
实体类中的属性类型一定要和数据库中的字段类型保持一致,否则会转换失败,当遇到实体类中的成员属性过多时,可以考虑用map集合封装
实体类要重写HashCode()和equals()方法,确保一致性
上一篇: C++ 程序流程结构详解
下一篇: php compact内置函数