一.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,只查询了一次证明二级缓存生效了