@Data
public class CreditCard extends BankCard {
/**
* 消费额度
*/
private String creditLine;
}
@Data
public class DebitCard extends BankCard {
/**
* 存款金额
*/
private String deposit;
}

resultmap是mybatis中最复杂的元素之一,它描述如何从结果集中加载对象,主要作用是定义映射规则、级联的更新、定制类型转化器。

resultmap构成元素

1.id和result元素

以User类为例:

class User{
private int userId;
private String name;
public User(long userId,String name){
this.userId = userId;
this.name = name;
}
}

id、result是最简单的映射,id为主键映射;result其他基本数据库表字段到实体类属性的映射。resultmap的xml如下:

<resultMap type="User" id="userMap">
<id property="UserId" column="user_id" javaType="int" jdbcType="int"/>
<result property="name" column="name" javaType="String" jdbcType="VARCHAR"/>
</resultMap>

id、result语句属性配置细节:

2. CONSTRUCTOR 构造器

在resultMap中,通常使用id、result子元素把Java实体类的属性映射到数据库表的字段上。但是如果在遇到JavaBean没有无参构造函数时,我还需要使用构造器元素实现一个JavaBean的实例化和数据注入。
再以User为例,那么对应的resultmap就需要添加构造器:

<constructor>
<idArg column="user_id" javaType="long"/>
<arg column="name" javaType="String"/>
</constructor>

定义java实体类的属性映射到数据库表的字段上。我们也可以使用实体类的构造方法来实现值的映射,这是通过构造方法参数的书写的顺序来进行赋值的。 
这样MyBatis就知道需要用这个构造方法构造了。

3.结果集处理方法

1. 使用map储存结果集

一般情况下,所有select语句都可以使用map储存,但是使用map就意味着可读性的下井,所以这不是推荐的方式。

<select id="findUserById" parameterType="long" resultType="map">
select user_id ,name form user where user_id=#{userId}
</select>
2. 使用POJO储存结果集(推荐)

一般我们都使用POJO储存查询结果。我们可以使用select自动映射,还可以使用select语句中的resultMap属性配置映射集合,不过需要提前定义resultMap。 
那我们就可以将之前的select语句修改:

<select id="findUserById" parameterType="long" resultMap="userMap">
select user_id ,name form user where user_id=#{userId}
</select>

4.级联

在数据库中包含着一对多、一对一的关系。比如说一个人和他的身份证就是一对一的关系,但是他和他的银行卡就是一对多的关系。我们的生活中存在着很多这样的场景。我们也希望在获取这个人的信息的同时也可以把他的身份证信息一同查出,这样的情况我们就要使用级联。在级联中存在3种对应关系。

- 一对一的关系

- 一对多的关系

- 多对多的关系(这种情况由于比较复杂,我们通常会使用双向一对多的关系来降低复杂度)

1.association 一对一级联

我们继续使用User类,同时为其增加一个Card类,人和他的身份证就行成了一对一的关系。我们再创建一个Card类。

@Data
@Alias("card")
public class Card {
private Long id;
private Long userId;
private String name;
private String address;
}

这是需要在User中添加属性Card,这样就形成了一对一的级联。

@Data
@Alias("user")
public class User {
  private Long id;
  private String username;
  private String password;
  private String email;
  private Card card;
}

这时需要CardMapper提供findCardByUserId(Long userId)方法,定义其映射器如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.changzhen.mybatis.mapper.CardMapper">
<resultMap id="cardMap" type="card">
<id property="id" column="id"></id>
<result property="userId" column="user_id"/>
<result property="name" column="name"/>
<result property="address" column="address"/>
</resultMap> <select id="findCardByUserId" parameterType="long" resultMap="cardMap">
SELECT id, user_id, name, address FROM card WHERE user_id = #{userId}
</select>
</mapper>

有了CardMapper,我们将可以在UserMaper中使用 findCardByUserId 进行级联

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.changzhen.mybatis.mapper.UserMapper">
<select id="getUser" resultMap="userMap" parameterType="long">
SELECT id,username,password,email FROM USER WHERE id=#{id}
</select>
<resultMap id="userMap" type="user">
<id property="id" column="id"/>
<result property="password" column="password"/>
<result property="email" column="email"/>
<association property="card" column="id" select="com.changzhen.mybatis.mapper.CardMapper.findCardByUserId"/>
</resultMap>

