文章目录

  • 一、Mybatis 延迟加载
    • 1.1 延迟加载介绍
      • 1.1.1 搭建项目工程
        • 1)SQL脚本:
        • 2)引入依赖:
        • 3)MyBatis核心配置文件:
        • 4)实体类:
        • 5)dao接口:
        • 6)mapper.xml:
    • 1.2 一对一实现延时加载
      • 1.2.1 需求
      • 1.2.2 dao接口
      • 1.2.3 接口映射
      • 1.2.4 测试
    • 1.3 一对多实现延时加载
      • 1.3.1 需求
      • 1.3.2 dao接口
      • 1.3.3 接口映射
      • 1.3.4 测试

一、Mybatis 延迟加载

1.1 延迟加载介绍

通过前面的学习,我们已经掌握了 Mybatis 中一对一,一对多,多对多关系的配置及实现,可以实现对象的关联查询。

我们昨天在配置emp和dept关联查询时,不管部门信息是否有使用到,都会把部门信息查询出来;我们希望查询员工信息时,暂时不查询部门信息,等到使用到部门信息的时候,再发送SQL语句查询部门相关信息,这样可以大大提高数据库的性能;

延迟加载,顾名思义就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载;

1.1.1 搭建项目工程

1)SQL脚本:

drop table if exists dept;CREATE TABLE `dept`  (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '部门名称',`location` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '部门地址',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 ;INSERT INTO `dept` VALUES (1, '研发部', '中国台湾');
INSERT INTO `dept` VALUES (2, '市场部', '中国香港');
INSERT INTO `dept` VALUES (3, '行政部', '中国钓鱼岛');
INSERT INTO `dept` VALUES (4, '销售部', '中国江西');drop table if exists emp;
CREATE TABLE `emp`  (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '员工姓名',`age` int(11) NULL DEFAULT NULL COMMENT '员工年龄',`addr` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '籍贯',`salary` decimal(10, 2) NULL DEFAULT NULL COMMENT '薪资',`dept_id` int(11) NULL DEFAULT NULL COMMENT '部门id',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;INSERT INTO `emp` VALUES (1, '张三', 20, '广西来宾', 7600.00, 1);
INSERT INTO `emp` VALUES (2, '李四', 22, '浙江绍兴', 6800.00, 4);
INSERT INTO `emp` VALUES (3, '小明', 25, '广东云浮', 6600.00, 2);
INSERT INTO `emp` VALUES (4, '小红', 23, '河南信阳', 7000.00, 3);
INSERT INTO `emp` VALUES (5, '张明', 25, '山东临沂', 8000.00, 1);

2)引入依赖:

<dependencies><!-- mybatis依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><!--mysql依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!--日志依赖--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency></dependencies>

3)MyBatis核心配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><settings><!--日志配置--><setting name="logImpl" value="STDOUT_LOGGING"/><!--开启全局的懒加载(默认值:false)--><setting name="lazyLoadingEnabled" value="true"/></settings><typeAliases><package name="com.dfbz.entity"/></typeAliases><!--  default 默认使用那个运行环境 --><environments default="dev"><!--配置dev运行环境--><environment id="dev"><!--事务管理器:JDBC事务管理--><transactionManager type="JDBC"></transactionManager><!--POOLED指定采用mybatis内置的连接池支持--><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF8"></property><property name="username" value="root"></property><property name="password" value="admin"></property></dataSource></environment></environments><mappers><package name="com.dfbz.dao"/></mappers>
</configuration>

4)实体类:

  • Emp:
package com.dfbz.entity;import lombok.Data;/*** @author lscl* @version 1.0* @intro:*/
@Data
public class Emp {private Integer id;private String name;private Integer age;private String addr;private Double salary;// 一个员工属于一个部门private Dept dept;
}
  • Dept:
package com.dfbz.entity;import lombok.Data;import java.util.List;/*** @author lscl* @version 1.0* @intro:*/
@Data
public class Dept {private Integer id;private String name;private String location;// 一个部门下有多个员工private List<Emp> empList;
}

5)dao接口:

  • EmpDao:
package com.dfbz.dao;import com.dfbz.entity.Emp;
import org.apache.ibatis.annotations.Param;import java.util.List;
import java.util.Set;/*** @author lscl* @version 1.0* @intro:*/
public interface EmpDao {}
  • DeptDao:
package com.dfbz.dao;import com.dfbz.entity.Dept;import java.util.List;/*** @author lscl* @version 1.0* @intro:*/
public interface DeptDao {}

