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,只查詢了一次證明二級緩存生效了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章