10【Mybatis延迟加载】
文章目录
- 一、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延迟加载】相关推荐
- MyBatis延迟加载和缓存(4)
一.项目创建 1.项目目录结构 2.数据库配置和上一篇的一样,这里不再描述.下面创建mybatis配置文件SqlMapConfig.xml 1 <?xml version="1.0&q ...
- MyBatis 延迟加载,一级缓存(sqlsession级别)、二级缓存(mapper级别)设置
什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再去加载关联信息 ...
- MyBatis 延迟加载,一级缓存,二级缓存设置
什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再去加载关联信息 ...
- Mybatis延迟加载机制
Mybatis延迟加载机制--à 效率蛮高 @Test public void testFindById() { OrderType ot = new OrderType(); try { ot = ...
- java day56【 Mybatis 延迟加载策略 、 Mybatis 缓存、Mybatis 注解开发 】
第1章 Mybatis 延迟加载策略 1.1 何为延迟加载? 1.2 实现需求 1.3 使用 assocation 实现延迟加载 1.3.1 账户的持久层 DAO 接口 1.3.2 账户的持久层映射文 ...
- 小天带你轻松解决Mybatis延迟加载原理源码问题
Mybatis延迟加载原理源码解析 Mybatis基本结构图 由上图可以知道MyBatis延迟加载主要使⽤:JavassistProxyFactory,CgliProxyFactoryb实现类.这两种 ...
- Mybatis延迟加载和查询缓存
一.延迟加载 resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 延迟加载:先 ...
- MyBatis延迟加载及在spring中集成配置
当你要使用one to one,many to one 就会碰到N+1的问题.很明显,对象之间关联很多有A关联B,B关联C,C关联A这样的关系,如果不是采用延迟加载,很容易一下在出现成千上万对象 ...
- mybatis:延迟加载时不要在get/set方法上面添加final关键字(原创)
1.mybatis-config.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ...
最新文章
- 强行删除文件 windwos10_如何彻底删除 Windows 当中的顽固文件?
- 常用Java面试题 List集合
- python学习之--习题集
- 线扫相机 编码器_面阵和线扫工业相机选型
- mysql5.1.7升级到5.6_1 MySQL5.6 升级到 5.7 版本
- VSCode如何关闭右侧预览功能 - 截图示下
- python数据分析第一步:读取以及查看数据
- windows资源监控
- phpmyadmin出现缺少mysqli扩展问题
- H盘提示拒绝访问资料怎么寻回
- 华为服务器pxe装系统,pxe启动服务器
- wgs84坐标系和国内地图坐标系的转换
- Windows UWF 实现系统重启还原(2021.11.02)
- 统一社会信用代码规则
- 元素的隐藏和显示(v-show指令)
- 超级电脑可下载人类思想 究竟是福是祸?(
- Mac添加新建文件按钮或服务
- win10去掉快捷方式小箭头_电脑一分钟小技巧:桌面快捷方式小箭头去除与恢复方法...
- python 识别人名_HanLP中人名识别分析
- ubuntu 18下载福昕pdf编辑器