6)mapper.xml:

  • DeptDao.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dfbz.dao.EmpDao"></mapper>
  • DeptDao.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dfbz.dao.DeptDao"></mapper>

搭建工程如下:

1.2 一对一实现延时加载

1.2.1 需求

  • 需求:查询Emp员工信息时候,也要显示Dept部门信息,但Dept信息用到的时候再向数据库发送查询语句。

SQL语句:

-- 一对一延迟加载
-- 需求:查询员工,同时也要显示部门。但部门信息是再用到的时候再查询.
-- 实现过程:
-- 1) 查询员工
SELECT * FROM emp;-- 3) 使用Dept对象数据时候,查询部门
SELECT * FROM dept WHERE id=1;

1.2.2 dao接口

  • EmpDao:
public interface EmpDao {List<Emp> findAll();
}
  • DeptDao:
public interface DeptDao {Dept findById(Integer id);
}

1.2.3 接口映射

  • DeptDao.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.dfbz.dao.DeptDao"><select id="findById" resultType="dept">select * from dept where id=#{id}</select>
</mapper>
  • EmpDao.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.dfbz.dao.EmpDao"><resultMap id="empResultMap" type="emp"><id column="id" property="id"></id><result column="name" property="name"></result><result column="addr" property="addr"></result><result column="salary" property="salary"></result><!--column: 查询出来的哪一列需要当做参数传递给select中的方法select: 查询部门的方法全名--><association property="dept" javaType="com.dfbz.entity.Dept"column="dept_id" select="com.dfbz.dao.DeptDao.findById"><id column="id" property="id"></id><result column="deptName" property="name"></result><result column="location" property="location"></result></association></resultMap><select id="findAll" resultMap="empResultMap">select * from emp</select>
</mapper>

Tips:将SQL语句拆分为两条后,查询的列和实体类属性名一致时可以不用手动映射;

  • 在MyBatis的核心配置文件中开启懒加载:
<setting name="lazyLoadingEnabled" value="true"/>

1.2.4 测试

// 一对一延迟加载
@Test
public void test1() {List<Emp> empList = empDao.findAll();for (Emp emp : empList) {System.out.println(emp.getId()+"---"+emp.getName());}
}

执行测试单元,观察日志:

我们发现,我们没有使用到部门相关的信息,但是部门依旧被查询到了,好像没有实现延迟加载的功能;这是为什么?

在MyBatis中,默认的延迟加载功能被关闭了,我们需要在全局配置文件中,开启延迟加载功能;

  • 修改SqlMapConfig.xml配置文件:
<!--开启全局的懒加载(默认值:false)-->
<setting name="lazyLoadingEnabled" value="true"/>

再次执行测试,观察日志,发现部门信息如果没有使用的话,则不会去查询部门;

我们也可以针对单个SQL语句的懒加载设置;

<resultMap id="empAllMap" type="com.dfbz.entity.Emp"><id column="id" property="id"></id><result column="name" property="name"></result><result column="age" property="age"></result><result column="addr" property="addr"></result><result column="salary" property="salary"></result><!--fetchType: 是否开启懒加载lazy: 开启eager: 立即加载--><association property="dept" javaType="com.dfbz.entity.Dept"select="com.dfbz.dao.DeptDao.findById" column="dept_id"></association>
</resultMap><select id="findAll" resultMap="empAllMap">select * from emp
</select>

Tips:当全局配置文件和mapper文件设置的加载方式不一样时以SQL语句上的配置为准

1.3 一对多实现延时加载

1.3.1 需求

  • 需求:查询部门信息,使用到员工信息再去查询员工信息

SQL语句:

-- 一对多延迟加载
-- 1) 查询部门
SELECT * FROM dept;
-- 2) 使用到员工信息之后再去查询员工信息
SELECT * FROM emp WHERE dept_id=1;

1.3.2 dao接口

  • DeptDao:
List<Dept> findAll();
  • EmpDao:
List<Emp> findByDeptId(Integer deptId);

1.3.3 接口映射

  • EmpDao.xml:
<select id="findByDeptId" resultType="emp">select * from emp where dept_id=#{deptId}
</select>
  • DeptDao.xml:
<resultMap id="deptResultMap" type="dept"><id column="id" property="id"></id><result column="name" property="name"></result><result column="location" property="location"></result><!--property: dept中的需要映射的属性名称ofType: 集合中泛型的类型column: 在结果集中选择column这一列当做参数传递到select指定的方法中fetchType: 是否延迟加载  lazy: 延迟加载  eager: 立即加载select: 映射empList的方法名--><collection property="empList" ofType="com.dfbz.entity.Emp"column="id" fetchType="lazy"select="com.dfbz.dao.EmpDao.findByDeptId"><result column="name" property="name"></result><result column="addr" property="addr"></result><result column="salary" property="salary"></result></collection>
</resultMap><select id="findAll" resultMap="deptResultMap">select * from dept;
</select>

