阿不

不抛弃,不放弃

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  158 随笔 :: 0 文章 :: 2080 评论 :: 66 Trackbacks

我们将来讨论一下在iBatis中非常重要的一个内容,在我个人看来,能否真正用好iBatis的一个关键,这就是ResultMap。字面上理解,它就是结果集的映射,就是将返回的记录逐个字段的映射赋值给对象的属性上。其实如果没有特殊需求的话我们完全可以使用ResultClass来代替它,因为如果字段与属性一模一样的话,查询出来数据集会自动匹配到ResultClass指定的类的实例对象,如果字段名不在属性中的话,那这个字段将不会被返回的实例体类对象接受,相当于没有查询出这个字段一样的。

每个ResultMap都有一个自己的ID,如果你在sqlmap.config中没有配置使用命名空间的话,那么这个ResulteMap ID是全局(这点在所有的iBatis配置元素都是一样的),ResultMap一个重要的属性的是class,它将决定这个ResultMap对应的实例的类,换句话讲,它的作用是指出结果集要映射的数据类型。在extends属性中可以设置它将要继承的ResultMap,如果给他指定的了值,那么它将会从super Resultmap继承所的映射配置字段。定义如下:

<resultMaps>

         <resultMap id="DemoResultMap" class="Hashtable">

             

         </resultMap>

</resultMaps>

如果你有正确配置了iBatisXSD架构文件的话,那么这时候就会提示resultMap的定义是不完全的。没错,接下来就是要定义Result元素。每一个result元素都是定义一个字段与数据类属性对应的映射。在每一个result元素有比较多的属性参数,其中propertycolumn是必须的,其它的参数属性都是可选的。所以我们在每一个resultMap中必须定义超过一个以上的result定义。通常以下的配置就可以完成基本的配置了。

<resultMaps>

         <resultMap id="DemoResultMap" class="Hashtable">

              <result property="id" column="id"/>

         </resultMap>

</resultMaps>

     但如果你需要更多的要求的话,result map仍然能够最大限度的满足你。columnIndex属性提供了我们将数据集的第几个下标字段映射到指定的数据对象属性的方案,但是这种方式应该尽量的少用,你会发现这对我们以后的维护和可读性会产生很大的副作用。dbType属性明确指出这个字段对应的数据库的类型,大多数情况我很少会用到。type属性则明确指出这个字段将对应的数据对象属性的数据类型,通常如果你想保证类型安全的话,设置这个属性是很必要的。resultMapping属性则稍微复杂一些,它是用在一种场景下,如果一个数据类的属性本身不是基元数据类型,而是一个复杂数据类型的话,那我们就不可能很简单地给它一个简单的result元素就了事了,还必须给他一个完整的resultMap。而resultMapping属性就是为了完成这个功能而存在的。它的属性值是一个已存在的resultMapIDnullValue属性就没什么好讲的了,它是给出当这个字段的值为null的时候,它的默认值是多少。select属性同resultMapping一样比较复杂一样,先说一下它的属性值必须是一个返回数据集合的查询语句的ID,能配置这个属性的数据类属性可以是一个基元类型,复合类型,也可以是一个包括多条数据的集合类型,这些类型都行,没有问题的。它的一处重要的存在意义就在于描述不同表之间的关系问题,通过本次的查询,你想不通过join的手段从另一个表查询相关字段的时候,你就可以使用select属性。如下:

<resultMaps>

         <resultMap id="DemoResultMap" class="Hashtable">

              <result property="id" column="id"/>

              <result property="Children" column="id" select="SELECT_Children"/>

         </resultMap>

     </resultMaps>

     <statements>

         <select id="SELECT_Children" resultClass="ChildrenObject">

              SELECT * FROM Children WHERE ParentID = #id#

         </select>

     </statements>

这样就可以做到不用通过编程的方式来表示不同表的关联关系和数据读取问题。但是这样有可能存在一种问题,如果你每次都要读取数据的时候,你会发现你会产生更多次的与数据库交互的情况,并且即使你不是每次都需要这数据,那会不会造成数据读取的浪费呢?接下来的lazyLoad属性就为我们提供了第二种问题的解决方案了,那就是数据的延迟加载,没错,延迟加载可以大大改善数据访问的性能,它只是要需的时候才去读取这些数据,对于主从表关系的时候,这样的方式可能是最好的解决方式了。

    OK,关于ResultMap的介绍就先到此为止,接下来我要记录一下,我在使用过程中遇到的一些问题:

    一.在使用ResultMap的时候,你要特别注意,如果你在ResultMap中给出的配置字段,但是你返回的数据集的时候却没有返回这个字段,那程序将出抛出异常。但是相反的,如果你返回了一些字段,却没有在ResultMap给出配置定义的话,那么那些字段将不会被处理而不会给你任何的提示,相当没有查询出这些字段。你要特别注意这个问题。

       二.如果没有特别需求的情况,我建议还是把数据类的属性设计成与数据库字段字一样的比较,这样如果一般情况下我们都可以不用写这个ResultMap,事实上如果没有这样的特殊要求,那么去写这个ResultMap仍然是一件非常耗时,并且容易出错的一份差事。

       三.在使用lazyLoad的时候要特别注意,不是什么类型的数据都可以lazyLoad的,只有是实现的IList的接口的类型,并且数据类的属性定义为IList类型的字段才能被lazyLoad。(关于是否只有IList类型的属性才能被lazyLoad的问题还需要探讨一下,因为就我使用的经验只有这种类型才可以,甚至是Generic版的IList都不支持)。而且你在使用它的时候,还不能把这个IList类型的属性转换成你真正的数据类型。因为在运行时,这个属性会被包装成一个动态的类型,这个动态类型仍然实现了IList接口,就是因为这个动态类型才扩展了我们可以lazyLoad的功能。这时候在程序中使用的是运行时的动态类型所以你没办法进行强类型转换。

       问题暂时没有想到更多了,如果以后还有关于resultMap的问题,我都会更新上来,也希望大家一起来指正我的一些错误和不足,一起完善。不要让我的一些错误的实践误导了初学者,谢谢。

