ResultMap自定义结果集

可以把查询返回的结果集封装成复杂的JavaBean对象

原来的ResultType属性,只能把查询到的结果集转换为简单的JavaBean

什么是简单的JavaBean对象?

- 不具有JavaBean和集合类型属性的对象

- 也就是不能建立ORM的多表关联映射

问题的引入:

如果字段标识符和数据表不一致,

例如实体类的user的密码字段,现在更改为pwd

数据表的字段依然为user_password

我们查询这个结果看看

所有的密码字段接受失败

那么,该如何解决这个问题?

方案一,在SQL语句中给这个字段起别名

再次测试,这个数据又能获取到了

但是这样的解决方案并不优雅

Mybatis提供了一个解决方案,使用ResultMap对字段标识进行映射绑定

测试结果,可行

一对一关系案例:

创建数据表

锁表 & 钥匙【一把锁就配一把钥匙】

CREATE TABLE t_lock(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(50) ); CREATE TABLE t_key(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(50),
`lock_id` INT,
FOREIGN KEY(`lock_id`) REFERENCES t_lock(`id`)
);

添加数据

INSERT INTO t_lock(`name`)
VALUES
('阿里巴巴'),
('联想'),
('华为'); INSERT INTO t_key(`name`,`lock_id`)
VALUES
('马云',1),
('任正非',2),
('柳传志',3);

【写反了,唉就这样把】

创建ORM实体类

锁类

package cn.dai.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; /**
* @author ArkD42
* @file Mybatis
* @create 2020 - 05 - 29 - 13:30
*/ @Data
@AllArgsConstructor
@NoArgsConstructor
public class Lock { private Integer id;
private String name;
}

钥匙类

package cn.dai.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; /**
* @author ArkD42
* @file Mybatis
* @create 2020 - 05 - 29 - 13:32
*/ @Data
@NoArgsConstructor
@AllArgsConstructor
public class Key { private Integer id;
private String name; // 注意这个设置的外键是来自这个锁对象的属性
private Lock lock; }

映射器【KeyMaper.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接口名称-->
<mapper namespace="cn.dai.mapper.KeyMapper"> <select id="queryKeyById" resultType="cn.dai.pojo.Key" parameterType="java.lang.Integer">
SELECT * FROM t_key WHERE id = #{id}
</select> </mapper>

注意!在这里采用的结果集类型,先看看结果如何

测试类

    @Test
public void sqlTest6(){
logger.info("- - - - TESTING - - - -");
SqlSession sqlSession = MybatisUtil.getSqlSession(true);
KeyMapper keyMapper = sqlSession.getMapper(KeyMapper.class); Key key = keyMapper.queryKeyById(2);
System.out.println(key); sqlSession.close();
}

结果:我们对应的锁类无法获取

我们需要一个关联查询来实现

首先从SQL语句实现

【查询钥匙表关联锁表,一起获取】

        SELECT
t_key.*,t_lock.name lock_name
FROM
t_key LEFT JOIN t_lock
ON
t_key.lock_id = t_lock.id
WHERE
t_key.id = #{id}

【就算是这样,没有类型匹配,返回的结果还是和上面一样,这里不展示了】

【留意SELECT子句筛选的字段】

所以需要通过结果集映射标签实现一些类型的绑定

使用默认的result标签处理

然后使用我们的结果集映射标签实现关联处理

<?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接口名称-->
<mapper namespace="cn.dai.mapper.KeyMapper"> <!--
id 设置这个结果集映射标签的标识,
type 设置需要转换出来的实体类对象的全限定类名
-->
<resultMap id="key" type="key"> <!-- id标签负责 转换主键列 -> 实体类的属性 -->
<id column="id" property="id"/>
<!-- 非主键列 转换给 实体类属性 -->
<result column="name" property="name"/>
<!-- 一般匹配的字段不需要显示的写出来,因为是默认的了 --> <!--
property 对应的是实体类的属性
column 对应的是数据表的列
-->
<result column="lock_id" property="lock.id" />
<result column="lock_name" property="lock.name" /> </resultMap> <!-- 这里的结果集映射就对应上面设置的id -->
<select id="queryKeyById" resultMap="key" parameterType="int">
SELECT
t_key.*,t_lock.name lock_name
FROM
t_key LEFT JOIN t_lock
ON
t_key.lock_id = t_lock.id
WHERE
t_key.id = #{id}
</select> </mapper>

