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. Qt--ui的简单使用(1)

    1  说明 本文主要介绍Qt ui界面的简单使用. 参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=22 2  工程创建 创建工程时,把创建界面给 ...

  2. C# .NET MVC 表单提交前校验数据等

    页面上写2个button,一个普通button,另一个是submit,submit的这个隐藏.校验函数写在普通button里,普通button click函数中去提交表单. 页面: <input ...

  3. keepalived高可用性负载均衡

    软件官网 http://www.keepalived.org/ 为什么需要keepalived 上图明显看出,LB机器应该是双节点,否则出现单点故障的问题,并且LB作为网站的入口,显然要提供高可用性的 ...

  4. unsupported operand type(s) for +: 'function' and 'str'

    unsupported operand type(s) for +: 'function' and 'str' 报错解释:这个错误表明你尝试将一个函数和一个字符串进行加法操作,在Python中,加法不 ...

  5. mybatis sqlmap sql in 查询

    <select id="selectBlogs" parameterType="map"> SELECT * FROM blog WHERE use ...

  6. oracle数据库与oracle实例

    1 oracle数据库分类 1.1 单租户数据库 ORACLE12C之前的oracle数据库都是单租户数据库.单租户数据库是独立和完整的数据库,包括ORACLE的元数据和应用的数据. 1.2 容器数据 ...

  7. Nuxt3页面开发实战探索

    title: Nuxt3页面开发实战探索 date: 2024/6/19 updated: 2024/6/19 author: cmdragon excerpt: 摘要:这篇文章是关于Nuxt3页面开 ...

  8. Operational Property Graphs到底是个啥?

    Operational Property Graphs,中文通常译为"操作属性图". 作为23ai中被官方highlight出的新特性之一,我们先看下官方的原文描述: Operat ...

  9. 2024年软件架构趋势之AI与机器学习的关系

    在当下这个信息爆炸的时代,我们经常会听到"AI"和"机器学习"这两个词.它们似乎总是携手出现,让人觉得它们就是一对不可分割的"好基友".但你 ...

  10. Ubuntu禁止和启动内核更新

    ubuntu禁止和启动内核更新 https://www.cnblogs.com/passedbylove/p/13091002.html https://www.cnblogs.com/sparkde ...