对于名为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配置文件中对应好。相关文章推荐
- 属性get和set对应的方法
- 对于Name属性没有get/set方法引起的:target is null for setProperty(null, "x", [Ljava.lang.String;@1a48515)异常
- VS中自动生成属性get和set方法
- Android如何生成公共属性的get,set方法时,去除 成员变量的m前缀
- 使用PHP魔术方法实现属性的set、get方法
- JS属性的get和set方法
- Java反射实体类属性(get ,set方法)
- Python3基础 描述符类与自制property方法 __get__,__set__,__delete__方法 讲一个特殊的类的实例指派给另一个类的属性
- ios-给分类中的属性写get方法和set方法
- java get/set方法 属性大小写问题
- 标签for属性与对应的id之关系
- java 私有属性加get/set方法跟直接把属性设置成public有区别吗?
- 【Unity&人物属性】人物属性大量设置用set,get方法还是public成员
- python-用@property将一个方法(例如getXxx/setXxx)变成属性
- SSH整合时实体类的属性生成get,set方法里的小坑
- PHP中的__get()和__set()方法获取设置私有属性
- OC学习之属性关键字以及set和get方法
- 类和类之间属性复制,必须存在get和set方法的属性才可以复制
- java 中对类中的属性使用set/get方法的意义和用法
- iOS 属性 set方法和get方法