MyBatis 配置之集合的嵌套方式

目录
  • MyBatis 配置之集合的嵌套
    • 前言介绍
    • 代码示例
    • 外部引用
    • 小结一下吧
  • 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 让你后来可以改变想法,而不对你的代码造成很小(或任何)影响。

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

(0)

相关推荐

  • 解决mybatis 中collection嵌套collection引发的bug

    我就废话不多说了,大家还是直接看代码吧~ <resultMap id="ParentMap" type="org.example.mybatis.Parent"> <id column="Id" jdbcType="VARCHAR" property="id" /> <result column="Name" jdbcType="VARCHAR&q

  • MyBatis一对多嵌套查询的完整实例

    前言 嵌套查询的实现原理为两次查询,比如产品表为主表,图片表为从表通过product_id字段与产品表id字段关联实现一对多,嵌套查询 首先查询 主表的数据 然后将主表id字段赋值给从表实体类中product_id 字段(productId)然后通过dao接口路径映射找到对应的MyBatis XMl文件SQL语句ID如:com.liao.dao.DImgMapper.selectDImgByProductId 进行子查询也就是第二次查询.然后返回数据 数据库建表语句和测试数据如下: 数据库版本为

  • Mybatis中连接查询和嵌套查询实例代码

    首先在mysql中确立表: #表一:地址国家表 CREATE TABLE address(aid INT AUTO_INCREMENT PRIMARY KEY,aname VARCHAR(20)); INSERT INTO address VALUES(NULL,"魏国"); INSERT INTO address VALUES(NULL,"蜀国"); INSERT INTO address VALUES(NULL,"吴国"); #表二:出场人物

  • MyBatis的嵌套查询解析

    Mybatis表现关联关系比hibernate简单,没有分那么细致one-to-many.many-to-one.one-to-one.而是只有两种association(一).collection(多),表现很简洁.下面通过一个实例,来展示一下Mybatis对于常见的一对多和多对一关系复杂映射是怎样处理的. 以最简单的用户表订单表这个最简单的一对多做示例: 对应的JavaBean: User: public class User { private int id; private String

  • MyBatis 配置之集合的嵌套方式

    目录 MyBatis 配置之集合的嵌套 前言介绍 代码示例 外部引用 小结一下吧 MyBatis 集合.集合嵌套查询 集合 集合的嵌套查询 集合的嵌套结果 MyBatis 配置之集合的嵌套 前言介绍 在一些查询结果包装类中,包含一些 List 集合属性,使用 collection 标签可以声明该 List 集合中属性的类型,便于 MyBatis 对包装类中的集合类型属性进行映射. 代码示例 例如商城,取出某一个商品信息以及该商品的评价列表,其中商品包装类 Product 的定义代码如下: pac

  • mybatis配置对象包含对象以及List的方式

    mybatis配置对象包含对象及List 这里隐藏get set方法 public class BatchManagerViewVo implements Serializable{ /** * @Description: serialVersionUID : TODO */ private static final long serialVersionUID = 1L; private List<ResourcesItemDto> resourceItem; private List<

  • spring、mybatis 配置方式详解(常用两种方式)

    在之前的文章中总结了三种方式,但是有两种是注解sql的,这种方式比较混乱所以大家不怎么使用,下面总结一下常用的两种总结方式: 一. 动态代理实现 不用写dao的实现类 这种方式比较简单,不用实现dao层,只需要定义接口就可以了,这里只是为了记录配置文件所以程序写的很简单: 1.整体结构图: 2.三个配置文件以及一个映射文件 (1).程序入口以及前端控制器配置 web.xml <?xml version="1.0" encoding="UTF-8"?> &

  • Mybatis配置返回为修改影响条数方式

    目录 Mybatis配置返回为修改影响条数 使用xml配置update语句返回影响的记录行数 解决办法 Mybatis配置返回为修改影响条数 mybatis执行update()方法默认返回为匹配的更新记录条数,现在需要将update()方法修改为与mysql执行一致返回影响条数,修改jdbc连接如下即可:添加useAffectedRows=true配置. jdbc:mysql://jdbc.host/{jdbc.db}?useAffectedRows=true 使用xml配置update语句返回

  • mybatis数组和集合的长度判断及插入方式

    目录 mybatis数组和集合的长度判断及插入 1.在使用foreach的是collection属性 2.判断长度 mybatis数组与集合判断非空和长度 数组判断 集合判断 mybatis数组和集合的长度判断及插入 1.在使用foreach的是collection属性 该属性是必须指定的,但是在不同情况下,该属性的值是不一样的 主要有一下4种情况:  如果传入的是单参数且参数类型是一个List的时候,collection属性值为list . 如果传入的是单参数且参数类型是非list的Colle

  • Java使用MyBatis框架分页的5种方式

    本文为大家分享了Java使用MyBatis框架分页的五种方式,供大家参考,具体内容如下 初始准备 1.创建分页对象类,方便模块间传值 //PageInfo.java import lombok.Data; @Data public class PageInfo { private int pageNo; private int pageSize; } 2.定义DAO层接口 import org.apache.ibatis.session.RowBounds; import org.springf

  • Mybatis配置之<properties>属性配置元素解析

    紧接着上篇博客<Mybatis的配置文件入门介绍>,我们开始对mybatis核心配置文件中的各个元素进行详细的说明,在这篇文章中,我们首先来看下<properties>元素,这个元素从上篇文章中可以看到是最先被解析的,设置的属性值将会被其他元素所使用. 我们先将之前的配置文件在这里拷贝一份,以便对比观察,如下所示: <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" &qu

  • spring boot下mybatis配置双数据源的实例

    目录 单一数据源配置 多个数据源配置 多数据源配置文件 多数据源配置类 最近项目上遇到需要双数据源的来实现需求,并且需要基于spring boot,mybatis的方式来实现,在此做简单记录. 单一数据源配置 单一数据源配置的话并没有什么特别的,在spring boot框架下,只需要在配置文件内添加对应的配置项即可,spring boot会自动初始化需要用到的bean. 配置信息如下.这里使用的是德鲁伊的数据源配置方式 #datasource配置 spring.datasource.type=c

  • MyBatis批量插入的几种方式效率比较

    目录 前言 一.前期准备 1.1 表结构 1.2 项目配置文件 1.3 实体类 二.反复执行单条插入语句 2.1 对应 mapper 接口 2.2 测试方法 三.foreach 拼接SQL 3.1 对应mapper 接口 3.2 测试方法 3.3 执行时间 四.批处理 4.1 rewriteBatchedStatements 参数 4.2 批处理准备 4.3 执行时间 4.4 如果数据更大 五.总结 前言 批处理数据主要有三种方式: 反复执行单条插入语句 foreach 拼接 sql 批处理 一

随机推荐