MyBatis 配置之集合的嵌套方式

 更新时间:2021年09月23日 16:03:54   作者:aFa攻防实验室  
这篇文章主要介绍了MyBatis 配置之集合的嵌套方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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 让你后来可以改变想法,而不对你的代码造成很小(或任何)影响。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Feign远程调用参数里面内容丢失的解决方案

    Feign远程调用参数里面内容丢失的解决方案

    这篇文章主要介绍了Feign远程调用参数里面内容丢失的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • JAVA实战项目实现客户选购系统详细流程

    JAVA实战项目实现客户选购系统详细流程

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用Java实现一个简单的客户选购系统,大家可以在过程中查缺补漏,提升水平
    2021-10-10
  • Spring常用配置及解析类说明

    Spring常用配置及解析类说明

    这篇文章主要介绍了Spring常用配置及解析类说明,涉及Spring常用配置项的方法以及它的解析类等相关内容,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Springboot项目如何兼容老的Spring项目问题

    Springboot项目如何兼容老的Spring项目问题

    这篇文章主要介绍了Springboot项目如何兼容老的Spring项目问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Java中的命名与目录接口JNDI基本操作方法概览

    Java中的命名与目录接口JNDI基本操作方法概览

    这篇文章主要介绍了Java中的命名与目录接口JNDI基本操作方法概览,JNDI提供统一的客户端API使得Java应用程序可以和这些命名服务和目录服务之间进行交互,需要的朋友可以参考下
    2016-03-03
  • 如何使用 Shell 脚本查看多个服务器的端口是否打开的方法

    如何使用 Shell 脚本查看多个服务器的端口是否打开的方法

    这篇文章主要介绍了如何使用 Shell 脚本来查看多个服务器的端口是否打开的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • Mapstruct对象插入数据库某个字段总是为空的bug详解

    Mapstruct对象插入数据库某个字段总是为空的bug详解

    这篇文章主要为大家介绍了在一次需求开发Mapstruct中对象插入数据库某个字段总是为空的bug问题详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 一文秒懂Java中的乐观锁 VS 悲观锁

    一文秒懂Java中的乐观锁 VS 悲观锁

    这篇文章主要介绍了java乐观锁 VS 悲观锁的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-05-05
  • Java基于ServletContextListener实现UDP监听

    Java基于ServletContextListener实现UDP监听

    这篇文章主要介绍了Java基于ServletContextListener实现UDP监听,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 使用Springboot注解形式进行模糊查询

    使用Springboot注解形式进行模糊查询

    这篇文章主要介绍了使用Springboot注解形式进行模糊查询的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07

最新评论