测试结果

千万要注意,要实现这个锁的名称的输出,就要留意上面的SELECT 筛选的字段

可以通过别名映射实现一些实体类的绑定

在这里是因为左外链接,所以可以看到,钥匙表是没有写这个表名的

或者使用Association标签实现映射

在结果集中设置关联映射标签,绑定属性标识和所对应的类型

其次声明关联表的属性映射

       <association property="lock" javaType="cn.dai.pojo.Lock">
<id column="lock_id" property="id"/>
<result column="lock_name" property="name" />
</association>

Association定义分布查询

什么意思?

可以通过一个查询得到子对象

分两种加载,立即加载和懒加载

一张表可能存在50多列,其中主要常用的是最前面的6列

后面的44列不一定马上需要,所以我们的查询应该拆分成两次查询

我们声明一个两步查询的方法

Key queryKeyByIdForTwoStep(Integer id);

对副表的二次查询在锁表中编写

package cn.dai.mapper;

import cn.dai.pojo.Lock;

/**
* @author ArkD42
* @file Mybatis
* @create 2020 - 05 - 30 - 11:59
*/
public interface LockMapper { Lock queryLockById(Integer id); }

锁表的映射器

<?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接口名称-->
<mapper namespace="cn.dai.mapper.LockMapper"> <select id="queryLockById" resultType="cn.dai.pojo.Lock" >
select * from t_lock where id = #{id}
</select> </mapper>

钥匙表的映射器

    <resultMap id="key2" type="cn.dai.pojo.Key">

        <id column="id" property="id"/>
<result column="name" property="name"/> <!--
select 调用另外一个映射器的查询方法,来获取对象的结果
column 把这钥匙表的查询SQL的字段结果返回给这个关联查询调用【就是那个查询的参数】 -->
<association
property="lock"
javaType="cn.dai.pojo.Lock"
select="cn.dai.mapper.LockMapper.queryLockById"
column="lock_id"
/> </resultMap> <select id="queryKeyByIdForTwoStep" resultMap="key2" parameterType="int">
SELECT
id,name,lock_id
FROM
t_key
WHERE
t_key.id = #{id}
</select>

测试结果

可以看到这样查询分了两次执行,并且把字段的参数传递给下一个查询的使用

开启懒加载查询

即延迟加载,减少非必要性的查询

优化数据库性能,需要在全局配置中开启

        <!-- 开启懒加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>

    @Test
public void sqlTest7(){
logger.info("- - - - TESTING - - - -");
SqlSession sqlSession = MybatisUtil.getSqlSession(true);
KeyMapper keyMapper = sqlSession.getMapper(KeyMapper.class); Key key = keyMapper.queryKeyByIdForTwoStep(2); //System.out.println(key); //开启懒加载是什么效果?如果我们不调用附表的信息,第二个查询是不会调用的
System.out.println(key.getName()); sqlSession.close();
}

结果

实际作用远不止这些,详见官方文档:

https://mybatis.org/mybatis-3/zh/sqlmap-xml.html