1.3.4 测试

// 一对多延迟加载
@Test
public void test2() {List<Dept> deptList = deptDao.findAll();for (Dept dept : deptList) {System.out.println(dept.getId()+"---"+dept.getName());}
}

10【Mybatis延迟加载】相关推荐

  1. MyBatis延迟加载和缓存(4)

    一.项目创建 1.项目目录结构 2.数据库配置和上一篇的一样,这里不再描述.下面创建mybatis配置文件SqlMapConfig.xml 1 <?xml version="1.0&q ...

  2. MyBatis 延迟加载,一级缓存(sqlsession级别)、二级缓存(mapper级别)设置

    什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再去加载关联信息 ...

  3. MyBatis 延迟加载,一级缓存,二级缓存设置

    什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再去加载关联信息 ...

  4. Mybatis延迟加载机制

    Mybatis延迟加载机制--à 效率蛮高 @Test public void testFindById() { OrderType ot = new OrderType(); try { ot = ...

  5. java day56【 Mybatis 延迟加载策略 、 Mybatis 缓存、Mybatis 注解开发 】

    第1章 Mybatis 延迟加载策略 1.1 何为延迟加载? 1.2 实现需求 1.3 使用 assocation 实现延迟加载 1.3.1 账户的持久层 DAO 接口 1.3.2 账户的持久层映射文 ...

  6. 小天带你轻松解决Mybatis延迟加载原理源码问题

    Mybatis延迟加载原理源码解析 Mybatis基本结构图 由上图可以知道MyBatis延迟加载主要使⽤:JavassistProxyFactory,CgliProxyFactoryb实现类.这两种 ...

  7. Mybatis延迟加载和查询缓存

    一.延迟加载 resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 延迟加载:先 ...

  8. MyBatis延迟加载及在spring中集成配置

     当你要使用one to one,many to one 就会碰到N+1的问题.很明显,对象之间关联很多有A关联B,B关联C,C关联A这样的关系,如果不是采用延迟加载,很容易一下在出现成千上万对象 ...

  9. mybatis:延迟加载时不要在get/set方法上面添加final关键字(原创)

    1.mybatis-config.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ...

最新文章

  1. 强行删除文件 windwos10_如何彻底删除 Windows 当中的顽固文件?
  2. 常用Java面试题 List集合
  3. python学习之--习题集
  4. 线扫相机 编码器_面阵和线扫工业相机选型
  5. mysql5.1.7升级到5.6_1 MySQL5.6 升级到 5.7 版本
  6. VSCode如何关闭右侧预览功能 - 截图示下
  7. python数据分析第一步:读取以及查看数据
  8. windows资源监控
  9. phpmyadmin出现缺少mysqli扩展问题
  10. H盘提示拒绝访问资料怎么寻回
  11. 华为服务器pxe装系统,pxe启动服务器
  12. wgs84坐标系和国内地图坐标系的转换
  13. Windows UWF 实现系统重启还原(2021.11.02)
  14. 统一社会信用代码规则
  15. 元素的隐藏和显示(v-show指令)
  16. 超级电脑可下载人类思想 究竟是福是祸?(
  17. Mac添加新建文件按钮或服务
  18. win10去掉快捷方式小箭头_电脑一分钟小技巧:桌面快捷方式小箭头去除与恢复方法...
  19. python 识别人名_HanLP中人名识别分析
  20. ubuntu 18下载福昕pdf编辑器

热门文章

  1. Unity之线性渲染器
  2. 如何查询我的连连跨境支付提现手续费费率?
  3. JavaScript进阶教程(6)—硬核动图让你轻松弄懂递归与深浅拷贝
  4. 开发工具:第六章:Java开发者相关的所有软件安装包(35.55GB的资源)
  5. 如何用计算机学唱歌,男孩学唱歌教程 男生如何练习唱歌?
  6. 分享Linux 机器 CPU 毛刺问题排查经历
  7. 暑假带娃出游该怎么玩?明星妈妈安娜分享夏日出游新启发
  8. Java常用框架笔记(1)
  9. 将一个多段线按一些点分割成一个或多个线段
  10. 左神算法:如何较为直观地打印二叉树(Java版)