通过关联处理,其中select元素指定的sql查询,而column则是指定传递给select的参数,是user对象id。当取出User的时候,MyBatis就知道下面的sql取出我们需要的级联信息。

 <association property="card" column="id" select="com.changzhen.mybatis.mapper.CardMapper.findCardByUserId"/>

其中参数是User的值,通过column配置,如果是多个参数则使用逗号隔开。

可以看出执行了两条sql分别查询了User和Card。

2.collection 一对多级联

这一对多的级联,一个身份证可以办理多张银行卡。每个用户对应一个身份证,每个身份证对应多个银行卡。所以这两个级联,分别使用association和collection完成。 
- 首先,创建BankCard类,为Card增加bankCardList属性

@Alias("bankCard")
@Data
public class BankCard {
private Long id;
private Long userId;
private String bankName;
private int type;
} @Data
@Alias("card")
public class Card {
private Long id;
private Long userId;
private String name;
private String address;
private List<BankCard> bankCards;
}

创建BankCardMapper

@Mapper
public interface BankCardMapper {
public List findCreditCardsByUserId(Long userId);
}

xml最简单的映射器

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.changzhen.mybatis.mapper.CreditCardMapper">
<select id="findCreditCardsByUserId" parameterType="long" resultType="creditCard">
SELECT id, user_id, bank_name, type FROM bank_card WHERE user_id = #{userId}
</select>
</mapper>
  • 最后在Card映射器中添加collection,一对多级联。
  • <mapper namespace="com.changzhen.mybatis.mapper.CardMapper">
    <resultMap id="cardMap" type="card">
    <id property="id" column="id"></id>
    <result property="userId" column="user_id"/>
    <result property="name" column="name"/>
    <result property="address" column="address"/>
    <collection property="creditCards" column="id" select="com.changzhen.mybatis.mapper.BankCardMapper.findBankCardsByUserId"/>
    </resultMap> <select id="findCardByUserId" parameterType="long" resultMap="cardMap">
    SELECT id, user_id, name, address FROM card WHERE user_id = #{userId}
    </select>
    </mapper>

    3.discriminator 鉴别器级联

鉴别器级联是在不公情况下使用不同的POJO。例如,在本例中我们每个人都有好多银行卡,但是银行卡的种类却不同,比如有借记卡(DebitCard)和信用卡(CreditCard),我们需要按需来创建不同的POJO。这时我们就需要在BankCard中添加types属性进行判断,确定使用哪个POJO。
接下来需要创建DebitCard和CreditCard两个继承BankCard的子类

案例

<!--column不做限制,可以为任意表的字段,而property须为type 定义的pojo属性-->
<resultMap id="唯一的标识" type="映射的pojo对象">
<id column="表的主键字段,或者可以为查询语句中的别名字段" jdbcType="字段类型" property="映射pojo对象的主键属性" />
<result column="表的一个字段(可以为任意表的一个字段)" jdbcType="字段类型" property="映射到pojo对象的一个属性(须为type定义的pojo对象中的一个属性)"/>
  <association property="pojo的一个对象属性" javaType="pojo关联的pojo对象">
<id column="关联pojo对象对应表的主键字段" jdbcType="字段类型" property="关联pojo对象的主席属性"/>
<result column="任意表的字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
</association>

<!-- 集合中的property须为oftype定义的pojo对象的属性-->
<collection property="pojo的集合属性" ofType="集合中的pojo对象">
<id column="集合中pojo对象对应的表的主键字段" jdbcType="字段类型" property="集合中pojo对象的主键属性" />
<result column="可以为任意表的字段" jdbcType="字段类型" property="集合中的pojo对象的属性" />
</collection>
</resultMap>

参考:https://blog.csdn.net/wuskzuo/article/details/79186144

<select id="findUserById" parameterType="long" resultType="map"> select user_id ,name form user where user_id=#{userId} </select>

9. resultMap 结果映射集的更多相关文章

  1. Mybatis resultMap空值映射问题解决

    Mybatis在使用resultMap来映射查询结果中的列,如果查询结果中包含空值的列(不是null),则Mybatis在映射的时候,不会映射这个字段,例如 查询 name,sex,age,数据库中的 ...

  2. Mybatis resultMap空值映射问题

    参考博客:https://www.oschina.net/question/1032714_224673 http://stackoverflow.com/questions/22852383/how ...

  3. resultMap自定义映射---8.3.1. 解决列名(表中的字段名称)和实体类中的属性名不一致

    1.1.1.1.      步骤一:将驼峰匹配注释掉 --------------测试完成后仍然 回来开启  其他地方可能用到 一旦注释掉驼峰匹配,那么再通过queryUserById查询的结果中,用 ...

  4. resultMap自定义映射(多对一)

    自定义resultMap,处理复杂的表关系,实现高级结果集映射 1) id :用于完成主键值的映射 2) result :用于完成普通列的映射 3) association :一个复杂的类型关联;许多 ...

  5. Mybatis中多表关联时,怎么利用association优雅写resultMap来映射vo

    前言 有好一阵没碰mybatis了,这次的项目基于性能考虑,选了mybatis,写着写着,发现有下面的需求,比如两表联查,取其中各一部分字段,怎么更方便地用vo来接,这里犯了难: 我想的是,因为这个s ...

  6. resultMap自定义映射(一对多)

    collection:处理一对多和多对多的关系 1) POJO中的属性可能会是一个集合对象,我们可以使用联合查询,并以级联属性的方式封装对象.使用collection标签定义对象的封装规则 publi ...

  7. 深入理解MyBatis的原理(四):映射器的用法

    前言:继续深入学习 mybatis 的用法及原理,还是先会用再学习原理. 映射器的主要元素有:select.insert.update.delete.parameterMap(即将被删除,不建议使用) ...

  8. 《深入浅出MyBatis技术原理与实战》——4. 映射器,5. 动态SQL

    4.1 映射器的主要元素 4.2 select元素 4.2.2 简易数据类型的例子 例如,我们需要统计一个姓氏的用户数量.应该把姓氏作为参数传递,而将结果设置为整型返回给调用者,如: 4.2.3 自动 ...

  9. 二、Mapper映射文件

    Mapper映射文件 mapper.xml映射文件主要是用来编写SQL语句的,以及一些结果集的映射关系的编写,还有就是缓存的一些配置等等. 在映射文件里面可以配置以下标签: 元素名称 描述 备注 se ...

随机推荐

  1. JVM系列(四):java方法的查找过程实现

    经过前面几章的简单介绍,我们已经大致了解了jvm的启动框架和执行流程了.不过,这些都是些无关痛痒的问题,几行文字描述一下即可. 所以,今天我们从另一个角度来讲解jvm的一些东西,以便可以更多一点认知. ...

  2. Kubernetes和docker----1.开始使用k8s和docker

    开始使用Kubernetes和docker docker命令 运行一个容器 docker run busybox echo "Hello world" 构建容器镜像 docker ...

  3. 用cmd编译java程序

    此时D:****/WorkSpace/javaCode文件夹中有一个Hello.java程序(****为任意的位置,不重要) 1 public class Hello { 2 public stati ...

  4. MYSQL 悲观锁和乐观锁简单介绍及实现

    1:悲观锁 1.1 特点: 每次查询都会进行锁行,怕"其他人"进行数据的修改. 1.2 实现步骤: 步骤1:开启事务test1,并对id=2的记录进行查询,并加锁,如:   步骤2 ...

  5. MHA架构搭建中遇到的问题

    1. 两个包:mha4mysql-manager-0.56-0.el6.noarch.rpm 和 mha4mysql-node-0.56-0.el6.norch.rpm 地址:https://code ...

  6. 订单和产品的多对多表关系在crudapi系统零代码实现

    表关系管理 在上一篇序列号管理中,产品和销售订单都是孤立的单表,本文通过crudapi中表关系(relation)管理将多个表连接起来,形成一个整体. 概要 关系类型 表与表之间的关系(relatio ...

  7. slickgrid ( nsunleo-slickgrid ) 5 增加子件

    slickgrid ( nsunleo-slickgrid ) 5 增加子件 上次把单元格切换的问题解决了,这次要最做的事情就是给slickgrid的treegird增加子件,我们先选中某一条记录,然 ...

  8. Everything about WSL 1 you want to know

    关于 WSL 1 入门,你应该知道这些 如有错误,欢迎指出 参考: WSL 文档 VMware Workstation Pro 文档 概述 通过 WSL 2 来认识 WSL 1 什么是 WSL 2? ...

  9. Python中异步协程的使用方法介绍

    1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后 ...

  10. protobuf基于java和javascript的使用

    目录 ProtoBuf介绍 整理下java和JavaScript的例子 demo测试 java作为服务端+客户端测试 客户端前端调用示例 项目地址 参考 ProtoBuf介绍 ProtoBuf 是go ...