MyBatis 缓存策略

一.Mybatis 极简入门

二.Mybatis 级联查询

三.Mybatis 延迟加载

本篇.Mybatis 缓存策略

Mybatis中有两级缓存

  • sqlsession级别,默认开启。在sqlsession中执行查询操作后,会在本地创建一个HashMap用来存储缓存信息,下一次再在同一个sqlsession执行相同的sql语句时,会直接去缓存加载,当执行update,delete,insert操作时,为了保证数据一致性会强制清空缓存。我们通过测试代码来看看效果。
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test {
    public static void main(String[] args) {
        InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
        //这里执行了两次相同的查询语句,sql只会显示一条
        Student student=studentDAO.findStudentByIDLazy(2L);
        System.out.println(student.getName());
        Student student1=studentDAO.findStudentByIDLazy(2L);
        System.out.println(student1.getName());
    }
}

在这里插入图片描述

package com.ibuyi.mybatis.test;
import com.ibuyi.mybatis.entity.Student;
import com.ibuyi.mybatis.repository.StudentDAO;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test {
    public static void main(String[] args) {
        InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);

        SqlSession sqlSession = sqlSessionFactory.openSession();
        StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
        //这里执行了两次相同的查询语句,sql只会显示一条
        Student student=studentDAO.findStudentByIDLazy(2L);
        System.out.println(student.getName());
        sqlSession.close();

        //为了验证只在同一个sqlsesion中一级缓存有效,我们重新打开一个sqlsession
        SqlSession sqlSession1=sqlSessionFactory.openSession();
        StudentDAO studentDAO1=sqlSession1.getMapper(StudentDAO.class);
        Student student1 = studentDAO1.findStudentByIDLazy(2L);
        System.out.println(student1);

    }
}

在这里插入图片描述

可见,一级缓存只在同一个sqlsession中有效。

  • 二级缓存即mapper缓存,使用maper.xml中的同一个sql语句查询会被缓存,即在多个sqlsession中使用同一个mapper.xml的方法,如果有缓存就会直接在缓存中查找,需要指定同一个namespace.

具体实现步骤如下:

  1. 实体类需要实现序列化接口‘
package com.ibuyi.mybatis.entity;

import lombok.Data;

import java.io.Serializable;

@Data
public class Student implements Serializable {
    private long id;
    private String name;
    private Classes classes;

}

  1. 在mapper中开启cache
<?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.ibuyi.mybatis.repository.StudentDAO">
<!--添加cache打开缓存-->
    <cache></cache>
</mapper>

  1. 在config,xml文件中打开二级缓存
<setting name="cacheEnabled" value="true"/>

4 测试代码

package com.ibuyi.mybatis.test;
import com.ibuyi.mybatis.entity.Student;
import com.ibuyi.mybatis.repository.StudentDAO;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test {
    public static void main(String[] args) {
        InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);

        SqlSession sqlSession = sqlSessionFactory.openSession();
        StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
        //这里执行了两次相同的查询语句,sql只会显示一条
        Student student=studentDAO.findStudentByIDLazy(2L);
        System.out.println(student);
        sqlSession.close();

        //为了验证只在同一个sqlsesion中一级缓存有效,我们重新打开一个sqlsession
        sqlSession=sqlSessionFactory.openSession();
        StudentDAO studentDAO1=sqlSession.getMapper(StudentDAO.class);
        Student student1=studentDAO1.findStudentByIDLazy(2L);
        System.out.println(student1);

    }
}

在这里插入图片描述

可以看见,两个不同的sqlsession查询同一个map,只查询了一次证明二级缓存生效了

原文地址:https://www.cnblogs.com/hzcya1995/p/13309402.html