罗里吧嗦
延迟加载:
就是在需要用到数据时才进行加载, 不需要用到数据时就不加载数据. 延迟加载也称懒加载, 按需加载.
延迟加载对应的是立即加载: 不管用不用, 只要一调用方法, 马上发起查询.
好处:
先从单表查询, 需要时再从关联表去关联查询, 大大提高数据库性能, 因为查询单表要比关联查询多张表速度要快.
坏处:
因为只有当需要用到数据时, 才会进行数据库查询, 这样在大批量数据查询时, 因为查询工作也要消耗
时间, 所以可能造成用户等待时间变长, 造成用户体验下降
实际开发过程中很多时候我们并不需要总是在加载用户信息时就一定要加载他的账户信息. 此时就是我们所说的延迟加载.
在对应的四种表关系中: 一对多, 多对一, 一对一, 多对多
一对多, 多对多: 通常情况下我们都是采用延迟加载.
多对一, 一对一: 通常情况下我们都是采用立即加载.
概要
1. 打开延迟加载
- <configuration>
- <settings>
- <!-- 延迟加载的开关 默认是 false -->
- <setting name="lazyLoadingEnabled" value="true"></setting>
- <!-- 将积极加载改为按需加载, 默认是 false, 即在这里配不配置都一样 -->
- <!--<setting name="aggressiveLazyLoading" value="false"></setting>-->
- </settings>
2. 在 mapper 映射文件的配置, 以及一些简单的注意事项
个人案例
基于: 一对多查询 https://www.cnblogs.com/ccoonngg/p/11330392.html
1. 创建 maven 项目, 导入依赖
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.cong</groupId>
- <artifactId>mybatis_lazyLoad</artifactId>
- <version>1.0-SNAPSHOT</version>
- <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.4.5</version>
- </dependency>
- <dependency>
- <groupId>MySQL</groupId>
- <artifactId>MySQL-connector-java</artifactId>
- <version>5.1.6</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>
- </dependencies>
- </project>
2. 两个类
- package com.cong.pojo;
- public class Account {
- private int aid;
- private int uid;
- private double money;
- // 从表实体应该包含一个主表实体的对象引用
- private User user;
- public User getUser() {
- return user;
- }
- public void setUser(User user) {
- this.user = user;
- }
- public int getAid() {
- return aid;
- }
- public void setAid(int aid) {
- this.aid = aid;
- }
- public int getUid() {
- return uid;
- }
- public void setUid(int uid) {
- this.uid = uid;
- }
- public double getMoney() {
- return money;
- }
- public void setMoney(double money) {
- this.money = money;
- }
- @Override
- public String toString() {
- return "Account{" +
- "aid=" + aid +
- ", uid=" + uid +
- ", money=" + money +
- '}';
- }
- }
- package com.cong.pojo;
- import java.util.List;
- public class User {
- private int uid;
- private String name;
- private char sex;
- private String addr;
- // 一对多关系映射: 主表实体应该包含从表实体的集合引用
- private List<Account> accounts;
- public List<Account> getAccounts() {
- return accounts;
- }
- public void setAccounts(List<Account> accounts) {
- this.accounts = accounts;
- }
- @Override
- public String toString() {
- return "User{" +
- "uid=" + uid +
- ", name='" + name + '\'' +
- ", sex=" + sex +
- ", addr='" + addr + '\''+
- '}';
- }
- public int getUid() {
- return uid;
- }
- public void setUid(int uid) {
- this.uid = uid;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public char getSex() {
- return sex;
- }
- public void setSex(char sex) {
- this.sex = sex;
- }
- public String getAddr() {
- return addr;
- }
- public void setAddr(String addr) {
- this.addr = addr;
- }
- }
3.mybatis 配置文件
<?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE configuration
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
- <settings>
- <!-- 延迟加载的开关 默认是 false -->
- <setting name="lazyLoadingEnabled" value="true"></setting>
- <!-- 将积极加载改为按需加载, 默认是 false, 即在这里配不配置都一样 -->
- <!--<setting name="aggressiveLazyLoading" value="false"></setting>-->
- </settings>
- <typeAliases>
- <package name="com.cong.pojo"></package>
- </typeAliases>
- <environments default="mysql">
- <environment id="mysql">
- <transactionManager type="JDBC"></transactionManager>
- <dataSource type="POOLED">
- <property name="driver" value="com.mysql.jdbc.Driver"></property>
- <property name="url" value="jdbc:mysql://localhost:3306/rainbow?characterEncoding=UTF-8"></property>
- <property name="username" value="root"></property>
- <property name="password" value="123456"></property>
- </dataSource>
- </environment>
- </environments>
- <mappers>
- <!--<mapper class="com.cong.mapper.UserMapper"></mapper>-->
- <package name="com.cong.mapper"></package>
- </mappers>
- </configuration>
4. 两个映射文件
下面是 AccountMapper.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.cong.mapper.AccountMapper">
- <!-- 定义封装 account 和 user 的 resultMap -->
- <resultMap id="accountUserMap" type="account">
- <id property="aid" column="aid"></id>
- <result column="uid" property="uid"></result>
- <result column="money" property="money"></result>
- <!--
- 一对一的延迟加载
- select: 填写我们要调用的 select 映射的 id, 使用全限定类名
- column : 填写我们要传递给 select 映射的参数
- -->
- <association property="user" column="uid" javaType="user"
- select="com.cong.mapper.UserMapper.findById">
- </association>
- </resultMap>
- <!-- 查询所有 account, 并且关联到它所属于的 user-->
- <select id="findAll" resultMap="accountUserMap">
- select * from account
- </select>
- <select id="findByUid" resultType="account">
- select * from account where uid = #{uid};
- </select>
- </mapper>
下面是 usermapper.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.cong.mapper.UserMapper">
- <!-- 定义 User 的 resultMap-->
- <resultMap id="userAccountMap" type="user">
- <id property="uid" column="uid"></id>
- <result property="name" column="name"></result>
- <result property="addr" column="addr"></result>
- <result property="sex" column="sex"></result>
- <!--
- 一对多的延迟加载
- ofType 用于指定集合元素的数据类型
- select 用于指定查询 account 的 sql 语句, 所以填写的是该 sql 语句映射的 id
- column 用于指定 select 属性的 sql 语句的参数来源,
- -->
- <collection property="accounts" ofType="account" notNullColumn="aid"
- column="uid" select="com.cong.mapper.AccountMapper.findByUid"
- >
- </collection>
- </resultMap>
- <!-- 查询所有 user, 以及它拥有的 account -->
- <select id="findAll" resultMap="userAccountMap">
- select * from user
- </select>
- <select id="findById" resultType="user" parameterType="int">
- select * from user where uid = #{uid};
- </select>
- </mapper>
5. 测试类
- import com.cong.mapper.AccountMapper;
- import com.cong.mapper.UserMapper;
- import com.cong.pojo.Account;
- import com.cong.pojo.User;
- import org.apache.ibatis.io.Resources;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.apache.ibatis.session.SqlSessionFactoryBuilder;
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
- import java.io.InputStream;
- import java.util.List;
- public class TestTables {
- private InputStream inputStream;
- private SqlSession sqlSession;
- private AccountMapper accountMapperr;
- private UserMapper userMapper;
- @Test
- public void findAllAccount(){
- List<Account> accounts = accountMapperr.findAll();
- for (Account account : accounts) {
- System.out.println("------------- 一个 account 的信息 --------------------");
- System.out.println(account.toString());
- System.out.println(account.getUser());
- }
- }
- @Test
- public void findAllUser(){
- List<User> users = userMapper.findAll();
- for (User user : users) {
- System.out.println("------------------ 一个 user 的信息 -----------------------");
- System.out.println(user.toString());
- if(!user.getAccounts().isEmpty()){
- for (Account account : user.getAccounts()) {
- System.out.println("\t" + account);
- }
- }
- }
- }
- @Before
- public void init() throws Exception{
- inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
- SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
- sqlSession = factory.openSession();
- accountMapperr = sqlSession.getMapper(AccountMapper.class);
- userMapper = sqlSession.getMapper(UserMapper.class);
- }
- @After
- public void destroy() throws Exception{
- sqlSession.commit();
- sqlSession.close();
- inputStream.close();
- }
- }
来源: http://www.bubuko.com/infodetail-3157286.html