Как установить значения из поля (отражение) в POJO? - PullRequest
0 голосов
/ 24 октября 2018

Я работаю над динамическим отображением значений из ResultSet в POJO в Java.Я могу получить значения, но не знаю, как установить эти значения в 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);
    }

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

Познакомьтесь с FieldUtils пакетом от Apache Commons, точно с writeDeclaredField метод:

@Test
public void testWriteDeclaredNamedField() {
    FieldUtils.writeDeclaredField(object, "fieldName", "fieldValue");
    assertEquals("fieldValue", FieldUtils.readDeclaredField(object, "fieldName"));
}
0 голосов
/ 24 октября 2018

Первый аргумент Field.set должен быть объектом, если это поле экземпляра, или null для static поля.Вместо этого вы передаете 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() было помечено устарело .

0 голосов
/ 24 октября 2018

Можете ли вы попробовать ниже строки до установки значения?

 field.setAccessible(true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...