Как сопоставить POJO с базой данных ResultSet, если columnNames и fieldNames отличаются с помощью java Reflection? - PullRequest
0 голосов
/ 25 октября 2018

Я работаю над динамическим отображением значений из набора результатов в POJO с использованием отражения Java.Это работает, но если имя столбца отличается от поля в pojo, оно не отображается.

Например: если имя моего столбца ORD_ID, а в моем pojo это orderId, ord_id не сопоставляется с идентификатором заказа.Вот логика, которую я использую ниже. Пожалуйста, предложите решение или идею.Заранее спасибо!

    int colCount = resultSet.getMetaData().getColumnCount();
    for (int i = 0; i < colCount; i++) 
    {
    columnNames.put(resultSet.getMetaData().getColumnName(i + 1).toLowerCase(), i);
    }
    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.setAccessible(true); 
                field.set(newObj, resultSet.getObject(index+1));
            }
        }
        results.add(newObj);
    }

Ответы [ 2 ]

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

, но если имя столбца отличается от поля в pojo, оно не отображается

Очевидно, что это не сработает, поскольку ваш код написан для этой цели, когда обаимена совпадают, поэтому я не понимаю элемент неожиданности.

Единственный выход, который я могу придумать, - это вторичная глобальная карта имени поля с именем столбца БД, и вы обращаетесь к нему, как только columnNames.containsKey(fieldName) ложно.Эта карта - ручная работа, и эта ручная работа всегда будет там, поскольку только вы, как разработчик, знаете, какой столбец соответствует какому полю в POJO.Это не может быть автоматизировано, если оба они различны, а внешнее сопоставление необходимо передавать в программу Java.

Это отображение можно сохранить во внешнем файле свойств.

Существуют такие API-интерфейсы, как apache-commons-dbutils , но и ручное сопоставление не исчезнет, ​​поскольку вы должны будете указать это в своем пользовательском файле - org.apache.commons.dbutils.BeanProcessor

Что-то еще можно сделать в строках инструментов генерации сущностей JPA, где мы присоединяем что-то вроде ниже к полям POJO -

@Column(name = "ADDRESS_IND")
private String addressInd;

, но это опять-таки ручная работачто касается спецификации картографирования.Я думаю, вы можете получить значение аннотации и построить свое отображение.

Как получить имя класса аннотации, значения атрибутов, используя отражение

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

Я недавно сделал нечто похожее, оно очень грубое, но оно работает.

// finalData format will be [List<String>,List<List<String>>] i.e [column names, column data]
    List<Object> finalData = new ArrayList<Object>();
    List<String> columnNames = new ArrayList<>();
    // columnData will be list of lists, where inner list comprised of each row data and outer list comprised of such row objects.
    List<List<String>> columnData = new ArrayList<List<String>>();


    ResultSet rs = serviceDao.generateData(query);//returns result set based on query

    ResultSetMetaData rsmd = rs.getMetaData();
    int columnCount = rsmd.getColumnCount();
    for (int i = 1; i <= columnCount; i++ ) {
      String columnName = rsmd.getColumnName(i);
      columnNames.add(columnName);
    }

    finalData.add(columnNames);// first object of finalData object
    //Iterate through result set for each row, get all the columns data which are present in column names
    while(rs.next()) {
        List<String> rowData = new ArrayList<String>();
        for(int i=0;i<columnNames.size();i++) {
            rowData.add(rs.getString(columnNames.get(i)));
        }
        columnData.add(rowData);
    }
    finalData.add(columnData); // Second object of finalData object

Редактировать 1: Вы можете использовать rs.getString("column name"), чтобы получить любой тип данных в виде строк. Oracle docs говорит

Обратите внимание, что хотя метод getString рекомендуется для извлечения типов SQL CHAR и VARCHAR, с его помощью можно получить любой из базовых типов SQL.Получение всех значений с помощью getString может быть очень полезным, но оно также имеет свои ограничения.Например, если он используется для получения числового типа, getString преобразует числовое значение в объект Java String, и значение должно быть преобразовано обратно в числовой тип, прежде чем его можно будет использовать как число.В случаях, когда значение обрабатывается как строка, недостатка нет.Кроме того, если вы хотите, чтобы приложение получало значения любого стандартного типа SQL, кроме типов SQL3, используйте метод getString.

...