一.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.
具體實現步驟如下:
- 實體類需要實現序列化接口‘
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;
}
- 在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>
- 在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,只查詢了一次證明二級緩存生效了