如何将ResultSet取值赋值给基于属性映射创建的泛型<T> POJO对象
实现方案
核心调整点
- 修正泛型对象实例化逻辑:你原有代码中用
ObjectMapper.convertValue传入字段类型映射生成泛型对象的逻辑存在问题,应该直接通过泛型类的无参构造方法实例化对象 - 通过反射完成字段赋值:从
ResultSet中取出对应类型的值后,直接调用字段的set方法写入已生成的pojo对象,注意要开启私有字段的访问权限避免报错
修正后的完整代码
// 你的Helper类需要先持有泛型对应的Class对象,示例类定义如下 public class ResultSetHelper<T> { private final Class<T> clazz; // 构造方法传入泛型实际类型的Class public ResultSetHelper(Class<T> clazz) { this.clazz = clazz; } // 原有其他属性:classFieldName、classFieldFiledType等自行保留 public T createObject(ResultSet oneResult) throws SQLException, InstantiationException, IllegalAccessException { // 1. 正确实例化泛型对象,依赖POJO类的无参构造 T pojo = clazz.newInstance(); // 2. 遍历所有字段完成赋值 for (Field declaredField : pojo.getClass().getDeclaredFields()) { // 开启字段访问权限,避免私有字段无法赋值 declaredField.setAccessible(true); ColumnType columnType = getColumnType(declaredField.getType()); Object value = null; switch (columnType) { case INT: value = oneResult.getInt(declaredField.getName()); // 处理数据库null值,避免数据库null转为基本类型默认值的问题 if (oneResult.wasNull() && declaredField.getType().equals(Integer.class)) { value = null; } break; case STRING: value = oneResult.getString(declaredField.getName()); break; // 其他字段类型自行补充对应取值逻辑 } // 赋值给pojo对象的对应字段 declaredField.set(pojo, value); } return pojo; } } // 调用示例 ResultSetHelper<你的POJO类> helper = new ResultSetHelper<>(你的POJO类.class); while (set.next()) { list.add(helper.createObject(set)); }
关键逻辑说明
- 泛型类的实际类型在运行时会被擦除,所以必须在初始化Helper的时候主动传入对应Class对象,才能正确实例化泛型对象
setAccessible(true)是为了绕过Java的访问权限检查,让私有字段也能被反射赋值,不会破坏原有类的封装性- 增加
wasNull()判断是为了兼容数据库null值的场景,如果字段是包装类型,数据库为null时会给对象字段赋值为null,而不是基本类型的默认值(比如int默认0)
内容的提问来源于stack exchange,提问作者Mannualky
相关产品推荐
相关产品推荐

