简体   繁体   English

根据ResultSetMetaData中的列数在Setter中设置值

[英]Set value in Setter according to number of column in ResultSetMetaData

I am looking for dynamic approach in order to set the values in setter method, in which I fetch the total number of column from ResultSetMetaData , on based of those result, I want to set the values in corresponding setter method. 我正在寻找动态方法以便在setter方法中设置值,在该方法中,我从ResultSetMetaData列的总数,基于这些结果,我想在相应的setter方法中设置值。 I already prepared the snippet in my utility class. 我已经在实用程序类中准备了该代码段。

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;
}

Now the scenario is I want to set Pay_codes Of Employees, now there are total 95 paycode, but it differs in case of employees. 现在的场景是我要设置“ Pay_codes Of Employees”,现在总共有95个支付码,但是对于雇员来说则有所不同。

For example, Regular employees has 13 paycode, where as contactual employee has 6 codes, similarly society employees has 8 paycodes. 例如,正式员工有13个支付代码,而联络员工有6个支付代码,同样社会员工有8个支付代码。

Now I need to show the list of paycodes on behalf of employee. 现在,我需要代表员工显示付款代码列表。 I passed EmployeeCode and I got the result. 我通过了EmployeeCode并得到了结果。

Now The problem 现在的问题
whether I set all the column in my RowMapper like below 是否在我的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

This seems very bad approach, because, Paycode can be increase or decrease as per client request. 这似乎是非常糟糕的方法,因为可以根据客户请求增加或减少Paycode。

So, I am looking for 2-3 line of dynamic code which set the values in setter according to the column name inside "ResultSetMetaData".So Kindly suggest me the best approach and help me to achieve the same. 因此,我正在寻找2-3行动态代码,这些代码将根据“ ResultSetMetaData”中的列名在setter中设置值。因此,请向我提出最佳方法,并帮助我实现最佳方法。

However I am thinking of generic implementation, is generic do some magic, If yes > then how? 但是我在考虑泛型实现,泛型做了一些魔术,如果是>那怎么做? please suggest me. 请建议我。

Use this code: 使用此代码:

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();
            }
        }
    }
}

So you use Java reflection API with PayCode.class.getDeclaredMethods to get class methods, and then you iterate through method names searching for method that contains name of the property. 因此,您可以将Java反射API与PayCode.class.getDeclaredMethods一起使用以获取类方法,然后遍历方法名称以搜索包含属性名称的方法。 Once you find it you set the value to the object with method.invoke(p, value) , and exit the loop. 一旦找到它,就可以使用method.invoke(p, value)将值设置为对象,然后退出循环。

You can make things faster if you store PayCode.class.getDeclaredMethods() , and then make a hash set with method name as a key, and method as a value Map<String, Method> : 如果存储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;
}

and then use it: 然后使用它:

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();
    }
}
  1. You can use reflection 您可以使用反射

     package com.test; import java.lang.reflect.Method; class PayCode { private String esic; private String epf; public String getEsic() { return esic; } public void setEsic(String esic) { this.esic = esic; } public String getEpf() { return epf; } public void setEpf(String epf) { this.epf = epf; } @Override public String toString() { return "PayCode [esic=" + esic + ", epf=" + epf + "]"; } } public class DynamicSetter { public static void main(String[] args) { PayCode payCode = new PayCode(); try { /** * Here you can take "set" hardcoded and generate suffix "Esic" * dynamically, may be using apache StringUtils or implement using * Substring, based on your class setter methods. */ Method esicMethod = PayCode.class.getMethod("set" + "Esic", String.class); esicMethod.invoke(payCode, "Test Paycode"); System.out.println("Check paycode in object : " + payCode); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } 
  2. You can use HashMap<> to add all pay code in that. 您可以使用HashMap <>在其中添加所有支付代码。 You can also implement gtter for each pay code to read from HashMap. 您还可以为要从HashMap读取的每个支付代码实现gtter。

     package com.test; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; class Employee { private Map<String, String> payCodes = new HashMap<>(); private String epf; public String getEsic() { return payCodes.get("ESIC"); } public String getEpf() { return payCodes.get("EPF"); } public Map<String, String> getPayCodes() { return payCodes; } } public class DynamicSetter { public static void main(String[] args) { } public static Integer extractData(ResultSet rs) throws SQLException, DataAccessException { while(rs.next()) { Employee e = new Employee(); Map<String, String> payCodes = e.getPayCodes(); //set app paycode in payCodes, you can use column name as key and fetch value from result set. } } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM