2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存

延迟加载

使用Assocation实现一对一延迟加载

2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第1张图片
在Mybatis核心配置文件添加配置开启延迟开关和按需加载(Mybatis 3.4.1 版本后按需加载默认开启)


    <settings>
        
        <setting name="lazyLoadingEnabled" value="true"/>
        
        <setting name="aggressiveLazyLoading" value="false"/>
    settings>

以查询账户同时查询该账户所属用户信息为例
映射配置IAccountDao.xml文件中的resultMap


    <resultMap id="accountUserMap" type="account">
        <id property="id" column="id">id>
        <result property="uid" column="uid">result>
        <result property="money" column="money">result>
        
        <association property="user" column="uid" javaType="User" select="com.itheima.dao.IUserDao.findById">association>
    resultMap>

select属性是IUserDao.xml中的findById方法
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第2张图片
当执行测试方法时:
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第3张图片
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第4张图片
把输出语句注释后:
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第5张图片
在这里插入图片描述

使用collection实现一对多延迟加载

示例:查询所有用户并查询该用户下的所有账户信息
IUserDao.xml中:


    <resultMap id="userAccount" type="User">
        <id property="id" column="id">id>
        <result property="username" column="username">result>
        <result property="birthday" column="birthday">result>
        <result property="sex" column="sex">result>
        <result property="address" column="address">result>
        
        <collection property="accounts" ofType="Account" select="com.itheima.dao.IAccountDao.findAccountByUid" column="id" >collection>
    resultMap>

    
    <select id="findAll" resultMap="userAccount">
        select * from user
    select>

IAccountDao.xml中:


    <select id="findAccountByUid" parameterType="int" resultType="Account">
        select * from account where uid = #{uid}
    select>

测试:
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第6张图片
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第7张图片


2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第8张图片
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第9张图片


缓存

2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第10张图片

一级缓存

2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第11张图片
演示:
这里的User对象并没有重写 toString() 方法

/**
     * 测试一级缓存
     */
    @Test
    public void testFirstLevelCache(){
        User user1 = userDao.findById(41);
        System.out.println(user1);

        User user2 = userDao.findById(41);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }

2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第12张图片
当中间关闭并重新获取SqlSession对象:

/**
     * 测试一级缓存
     */
    @Test
    public void testFirstLevelCache() throws Exception {
        User user1 = userDao.findById(41);
        System.out.println(user1);

        // 关闭sqlSession对象
        sqlSession.close();
        // 重新执行初始化方法(重新获取sqlSession对象并生成接口IUserDao的代理对象userDao)
        init();

        User user2 = userDao.findById(41);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }

在这里插入图片描述
在这里插入图片描述
除了重新关闭SqlSession对象,还有一个方法可以清空SqlSession对象里的缓存

sqlSession.clearCache();

触发清空一级缓存
在这里插入图片描述
新增一个更新方法


    <update id="updateUser" parameterType="User">
        update user set username=#{username}, birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    update>

测试方法:

/**
     * 测试缓存的同步
     */
    @Test
    public void testCleanCache() {
        // 1.根据id查询用户
        User user1 = userDao.findById(41);
        System.out.println(user1);

        // 2.更新用户信息
        user1.setUsername("星瞳");
        user1.setAddress("星神界");
        userDao.updateUser(user1);

        // 3.再次根据id查询用户
        User user2 = userDao.findById(41);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }

结果:
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第13张图片

二级缓存

新建测试类:

package com.itheima.test;

import com.itheima.dao.IUserDao;
import com.itheima.domain.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;

/**
 * 测试类
 */
public class SecondLevelCacheTest {

    private InputStream in;
    private SqlSessionFactory factory;

    @Before  //用于在测试方法执行之前执行
    public void init()throws Exception{
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory
        factory = new SqlSessionFactoryBuilder().build(in);
    }

    @After//用于在测试方法执行之后执行
    public void destroy()throws Exception{
        in.close();
    }

    /**
     * 测试二级缓存
     */
    @Test
    public void testFirstLevelCache() throws Exception {

        SqlSession sqlSession1 = factory.openSession();
        IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);

        User user1 = dao1.findById(41);
        System.out.println(user1);

        sqlSession1.close(); // 一次缓存清空

        System.out.println("---------------------------");

        SqlSession sqlSession2 = factory.openSession();
        IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);

        User user2 = dao2.findById(41);
        System.out.println(user2);

        sqlSession2.close();

        System.out.println(user1==user2);
    }

}

当我们未使用二级缓存时执行testFirstLevelCache()测试:
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第14张图片


接下来介绍并使用二级缓存

2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第15张图片
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第16张图片
第一步:在Mybatis核心配置文件中添加
不配也行,因为默认值就是true

在这里插入图片描述

<settings>
        <setting name="cacheEnabled" value="true"/>
 settings>

第二步:映射配置文件IUserDao.xml中添加:


<cache/>

第三部:映射配置文件IUserDao.xml中让想支持二级缓存的操作的的select标签中添加属性
2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第17张图片
当我们使用了二级缓存之后,再次执行testFirstLevelCache()测试:

2019/12/17:黑马Mybatis学习笔记(六)—— 延迟加载与缓存_第18张图片

你可能感兴趣的:(Mybatis)