我正在寻找动态方法以便在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中设置值。因此,请为我提供最佳方法,并帮助我实现这一目标。
但是我在考虑泛型实现,泛型在做一些魔术,如果是>那么如何?请建议我。
答案 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)
您可以使用反射
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();
}
}
}
您可以使用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.
}
}
}