java - 根据 ResultSetMetaData 中的列数在 Setter 中设置值
问题描述
我正在寻找动态方法以设置 setter 方法中的值,在该方法中,我从中获取列的总数ResultSetMetaData
,基于这些结果,我想在相应的 setter 方法中设置值。我已经在我的实用程序类中准备了代码片段。
public Integer extractData(ResultSet rs) throws SQLException, DataAccessException {
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for(int i = 1 ; i <= columnCount ; i++){
SQLColumn column = new SQLColumn();
String columnName = rsmd.getColumnName(i);
}
return columnCount;
}
现在的场景是我想设置Pay_codes
员工,现在总共有 95 个工资码,但在员工的情况下有所不同。
例如,普通员工有 13 个工资代码,而联系员工有 6 个代码,同样社会员工有 8 个工资代码。
现在我需要代表员工显示工资代码列表。我通过了EmployeeCode
,我得到了结果。
现在问题
是我是否在我的 RowMapper 中设置了所有列,如下所示
Paycode pc=new PayCode();
if(rs.getString("ESIC") != null){
pc.setESICCode(rs.getString("ESIC"));
}
if(rs.getString("EPF") != null){
pc.setEPFCode(rs.getString("EPF"));
}
if(rs.getString("Allowance") != null){
pc.setAllowance(rs.getString("Allowance"));
}
and many more columns........till 300+ lines
这似乎是非常糟糕的方法,因为 Paycode 可以根据客户请求增加或减少。
所以,我正在寻找 2-3 行动态代码,它根据“ResultSetMetaData”中的列名设置 setter 中的值。所以请建议我最好的方法并帮助我实现同样的目标。
但是我正在考虑通用实现,通用是否有一些魔力,如果是>那么如何?请建议我。
解决方案
使用此代码:
private void mapFields(PayCode p, String setterName, Object value) {
Method[] methods = PayCode.class.getDeclaredMethods();
for(Method method: methods){
if(method.getName().contains(setterName)){
try {
method.invoke(p, value);
break;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
因此,您使用 Java 反射 APIPayCode.class.getDeclaredMethods
来获取类方法,然后遍历方法名称以搜索包含属性名称的方法。一旦你找到它,你用 将值设置为对象method.invoke(p, value)
,然后退出循环。
如果你存储PayCode.class.getDeclaredMethods()
,你可以让事情变得更快,然后用方法名作为键,方法作为值来创建一个哈希集Map<String, Method>
:
static Map<String, Method> mapFields(Class clazz) {
Method[] methods = clazz.getDeclaredMethods();
Map<String, Method> result = new HashMap<>();
for(Method method: methods){
String methodName = method.getName();
if(methodName.indexOf("set") == 0){
result.put(methodName.substring(3), method);
}
}
return result;
}
然后使用它:
Map<String, Method> fields = mapFields(PayCode.class);
if(fields.containsKey(name)){
try {
fields.get(name).invoke(p, value);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
推荐阅读
- swift - 在发布模式下无法连接到 RPC 服务器,但在调试模式下工作正常
- scala - 如何在使用 Spark 结构化流从 Kafka 读取数据时跳过 ssl.truststore.password 属性?
- python - Django:如何在 Django 项目中设置静态文件
- java - 在@CachePut findAll() 没有从缓存中给出结果之后
- java - 无法从 ActionForm 转换为 AddExpenseForm
- flutter - ListTile中半径大于27的Flutter CircleAvatar变成椭圆
- vue.js - 有什么方法可以将 mixin 传递给通过 Vue Router 加载的组件
- django - 如何从 Django 中的应用程序中清除所有数据?
- symfony - DoctrineEncryptBundle Symfony - 尽管仅选择了实体,但已更新加密字段
- c# - 无法在 3 层 winforms C# 应用程序中加载文件或程序集异常