MyBatis 配置之集合的嵌套方式

作者:aFa攻防实验室 时间:2023-01-15 12:26:49 

MyBatis 配置之集合的嵌套

前言介绍

在一些查询结果包装类中,包含一些 List 集合属性,使用 collection 标签可以声明该 List 集合中属性的类型,便于 MyBatis 对包装类中的集合类型属性进行映射。

代码示例

例如商城,取出某一个商品信息以及该商品的评价列表,其中商品包装类 Product 的定义代码如下:


package cn.com.mybatis.pojo;
public class Product{
   //商品id
   private int pid;
   //商品名称
   private String pname;
   //商品的评价信息
   private List<Reply> replys;
   //get和set方法
}

此时,商品的评价信息就是一个 List,所以在定义结果映射配置时,使用 collection 来定义评价结果集合,示例代码如下:


<resultMap id="productResult" type="cn.com.mybatis.pojo.Product">
   <id property="pid" column="product_id"/>
   <result property="pname" column="product_name"/>
   <collection property="replys" select="queryReplyByProductId" column="product_id" ofType="Reply"/>
</resultMap>

<select id="queryProductInfo" parameterType="int" resultMap="productResult">
   select
       P.id as product_id,
       P.name as product_name
   from product P WHERE P.id = #{id}
</select>

<select id="queryReplyByProductId" parameterType="int" resultType="Reply">
   select * from reply R WHERE R.pid = #{ProductId}
</select>

以上示例中,Product 与商品评价 Reply 会进行关联,一个商品评价 Reply 的 pid 只对应一个商品 Product 的 id,而一个商品 Product 的 id 可对应多个商品评价 Reply 的 pid,是一对多的关系。

通过配置集合的嵌套结果,就可以将查询结果中的包装类的集合类型的属性嵌套到结果集中。通过上面的配置最终得到一个包含 Reply 的 List 的商品包装类 Product。

外部引用

collection 标签也可以引入外部的 resultMap 配置。如果 queryReplyByProductId 配置的 sql 查询结果中使用了别名,或数据库字段名与 Reply 类属性名不对应,此时需要返回一个名为 replyResult 的 resultMap,那么 productResult 中的 collection 可以做如下配置:


<resultMap id="productResult" type="cn.com.mybatis.pojo.Product">
   <id property="pid" column="product_id"/>
   <result property="pname" column="product_name"/>
   <collection property="replys" ofType="Reply" resultMap="replyResult" columnPrefix="reply_">
</resultMap>

<resultMap id="replyResult" type="Reply">
   <id property="id" column="id"/>
   <result property="username" column="username"/>
   <result property="info" column="info"/>
</resultMap>

columnPrefix 代表为外部引入的 resultMap 中的每一个元素的 column 属性加上一个前缀。

小结一下吧

在一些查询结果包装类中,包含一些 List 集合属性,可使用 collection 标签声明该 List 集合中属性的类型。以便于 MyBatis 对包装类中的集合类型属性进行映射。可以在 collection 标签中配置,也可以引入外部的 resultMap 做配置。

MyBatis 集合、集合嵌套查询

集合


<collection property="posts" ofType="domain.blog.Post">
 <id property="id" column="post_id"/>
 <result property="subject" column="post_subject"/>
 <result property="body" column="post_body"/>
</collection>

集合元素的作用几乎和关联是相同的。实际上,它们也很相似,文档的异同是多余的。 所以我们更多关注于它们的不同。

我们来继续上面的示例,一个博客只有一个作者。但是博客有很多文章。在博客类中, 这可以由下面这样的写法来表示:


private List<Post> posts;

要映射嵌套结果集合到 List 中,我们使用集合元素。就像关联元素一样,我们可以从 连接中使用嵌套查询,或者嵌套结果。

集合的嵌套查询

首先,让我们看看使用嵌套查询来为博客加载文章。


<resultMap id="blogResult" type="Blog">
 <collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>
</resultMap>

<select id="selectBlog" resultMap="blogResult">
 SELECT * FROM BLOG WHERE ID = #{id}
</select>

<select id="selectPostsForBlog" resultType="Post">
 SELECT * FROM POST WHERE BLOG_ID = #{id}
</select>

这里你应该注意很多东西,但大部分代码和上面的关联元素是非常相似的。首先,你应 该注意我们使用的是集合元素。然后要注意那个新的“ofType”属性。这个属性用来区分 JavaBean(或字段)属性类型和集合包含的类型来说是很重要的。所以你可以读出下面这个 映射:


<collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>

读作: “在 Post 类型的 ArrayList 中的 posts 的集合。”

javaType 属性是不需要的,因为 MyBatis 在很多情况下会为你算出来。所以你可以缩短 写法:


<collection property="posts" column="id" ofType="Post" select="selectPostsForBlog"/>

集合的嵌套结果

至此,你可以猜测集合的嵌套结果是如何来工作的,因为它和关联完全相同,除了它应 用了一个“ofType”属性

首先, 让我们看看 SQL:


<select id="selectBlog" resultMap="blogResult">
 select
 B.id as blog_id,
 B.title as blog_title,
 B.author_id as blog_author_id,
 P.id as post_id,
 P.subject as post_subject,
 P.body as post_body,
 from Blog B
 left outer join Post P on B.id = P.blog_id
 where B.id = #{id}
</select>

我们又一次联合了博客表和文章表,而且关注于保证特性,结果列标签的简单映射。现 在用文章映射集合映射博客,可以简单写为:


<resultMap id="blogResult" type="Blog">
 <id property="id" column="blog_id" />
 <result property="title" column="blog_title"/>
 <collection property="posts" ofType="Post">
   <id property="id" column="post_id"/>
   <result property="subject" column="post_subject"/>
   <result property="body" column="post_body"/>
 </collection>
</resultMap>

同样,要记得 id 元素的重要性,如果你不记得了,请阅读上面的关联部分。

同样, 如果你引用更长的形式允许你的结果映射的更多重用,你可以使用下面这个替代 的映射:


<resultMap id="blogResult" type="Blog">
 <id property="id" column="blog_id" />
 <result property="title" column="blog_title"/>
 <collection property="posts" ofType="Post" resultMap="blogPostResult" columnPrefix="post_"/>
</resultMap>

<resultMap id="blogPostResult" type="Post">
 <id property="id" column="id"/>
 <result property="subject" column="subject"/>
 <result property="body" column="body"/>
</resultMap>

注意 这个对你所映射的内容没有深度,广度或关联和集合相联合的限制。当映射它们 时你应该在大脑中保留它们的表现。

你的应用在找到最佳方法前要一直进行的单元测试和性 能测试。好在 myBatis 让你后来可以改变想法,而不对你的代码造成很小(或任何)影响。

来源:https://blog.csdn.net/fageweiketang/article/details/80905295

标签:MyBatis,集合,嵌套
0
投稿

猜你喜欢

  • 基于Unity编写一个九宫格抽奖软件

    2022-12-30 21:02:00
  • Java生产者消费者模式实例分析

    2023-12-13 02:12:59
  • SpringBoot整合mybatis-generator-maven-plugin的方法

    2022-08-14 18:34:22
  • Android 文件下载三种基本方式

    2023-02-26 08:21:48
  • C#算法之散列表

    2022-07-30 19:05:52
  • Java程序图形用户界面设计之按钮与布局

    2023-07-18 07:03:21
  • 基于java中的流程控制语句总结(必看篇)

    2023-11-08 09:56:59
  • GridView基于pulltorefresh实现下拉刷新 上拉加载更多功能(推荐)

    2022-08-29 23:51:58
  • java基于netty NIO的简单聊天室的实现

    2023-11-18 15:29:43
  • java 使用HttpURLConnection发送数据简单实例

    2023-12-12 01:44:00
  • 基于C#调用c++Dll结构体数组指针的问题详解

    2021-12-10 23:16:41
  • Android给图片添加水印

    2022-12-02 20:25:44
  • Java实现的最大匹配分词算法详解

    2021-12-30 00:50:04
  • springboot后端配置多个数据源、Mysql数据库的便捷方法

    2022-05-01 07:21:37
  • servlet实现文件上传、预览、下载、删除功能

    2023-11-16 21:52:48
  • java web开发之购物车功能实现示例代码

    2023-01-24 16:52:55
  • C#异常捕获机制图文详解

    2023-05-22 19:39:20
  • Java处理Webp图片格式转换的示例代码

    2022-03-09 06:27:29
  • Android创建和使用数据库SQLIte

    2023-04-03 17:18:01
  • C# wpf 无边框窗口添加阴影效果的实现

    2023-11-05 01:15:09
  • asp之家 软件编程 m.aspxhome.com