-
为什么使用缓存?
首次访问时,查询数据库,并将数据存储到内存中;再次访问时直接访问缓存,减少IO、硬盘读写次数、提高效率
-
Mybatis中的一级缓存和二级缓存?
-
一级缓存:
它指的是mybatis中的SqlSession对象的缓存。当我们执行完查询之后,查询的结果会同时存在在SqlSession为我们提供的一块区域中。当我们再次查询同样的数据,mybatis会先去SqlSession中查询是否有,有的话直接拿出来使用。当SqlSession对象消失时,Mybatis的一级缓存也就消失了。
-
二级缓存:
它指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessioFactory对象创建的SqlSession共享其缓存。
-
1.一级缓存(默认开启)
(1) 首先在UserMapper接口定义两个方法:
java
package com.by.mapper;
import com.by.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.junit.Test;
import java.util.List;
/**
* <p>Project: mybatis - UserMapper</p>
* <p>Powered by scl On 2023-12-22 15:52:05</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public interface UserMapper {
User getUserById(Integer id);
void deleteUserById(Integer id);
}
(2)在UserMapper.xml文件中实现这两个方法:
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="com.by.mapper.UserMapper">
<select id="getUserById" parameterType="int" resultType="user">
select *
from user
where id = #{id}
</select>
<delete id="deleteUserById" parameterType="int">
delete
from user
where id = #{id};
</delete>
</mapper>
(3)测试类:
java
/*
* Copyright (c) 2020, 2023, All rights reserved.
*
*/
package com.by;
import com.by.mapper.UserMapper;
import com.by.pojo.User;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* <p>Project: mybatis - MyBatisTest</p>
* <p>Powered by scl On 2023-12-18 11:44:53</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public class MyBatisTestCache {
private InputStream inputStream;
private SqlSession sqlSession;
@Before
public void init() throws IOException {
加载配置文件
//String resource = "mybatis-config.xml";
//inputStream = Resources.getResourceAsStream(resource);
//
创建sqlSessionFActory
//SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//
获得数据的绘画实例
//sqlSession = sessionFactory.openSession();
}
/**
* 一级缓存
*
* @throws IOException
*/
@Test
public void testFirstGoCache() {
UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);
UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);
System.out.println("=========One===========");
User user1 = userMapper1.getUserById(42); // 执行sql语句
System.out.println(user1);
System.out.println("=========Two===========");
User user2 = userMapper2.getUserById(42); // 不执行sql语句,走缓存
System.out.println(user2);
}
/**
* 一级缓存,不走缓存,同一个sqlSession,中间执行了增删改
*
* @throws IOException
*/
@Test
public void testFirstNoCache() {
UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);
UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);
System.out.println("=========One===========");
User user1 = userMapper1.getUserById(42); // 执行sql语句
System.out.println(user1);
System.out.println("========同一个sqlsession之间执行增删改========");
userMapper1.deleteUserById(41);
sqlSession.commit();
System.out.println("=========Two===========");
User user2 = userMapper2.getUserById(42); // 执行sql语句
System.out.println(user2);
}
/**
* 一级缓存,不走缓存,不同的sqlSession
*
* @throws IOException
*/
@Test
public void testFirstNoCache2() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建sqlSessionFActory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession1 = sessionFactory.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
// 获得数据的绘画实例
SqlSession sqlSession2 = sessionFactory.openSession();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
System.out.println("=========One===========");
User user1 = userMapper1.getUserById(42); // 执行sql语句
System.out.println(user1);
System.out.println("=========Two===========");
User user2 = userMapper2.getUserById(42); // 执行sql语句
System.out.println(user2);
}
@After
public void close() throws IOException {
//inputStream.close();
//sqlSession.close();
}
}
2.二级缓存(需要手动开启)
(1)在UserMapper接口中创建两个方法:同上
(2)在UserMapper.xml文件中实现这两个方法:
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="com.by.mapper.UserMapper">
<!--局部开启二级缓存-->
<cache></cache>
<select id="getUserById" parameterType="int" resultType="user">
select *
from user
where id = #{id}
</select>
<delete id="deleteUserById" parameterType="int">
delete
from user
where id = #{id};
</delete>
</mapper>
(3)测试类:
java
/*
* Copyright (c) 2020, 2023, All rights reserved.
*
*/
package com.by;
import com.by.mapper.UserMapper;
import com.by.pojo.User;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
/**
* <p>Project: mybatis - MyBatisTest</p>
* <p>Powered by scl On 2023-12-18 11:44:53</p>
* <p>描述:<p>
*
* @author 孙臣龙 [1846080280@qq.com]
* @version 1.0
* @since 17
*/
public class MyBatisTestCache2 {
private InputStream inputStream;
private SqlSession sqlSession;
@Before
public void init() throws IOException {
加载配置文件
//String resource = "mybatis-config.xml";
//inputStream = Resources.getResourceAsStream(resource);
//
创建sqlSessionFActory
//SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//
获得数据的绘画实例
//sqlSession = sessionFactory.openSession();
}
/**
* 二级缓存
*
* @throws IOException
*/
@Test
public void testSecondGoCache() {
UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);
UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);
System.out.println("=========One===========");
User user1 = userMapper1.getUserById(42); // 执行sql语句
System.out.println(user1);
sqlSession.commit();
System.out.println("=========Two===========");
User user2 = userMapper2.getUserById(42); // 不执行sql语句,走缓存
System.out.println(user2);
}
/**
* 二级缓存,不走缓存,两个sql之间执行增删改
*
* @throws IOException
*/
@Test
public void testSecondNoCache() {
UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);
UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);
System.out.println("=========One===========");
User user1 = userMapper1.getUserById(42); // 执行sql语句
System.out.println(user1);
sqlSession.commit();
System.out.println("************增删改**************");
userMapper1.deleteUserById(41);
sqlSession.commit();
System.out.println("=========Two===========");
User user2 = userMapper2.getUserById(42); // 执行sql语句
System.out.println(user2);
}
/**
* 二级缓存,不走缓存,不同的sqlSessionFactory
*
* @throws IOException
*/
@Test
public void testSecondNoCache2() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream1 = Resources.getResourceAsStream(resource);
InputStream inputStream2 = Resources.getResourceAsStream(resource);
//工厂1
SqlSessionFactory sessionFactory1 = new SqlSessionFactoryBuilder().build(inputStream1);
SqlSession sqlSession1 = sessionFactory1.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
//工厂2
SqlSessionFactory sessionFactory2 = new SqlSessionFactoryBuilder().build(inputStream2);
SqlSession sqlSession2 = sessionFactory2.openSession();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
System.out.println("=========One===========");
User user1 = userMapper1.getUserById(42); // 执行sql语句
System.out.println(user1);
sqlSession1.commit();
System.out.println("=========Two===========");
User user2 = userMapper2.getUserById(42); // 执行sql语句
System.out.println(user2);
}
@After
public void close() throws IOException {
//inputStream.close();
//sqlSession.close();
}
}
总结:
1、一级缓存
范围:一级缓存范围是sqlSession
配置:默认开启
走缓存:同一个sqlsession执行同一条sql
不走缓存:不同sqlSession 或 两次查询之间执行了增删改
2、二级缓存
范围:二级缓存范围是sqlSessionFactory
配置:<cache></cache>
走缓存:同一个sqlSessionFactrory,sqlsession执行commit或close
不走缓存:不同sqlSessionFactrory 或 两次查询之间执行了增删改
开启缓存:
1.在SqlMapConfig.xml 文件开启二级缓存,默认开启,可以省略
XML
<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>
2.配置相关的Mapper映射文件 开启局部缓存(必须有)
XML
<!-- 开启二级缓存的支持 -->
<cache></cache>