阿不 http://hjf1223.cnblogs.com
posted on 2006-05-28 01:52 阿不 阅读(3873) 评论(12)  编辑 收藏 所属分类: .Net相关技术Ibatisnet

评论

#1楼 [楼主] 2006-05-28 02:00 阿不      
四.关于extends的问题,我们可以把他很简单的理解为继承,它就跟类的继承的相像的。如果你有遇到一种情况,两个resultMap是一个包含另一个的关系的时候,那你们就可以将公共的部分抽离出来,单独做一个resultMap,然后需要比较全字段的那个属性再从这个resultMap继承下来。这样就可以实现复用了。
  回复  引用  查看    

#2楼 [楼主] 2006-05-28 02:15 阿不      
补充一点,有关于iBatisnet使用的一些问题可以到http://groups.google.com/group/Ibatisnet
去讨论,由shanyou创建的一个用户组,在这里可以得到别人最大程度的帮助。
  回复  引用  查看    

#3楼  2006-05-28 08:28 Dflying Chen      
呵呵,你写的东西我都没接触过。挺有意思的
  回复  引用  查看    

#4楼 [楼主] 2006-05-28 10:28 阿不      
你可能不注重这方面的研究吧。你有专攻主要注重于Atlas,而我还要学习Castle,Enterprise Library,Atlas等,这些都是我必须掌握的东西,我们的团队需要这样的技术支持。
  回复  引用  查看    

#5楼  2006-05-28 10:56 neuhawk1 [未注册用户]
Castle,Enterprise Library,Atlas,我已经用上了.wwf在学.
  回复  引用    

#6楼  2006-08-07 23:43 opoll [未注册用户]
想问一下,用这样的框架做大中型的网站,或者说访问量较大的应用,性能怎么样?相比较自己完全用.net类库本身来实现的方式而言,这种方式的性能大概要损失多少?
我个人觉得这种框架在企业应用种比较普遍。
  回复  引用    

#7楼 [楼主] 2006-08-09 16:36 阿不      
@opoll
相对于其它更强大的ORM处理方案,ibatis的性能是非常不错的,除了程序初始化要稍微比较长一点的时间外,效率还是比较高的。
  回复  引用  查看    

#8楼  2006-08-19 19:03 opoll [未注册用户]
博主,能和你交流一下吗?我的邮件huguojunsy#gmail.com
希望得知你的email或者msn
  回复  引用    

#9楼  2006-09-02 16:17 hpy223 [未注册用户]
请问,如何获取执行存储过程后,返回的参数
也就是:
parameter property="RsCounts" column="Counts" direction="Output"
中这个RsCounts如何取得?
  回复  引用    

#10楼 [楼主] 2006-09-02 21:53 阿不      
你可以通过传入参数对象的RsCounts属性就可以取得输出值了,谢谢。
  回复  引用  查看    

#11楼  2006-09-11 21:35 徒弟 [未注册用户]
师傅,俺来也。很喜欢你们的文章,支持。
  回复  引用    

#12楼  2007-09-04 12:06 老袁 [未注册用户]
Hi Pls Help!

Person类有很多的属性(100多个),我建立一个通用的Property类,每个属性都是Property类的实例, 然后建立一个属性集合(Hashtable)把这些属性放进去。iBatis如何实现?

c#示意代码
Property 身高 = new Property("150","int");
Property 血型 = new Property("c","string");
HashTable properties = new HashTable();
properties.Add("身高",身高);
properties.Add("血型",血型);

Person person = new Person(1,"小王");
person.Properties = properties;

数据库表(Person)
ID Name Height Weight BloodType ....
1 小王 150 60 c

急啊,兄弟,指望你这个专家帮我解决一下!




public class Person
{
public int ID {}
public string Name{}
public HashTable Properties;

//other methods
}

public class Property
{
public string DataValue{}
public string DataType{}

//other properties and methods
}

<resultMap id = "ResultWeightProperty" class = "Property">
<result property = "DataValue" column = "Weight"/>
<!--no column-->
<result property = "DataType" value = "int"/>
<resultMap>

<resultMap id = "PersonProperties" class = "HashTable">
<result property ="weight" resultMapping = "ResultWeightProperty"/>
<result property ="height" resultMapping = "ResultHeightProperty"/>
</resultMap>

<resultMap id = "ResultPerson" class = "Person">
<result property = "ID" column = "id"/>
<result property = "Name" column = "name"/>
<result property = "Properties" resultMapping= "PersonProperties"/>
</resultMap>

<select id = "GetPersonProperties" parameterClass = "int" resultMap = "ResultPerson">
select id,name,weight,height,haircolor,.... from person where person_id = #value#
</select>
  回复  引用    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  博客园首页

  新闻频道

  社区

  小组

  博问

  网摘

  闪存

  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-10-18 11:36 编辑过
成果网帮您增加网站收入


相关链接: