困扰了两天的问题,今天终于得解.原来理解有误啊.哎....
系统采用struts1.3+spring+ibatis2.3架构..
系统启动时一直出现:
There is no READABLE property named 'nick_name' in class 'com.xlyc.domain.account.Account'
错误.
现把配置文件中的一些信息贴出来.
Account.xml
< resultMap class ="Account" id ="get-accountInfo-result" >
< result property ="id" column ="id" />
< result property ="email" column ="email" />
< result property ="password" column ="password" />
< result property ="nickName" column ="nick_name" />
</ resultMap >
其中的property属性中的值是bean(com.xlyc.domain.account.Account)类中的属性字段
< select id ="getAccountById" parameterClass ="java.lang.Integer"
resultMap ="get-accountInfo-result" >
select id AS id,
email as email,
password as password,
nick_name AS nick_name
from account WHERE id = #value#
</ select >
SELECT 语句中的AS之后的字段要与RESULTMAP中的COLUMN字段是一致的,而不是与property中的值对应.这一点很重要.
< update id ="updateAccountInfo" parameterClass ="Account" >
UPDATE account set email=#email#,nick_name=#nickName# WHERE id=#id#
</ update >
UPDATE语句中的#nickName#中的双#号之间的值应该为Account类中的一个属性名.而不是随便的一个参数值传进去.
但如果是int,String,etc类型的话.参数值应该就value作为参数传递进去.
下面借用别人的一些经验之谈丰富一下本篇内容..
1.在配置ParameterMap的时候,如果传入的参数对像是元数据类型(int,string etc),那么在配置Parameter元素的时候,property的属性名使用value。通过这种情况主要使用在为存储指定参数的情况下。
2.如果ParameterMap中配置的parameter元素不包含在传入参数对象中(属性或IDictionary对象的一个key,value项),将会产生异常,而不管在statement中有没有用到。
3.在使用parameterMap的extends属性时,它将会继承extends值对应的parameterMap配置,并且会继承它的所有的参数映射,并且顺序是从继承的那配置为基准开始计算。这个在需要用到extends属性的时候要特别注意。
4.在为存储过程传参过程要特别注意,参数映射与存储过程的参数之间的顺序对应要正确。而且必须为提供与存储过程足够的参数(parameter配置足够多),即使存储过程的部分参数已经有默认值了。否则将抛出System.ArgumentOutOfRangeException异常。
5.正常情况下,应该尽量使用内联参数。
一.在使用ResultMap的时候,你要特别注意,如果你在ResultMap中给出的配置字段,但是你返回的数据集的时候却没有返回这个字段,那程序将出抛出异常。但是相反的,如果你返回了一些字段,却没有在ResultMap给出配置定义的话,那么那些字段将不会被处理而不会给你任何的提示,相当没有查询出这些字段。你要特别注意这个问题。
二.如果没有特别需求的情况,我建议还是把数据类的属性设计成与数据库字段字一样的比较,这样如果一般情况下我们都可以不用写这个ResultMap,事实上如果没有这样的特殊要求,那么去写这个ResultMap仍然是一件非常耗时,并且容易出错的一份差事。
三.在使用lazyLoad的时候要特别注意,不是什么类型的数据都可以lazyLoad的,只有是实现的IList的接口的类型,并且数据类的属性定义为IList类型的字段才能被lazyLoad。(关于是否只有IList类型的属性才能被lazyLoad的问题还需要探讨一下,因为就我使用的经验只有这种类型才可以,甚至是Generic版的IList都不支持)。而且你在使用它的时候,还不能把这个IList类型的属性转换成你真正的数据类型。因为在运行时,这个属性会被包装成一个动态的类型,这个动态类型仍然实现了IList接口,就是因为这个动态类型才扩展了我们可以lazyLoad的功能。这时候在程序中使用的是运行时的动态类型所以你没办法进行强类型转换。