如果使用java Reflection,如果列名称和字段名称不同,如何将POJO与数据库ResultSet映射?



我正在使用Java反射将值从结果集动态映射到POJO。它正在工作,但如果列名与 pojo 中的字段不同,则不会对其进行映射。

例如:如果我的列名是ORD_ID,而在我的 pojo 中它是 orderId,则该ord_id不会与订单 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);
}

但如果列名与 pojo 中的字段不同,则不是 获取映射

显然,这是行不通的,因为当两个名称匹配时,您的代码就是为此目的而编写的,所以我不明白惊喜元素。

我能想到的唯一出路是字段名称到数据库列名称的辅助全局映射,一旦columnNames.containsKey(fieldName)为假,您就会引用它。该映射是一项手动工作,并且该手动工作将始终存在,因为只有您作为开发人员知道哪一列映射到 POJO 中的哪个字段。如果两者不同,并且外部映射需要提供给Java progarm,则无法自动化。

该映射可以保留在外部属性文件中。

有像apache-commons-dbutils这样的API,但手动映射不会消失,因为您必须在自定义中提供它 - org.apache.commons.dbutils.BeanProcessor

还可以在 JPA 实体生成工具的行中完成其他操作,我们将如下所示的内容附加到 POJO 字段 -

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

但就映射规范而言,这又是一项手动工作。我认为,您可以检索注释值并构建映射。

如何使用反射获取注释类名、属性值

我最近做了类似的事情,它非常粗糙,但它有效。

// 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")以字符串形式检索任何数据类型。 甲骨文文档 说

请注意,尽管建议使用 getString 方法检索 SQL 类型 CHAR 和 VARCHAR,但可以使用它检索任何基本的 SQL 类型。使用 getString 获取所有值可能非常有用,但它也有其局限性。例如,如果它用于检索数值类型,getString 会将数值转换为 Java String 对象,并且该值必须先转换回数值类型,然后才能将其作为数字进行操作。如果无论如何都将值视为字符串,则没有任何缺点。此外,如果希望应用程序检索除 SQL3 类型以外的任何标准 SQL 类型的值,请使用 getString 方法。

相关内容

最新更新