【Mybatis】08 ResultMap、Association、分步查询、懒加载的更多相关文章

  1. mybatis 详解(八)------ 懒加载

    本章我们讲如何通过懒加载来提高mybatis的查询效率. 本章所有代码:http://pan.baidu.com/s/1o8p2Drs 密码:trd6 1.需求:查询订单信息,有时候需要关联查出用户信 ...

  2. 四十二:数据库之SQLAlchemy之数据查询懒加载技术

    懒加载在一对多,或者多对多的时候,如果要获取多的这一部分的数据的时候,通过一个relationship定义好对应关系就可以全部获取,此时获取到的数据是list,但是有时候不想获取全部数据,如果要进行数 ...

  3. 27.Hibernate-缓存和懒加载.md

    目录 1.一级缓存 2.缓存的有效性 3.list和iterator缓存的区别 4.懒加载 4.1get 4.2load 1.一级缓存 Hibernate中一级缓存是Session缓存,有效范围在Se ...

  4. mybatis中使用懒加载实现一对多复杂查询

    1.包结构 2.pom配置 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...

  5. mybatis 嵌套查询与懒加载

    懒加载:对于页面有很多静态资源的情况下(比如网商购物页面),为了节省用户流量和提高页面性能,可以在用户浏览到当前资源的时候,再对资源进行请求和加载. fetchType="lazy" ...

  6. MyBatis关联查询和懒加载错误

    MyBatis关联查询和懒加载错误 今天在写项目时遇到了个BUG.先说一下背景,前端请求更新生产订单状态,后端从前端接收到生产订单ID进行查询,然后就有问题了. 先看控制台报错: org.apache ...

  7. MyBatis --- 映射关系【一对一、一对多、多对多】,懒加载机制

    映射(多.一)对一的关联关系 1)若只想得到关联对象的id属性,不用关联数据表 2)若希望得到关联对象的其他属性,要关联其数据表 举例: 员工与部门的映射关系为:多对一 1.创建表 员工表 确定其外键 ...

  8. mybatis使用associaton进行分步查询

    Employee类 public class Employee { private Integer id; private String lastName; private String email; ...

  9. MyBatis加强(1)~myBatis对象关系映射(多对一关系、一对多关系)、延迟/懒加载

    一.myBatis对象关系映射(多对一关系.一对多关系) 1.多对一关系: ---例子:多个员工同属于一个部门. (1)myBatis发送 额外SQL: ■ 案例:员工表通过 dept_id 关联 部 ...

  10. mybatis和hibernate中的懒加载

    概念:所谓懒加载就是延时加载,延迟加载.什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载.至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,因为内存容量有限 ,为了减 ...

随机推荐

  1. k8s——核心概念篇

    服务的分类 有状态 代表应用 nginx apache 优点 对客户端透明,无依赖关系,可以高效实现扩容,迁移 缺点 不能存储数据,需要额外的数据服务支撑 无状态 代表应用 MYSQL Redis 优 ...

  2. Nacos 版本不一致报错: Request nacos server failed

    在做微服务开发中,测试环境使用Nacos没有问题,但是生产环境服务启动一直报错: com.alibaba.nacos.api.exception.NacosException: Request nac ...

  3. uni-app mpvue wepy websocket的介绍

    uni-app 网址:https://uniapp.dcloud.io/ uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.H5.以 ...

  4. C#异步编程是怎么回事(番外)

    在上一篇通信协议碰到了多线程,阻塞.非阻塞.锁.信号量...,会碰到很多问题.因此我感觉很有必要研究多线程与异步编程. 首先以一个例子开始 我说明一下这个例子. 这是一个演示异步编程的例子. 输入jo ...

  5. UDP端口探活的那些细节

    一 背景 商业客户反馈用categraf的net_response插件配置了udp探测, 遇到报错了,如图  udp是无连接的,无法用建立连接的形式判断端口. 插件最初的设计是需要配置udp的发送字符 ...

  6. 论文阅读 《Pingmesh: A Large-Scale System for Data Center Network Latency Measurement and Analysis》

    背景 在我们内部产品中,一直有关于网络性能数据监控需求,我们之前是直接使用 ping 命令收集结果,每台服务器去 ping (N-1) 台,也就是 N^2 的复杂度,稳定性和性能都存在一些问题,最近打 ...

  7. nginx访问日志

    访客日志 处理日志模块的官网教程 https://nginx.org/en/docs/http/ngx_http_log_module.html 创建nginx访问日志 日志对于程序员很重要,可用于问 ...

  8. excel计算日期天数和表格冻结首行

    excel计算日期天数和表格冻结首行 1.在单元格E35中输入公式DATEDIF(A35.B35."MD")MD表起始日期.结束日期天数差."Y" 时间段中的整 ...

  9. apollo配置中心从数据库中查询所有的配置及项目

    apollo配置中心从数据库中查询所有的配置及项目 需求背景:如果需要从Apollo查询某个配置项做批量的更新替换,如果一个一个找不合适且容易遗漏,需要从底层数据库表中模糊查询来实现. 1.查看apo ...

  10. discuz论坛个人空间自定义css样式

    Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` discuz论坛个人空间自定义css样式 日期:2020- ...