示例:html
<resultMap id="blogResult" type="Blog"> <association property="author" column="author_id" javaType="Author" select="selectAuthor"/> </resultMap> <select id="selectBlog" resultMap="blogResult"> SELECT * FROM BLOG WHERE ID = #{id} </select> <select id="selectAuthor" resultType="Author"> SELECT * FROM AUTHOR WHERE ID = #{id} </select>
咱们有两个查询语句:一个来加载博客,另一个来加载做者,并且博客的结果映射描 述了“selectAuthor”语句应该被用来加载它的 author 属性。java
其余全部的属性将会被自动加载,假设它们的列和属性名相匹配。sql
这种方式很简单, 可是对于大型数据集合和列表将不会表现很好。 问题就是咱们熟知的 “N+1 查询问题”。归纳地讲,N+1 查询问题能够是这样引发的:mybatis
这个问题会致使成百上千的 SQL 语句被执行。这一般不是指望的。性能
MyBatis 能延迟加载这样的查询就是一个好处,所以你能够分散这些语句同时运行的消 耗。然而,若是你加载一个列表,以后迅速迭代来访问嵌套的数据,你会调用全部的延迟加 载,这样的行为多是很糟糕的。spa
因此还有另一种方法。xml
在上面你已经看到了一个很是复杂的嵌套关联的示例。 下面这个是一个很是简单的示例 来讲明它如何工做。代替了执行一个分离的语句,咱们联合博客表和做者表在一块儿,就像:htm
<select id="selectBlog" resultMap="blogResult"> select B.id as blog_id, B.title as blog_title, B.author_id as blog_author_id, A.id as author_id, A.username as author_username, A.password as author_password, A.email as author_email, A.bio as author_bio from Blog B left outer join Author A on B.author_id = A.id where B.id = #{id} </select>
注意这个联合查询, 以及采起保护来确保全部结果被惟一并且清晰的名字来重命名。 这使得映射很是简单。如今咱们能够映射这个结果:blog
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" /> <result property="title" column="blog_title"/> <association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult"/> </resultMap> <resultMap id="authorResult" type="Author"> <id property="id" column="author_id"/> <result property="username" column="author_username"/> <result property="password" column="author_password"/> <result property="email" column="author_email"/> <result property="bio" column="author_bio"/> </resultMap>
在上面的示例中你能够看到博客的做者关联表明着“authorResult”结果映射来加载做 者实例。ci
很是重要: id元素在嵌套结果映射中扮演着非 常重要的角色。你应该老是指定一个或多个能够惟一标识结果的属性。实际上若是你不指定它的话, MyBatis仍然能够工做,可是会有严重的性能问题。在能够惟一标识结果的状况下, 尽量少的选择属性。主键是一个显而易见的选择(即便是复合主键)。
如今,上面的示例用了外部的结果映射元素来映射关联。这使得 Author 结果映射能够 重用。然而,若是你不须要重用它的话,或者你仅仅引用你全部的结果映射合到一个单独描 述的结果映射中。你能够嵌套结果映射。这里给出使用这种方式的相同示例:
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" /> <result property="title" column="blog_title"/> <association property="author" javaType="Author"> <id property="id" column="author_id"/> <result property="username" column="author_username"/> <result property="password" column="author_password"/> <result property="email" column="author_email"/> <result property="bio" column="author_bio"/> </association> </resultMap>
若是blog有一个co-author怎么办? select语句将看起来这个样子:
<select id="selectBlog" resultMap="blogResult"> select B.id as blog_id, B.title as blog_title, A.id as author_id, A.username as author_username, A.password as author_password, A.email as author_email, A.bio as author_bio, CA.id as co_author_id, CA.username as co_author_username, CA.password as co_author_password, CA.email as co_author_email, CA.bio as co_author_bio from Blog B left outer join Author A on B.author_id = A.id left outer join Author CA on B.co_author_id = CA.id where B.id = #{id} </select>
再次调用Author的resultMap将定义以下:
<resultMap id="authorResult" type="Author"> <id property="id" column="author_id"/> <result property="username" column="author_username"/> <result property="password" column="author_password"/> <result property="email" column="author_email"/> <result property="bio" column="author_bio"/> </resultMap>
由于结果中的列名与resultMap中的列名不一样。 你须要指定columnPrefix去重用映射co-author结果的resultMap。
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" /> <result property="title" column="blog_title"/> <association property="author" resultMap="authorResult" /> <association property="coAuthor" resultMap="authorResult" columnPrefix="co_" /> </resultMap>
上面你已经看到了如何处理“有一个”类型关联。可是“有不少个”是怎样的?下面这 个部分就是来讨论这个主题的。
官方连接:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html