首页 > 解决方案 > 如何将字段(反射)中的值设置为 POJO?

问题描述

我正在研究将值从 ResultSet 动态映射到 java 中的 POJO。我能够获取这些值,但不知道如何将这些值设置为 pojo。有什么建议么?提前致谢 !!

List<T> results = new ArrayList<>();
    while(resultSet.next())
    {
        T newObj = clazz.newInstance();
        for (Field field : clazz.getDeclaredFields()) 
        {
            String fieldName = field.getName().toLowerCase();
            if (columnNames.containsKey(fieldName)) 
            {
                final int index = columnNames.get(fieldName);
                field.set(fieldName, resultSet.getObject(index+1));
            }
        }
        results.add(newObj);
    }

标签: javajakarta-eereflection

解决方案


第一个参数Field.set必须是对象,如果它是一个实例字段,或者nullstatic字段。相反,您正在通过fieldName,这显然是错误的。

所以改变

field.set(fieldName, resultSet.getObject(index+1));

field.set(newObj, resultSet.getObject(index+1));

当您的代码没有必要的访问权限时,它可能需要在Field对象上设置“可访问”状态。但一般来说,您应该避免对ResultSet. 所以,你可以使用

List<T> results = new ArrayList<>();
Field[] theFields = clazz.getDeclaredFields();
// if overriding access right is needed:
AccessibleObject.setAccessible(theFields, true);

while(resultSet.next())
{
    T newObj = clazz.newInstance();
    for (Field field: theFields) 
    {
        Integer index = columnNames.get(field.getName().toLowerCase());
        if(index != null)
            field.set(newObj, resultSet.getObject(index+1));
    }
    results.add(newObj);
}

反而。甚至

List<T> results = new ArrayList<>();
Field[] theFields = clazz.getDeclaredFields();
// if overriding access right is needed:
AccessibleObject.setAccessible(theFields, true);

int numberOfFields = theFields.length;
int[] columnIndex = new int[numberOfFields];
for(int ix = 0; ix < numberOfFields; ix++) {
    Integer index = columnNames.get(theFields[ix].getName().toLowerCase());
    if(index != null) columnIndex[ix] = index + 1;
}

Constructor<T> con = clazz.getConstructor();

while(resultSet.next())
{
    T newObj = con.newInstance();
    for(int ix = 0; ix < numberOfFields; ix++)
        if(columnIndex[ix] != 0)
            theFields[ix].set(newObj, resultSet.getObject(columnIndex[ix]));
    results.add(newObj);
}

这在初始化中更复杂,但进一步减少了循环内的重复工作。请注意,使用Constructor这里不仅仅是一种优化,从 Java 9 开始,Class.newInstance()它已被标记为deprecated


推荐阅读