您的位置:首页 > 其它

对于名为cMemberId这类属性属性名与其set、get方法对应关系的差异

2011-05-11 18:54 609 查看

现象

数据库中有一个字段为c_member_id,对应DO中类的属性为cMemberId,在数据库查询的时候可以正确的将值注入到这个属性中,但是在调用beanUtils中的setProperty方法的时候却会出现找不到set方法的情况,报错。

eclipse中对该属性自动生成的getter和setter方法

public String getcMemberId() {
return cMemberId;
}
public void setcMemberId(String cMemberId) {
this.cMemberId = cMemberId;
}

beanUtils的setProperty和getProperty方法寻找getter和setter方法的规则

见PropertyDescriptor中的方法
getReadMethod:

if (type == boolean.class || type == null) {
readMethodName = "is" + getBaseName();
} else {
readMethodName = "get" + getBaseName();
}

getBaseName中的处理:
public static String capitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
return name.substring(0, 1).toUpperCase(ENGLISH) + name.substring(1);
}
即:属性cMemberId拼装出来的get方法名称是:getCMemberId,悲剧,找不到,这样通过BeanUtils通过反射方式执行相关的方法都会出错

ibatis查询数据库的时候的处理规则

sql-map配置文件中:
在查询的时候设值的时候会调用到PropertyAccessPlan中的public void setProperties(Object object, Object[] values)方法
Object[] arg = new Object[1];
for (i = 0; i < propertyNames.length; i++) {
arg[0] = values[i];
try {
setters[i].invoke(object, arg);
} catch (Throwable t) {
throw ClassInfo.unwrapThrowable(t);
}
}

setters的来源:

private void addMethods(Class cls) {
Method[] methods = getAllMethodsForClass(cls);                      注:取得所有方法
for (int i = 0; i < methods.length; i++) {
String name = methods[i].getName();                               注:取得方法名
if (name.startsWith("set") && name.length() > 3) {                注:如果以set开头并且方法名称长度大于3
if (methods[i].getParameterTypes().length == 1) {
name = dropCase(name);                                        注:取得属性名称
if (setMethods.containsKey(name)) {
...
}
setMethods.put(name, methods[i]);                             注:把属性与其setter方法对应关系放入map
setTypes.put(name, methods[i].getParameterTypes()[0]);
}

注:根据方法名取得属性名称
private static String dropCase(String name) {
if (name.startsWith("is")) {
name = name.substring(2);
} else if (name.startsWith("get") || name.startsWith("set")) {
name = name.substring(3);
} else {
throw new ProbeException("Error parsing property name '" + name + "'.  Didn't start with 'is', 'get' or 'set'.");
}

注:如果方法名去掉前缀后长度为1或者长度大于1并且第二个字母不是大写,将第一字母变为小写
if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
name = name.substring(0, 1).toLowerCase(Locale.US) + name.substring(1);
}

return name;
}
即:对于方法是getcMemberId的方法可以正确的对应到属性cMemberId

总结

对于名为cMemberId这种属性取getter,setter方法的时候eclipse中和beanUtils中的处理不一致(不一致的应该不只这两个地方),而ibatis中兼容了这两种处理,处理方式可以是将bean中的名称不去使用cMemberId这种属性名,而换一个正常点的属性名,如complaintMemberId,这个时候注意在ibatis的sql-map配置文件中对应好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: