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

时间:2018-10-04 10:26:02

标签: java

我正在寻找动态方法以便在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中设置值。因此,请为我提供最佳方法,并帮助我实现这一目标。

但是我在考虑泛型实现,泛型在做一些魔术,如果是>那么如何?请建议我。

2 个答案:

答案 0 :(得分:0)

使用此代码:

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 Reflection API与PayCode.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();
    }
}

答案 1 :(得分:0)

  1. 您可以使用反射

    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. 您可以使用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.
    
    
            }
        }
    }