以区域对象为例子,通常,我们就创建这样一个数据表 create table area ( id int identity PRIMARY KEY ,name varchar(50),parentid int )
对于这个对象,我们有一个非常oo的表达 public class Area { private int id; private String name; private Area parent; private IList children; public int Id { get{return this.id;} set{this.id=value;} }
public String Name { get{return this.name;} set{this.name=value;} } public Area Parent { set{this.parent=value;} get{return this.parent;} } public IList Children { get{return this.children;} set{this.children=value;} } }
这个例子能说明通常ormapping中最主要的一些内容,如
- 一对多(一个区域有一个或多个子区域)
- 一对一(一个区域最多有一个父区域)
- use left outer join(一种针对一对一,提升性能的常见处理方法)
- lazyloading(延迟读取)
通常,很容易完成id,name的映射,但parent,children呢,下面是一种处理方法 resultMap部分 <resultMap id="areaResult" class="Area"> <result property="Id" column="id"/> <result property="Name" column="name"/> <result lazyLoad="true" property="Parent" select="getParent" column="parentid"/> <result lazyLoad="true" property="Children" select="getChildren" column="id"/> </resultMap>
statement部分
<selectid="getParent" parameterClass="int" resultMap="areaResult"> select * from area where id=#value" </select> <select id="getChildren" parameterClass="int" resultMap="areaResult"> select * from area where parentid=#value# </select> <select id="find" resultMap="areaResult"> select * from area </select>
大家看到,由于lazyLoad设置为真 ,当调用area.Parent或是area.Children,才会发生查询,但显然,利用如下的设置 ,我们可以同时设置
parent属性
<resultMap id="parentResult" class="Area"> <result property="Id" column="id2"/> <result property="Name" column="name2"/> <result lazyLoad="true" property="Children" column="id2" select="getChildren"/> </resultMap> <resultMap id="areaResult2" class="Area"> <result property="Id" column="id"/> <result property="Name" column="Name"/> <result property="Parent" resultMapping="parentResult"/> <result lazyLoad="true" property="Children" column="id" select="getChildren"/> </resultMap> statement部分
<select id="getChildren" parameterClass="int" resultMap="areaResult"> select * from area where parentid=#value# </select> <select id="find" resultMap="areaResult"> select area1.id as id,area2.name as name ,area2.id as id2,area2.name as name2 from area area1 left ouer join area area2 on area1.parentid=area2.id </select> 注:事实上,在java版本中,可以这样写 <resultMap id="areaResult2" class="Area"> <result property="Id" column="id"/> <result property="Name" column="Name"/> <result property="Parent.Id" column="id2"/> <result property="Parent.Name" column="name2"/> <result lazyLoad="true" property="Parent.Children" column="id2" select="getChildren"/> <result lazyLoad="true" property="Children" column="id" select="getChildren"/> </resultMap> 这样,可以不用配置parentResult
插入和更新 在插入和更新中,由于允许使用#对象.属性#的inline parameter,所以可以写这样的sql insert into area (name,parentid) values (#Name#,#Parent.Id#) 和 Update area set name=#Name# ,parentid=#Parent.Id# where id=#Id#
最后,介绍一些资源 星月夜 http://starrynight.blogdriver.com/starrynight/index.html (作者翻译了java版本的ibatis 手册和教程) http://blog.csdn.net/nuke/archive/2004/08/29/ibatisGuide.aspx (可下载opendoc系列的ibatis开发指南)
ibatis 是比较适合.net社区习惯的工具,我建议使用,事实上,我已经放弃了nhibernate 的进一步学习
|