Mybatis使用collection分页问题举例分析

本篇内容介绍了“Mybatis使用collection分页问题举例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

原因

引起该问题的原因是当我们使用的是ResultMap集合的嵌套结果映射来处理通过join查询的结果集,映射成Java实体类型的时候,会导致主数据被映射折叠后少于从数据库获取的数据,从而导致获取的映射数据少于每页大小的数据。

方案

方案一

不使用集合的嵌套结果映射,使用集合的嵌套select查询解决。使用该方案需要注意性能问题,会导致“N+1查询问题”。

这种方式虽然很简单,但在大型数据集或大型数据表上表现不佳。这个问题被称为“N+1 查询问题”。 概括地讲,N+1 查询问题是这样子的:

你执行了一个单独的 SQL 语句来获取结果的一个列表(就是“+1”)。对列表返回的每条记录,你执行一个 select 查询语句来为每条记录加载详细信息(就是“N”)。

这个问题会导致成百上千的 SQL 语句被执行。有时候,我们不希望产生这样的后果。

好消息是,MyBatis 能够对这样的查询进行延迟加载,因此可以将大量语句同时运行的开销分散开来。 然而,如果你加载记录列表之后立刻就遍历列表以获取嵌套的数据,就会触发所有的延迟加载查询,性能可能会变得很糟糕。

方案二

移除collection配置,在业务逻辑中进行处理。先将参与分页的数据获取出来,再根据需要在业务代码中获取分页数据关联的数据。博主更倾向于这种方案解决mybatis中collection分页问题。

扩展

Mybatis中配置加载一对多关系的两种方式:

1.集合的嵌套 Select 查询

一共会产生两个SQL语句,一个查询主的数据,另一个查询关联的数据。如下所示:

<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>

2.集合的嵌套结果映射

只会产品一个SQL语句,主数据以及关联数据通过别名的形式进行配置映射到各自的对象的属性上。入戏所示:

<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使用collection分页问题举例分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!