-------------MyBatis 缓存介绍-----------------------
MyBatis 提供了查询缓存来缓存数据,以提高查询的性能。MyBatis 的缓存分为一级缓存
和二级缓存
。
- 一级缓存是 SqlSession 级别的缓存(不同的 SqlSession 之间的缓存数据区域互不影响。)# 默认开启
- 二级缓存是 mapper 级别的缓存,多个 SqlSession 共享(不同的 SqlSession 两次执行相同的 namespace 下的 sql 语句,两次查询只执行一次)
------------------------------------MyBatis缓存与redis缓存的关系------------------------------------
---------MyBatis的一级缓存 二级缓存的实现----------------------------------------------------------------------------------
sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置数据源 -->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC" /><!-- JDBC 使用jdbc常规的事物代理管理 -->
<!--MANAGED 把事物交给spring容器进行 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
<!-- 映射文件 -->
<mappers>
<mapper resource="cn/yyeg/pojo/UserMapper.xml" />
</mappers>
</configuration>
UserMapper.xml
<?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="UserMapper">
<--<cache/>--> <-- 一级缓存可以关掉-->
<select id="findUser" resultType="cn.yyeg.pojo.User">
select * from user;
</select>
</mapper>
一级sql缓存的验证 //同一个sqlsesseion对象,使用一级缓存,查询一次 //session.close后再获取是新对象
package cn.yyeg.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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.Test;
import cn.yyeg.pojo.User;
public class MyTest {
@Test
public void test() throws IOException{
//创建输入流
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 创建会话
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//openSession(true)表示自动提交
SqlSession session = factory.openSession(true);
User user = new User();
user.setName("李白");
List<User> list = session.selectList( "UserMapper.findUser");
for (User user2 : list) {
System.out.println(user2);
}
System.out.println(session.hashCode());
//同一个sqlsesseion对象,使用一级缓存,查询一次 //session.close后再获取是新对象
// session.close();//关不关都一样
// session = factory.openSession(true);//获取新的sesseion
List<User> list1 = session.selectList( "UserMapper.findUser");
for (User user2 : list1) {
System.out.println(user2);
}
System.out.println(session.hashCode());//不同的值,不同的对象
}
}
二级缓存的验证 前提条件(Mapper级缓存)
1. UserMapper.xml 中设置一个 <cache/> 标签,#当前Mapper开启二级
或者sqlMapConfig.xml中设置全局二级缓存标签
<settings><!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/></settings>
2.session.close(); 上一个session必须close,然后再从工厂中获取session,才具有二级缓存的效果@风骚骚
3.操作的对象User必须实现序列化,否则java.io.NotSerializableException:
package cn.yyeg.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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.Before;
import org.junit.Test;
import cn.yyeg.pojo.User;
public class MyTest2 {
private SqlSession session = null;
private SqlSessionFactory factory = null;
@Before
public void inti() throws IOException {
// 创建输入流
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
// 创建会话
factory = new SqlSessionFactoryBuilder().build(inputStream);
// openSession(true)表示自动提交
session = factory.openSession(true);
}
@Test
public void test() throws IOException {
tt1();
System.out.println(session.hashCode());
session.close();//使用二级的前提是前一个session执行close()方法//不close,仍然两次查询
tt2();
System.out.println(session.hashCode());
}
private void tt2() {
session = factory.openSession(true);//关闭了,需要重新获取
List<User> list1 = session.selectList("UserMapper.findUser");
for (User user2 : list1) {
System.out.println(user2);
}
}
private void tt1() {
List<User> list = session.selectList("UserMapper.findUser");
for (User user2 : list) {
System.out.println(user2);
}
}
}