-
为什么使用缓存?
首次访问时,查询数据库,并将数据存储到内存中;再次访问时直接访问缓存,减少IO、硬盘读写次数、提高效率
-
Mybatis中的一级缓存和二级缓存?
-
一级缓存:
它指的是mybatis中的SqlSession对象的缓存。当我们执行完查询之后,查询的结果会同时存在在SqlSession为我们提供的一块区域中。当我们再次查询同样的数据,mybatis会先去SqlSession中查询是否有,有的话直接拿出来使用。当SqlSession对象消失时,Mybatis的一级缓存也就消失了。
-
二级缓存:
它指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessioFactory对象创建的SqlSession共享其缓存。
-
1.一级缓存(默认开启)
(1) 首先在UserMapper接口定义两个方法:
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 version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//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 userwhere id = #{id}</select><delete id="deleteUserById" parameterType="int">deletefrom userwhere id = #{id};</delete>
</mapper>
(3)测试类:
/** 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;@Beforepublic 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*/@Testpublic 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*/@Testpublic 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*/@Testpublic void testFirstNoCache2() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 创建sqlSessionFActorySqlSessionFactory 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);}@Afterpublic void close() throws IOException {//inputStream.close();//sqlSession.close();}}
2.二级缓存(需要手动开启)
(1)在UserMapper接口中创建两个方法:同上
(2)在UserMapper.xml文件中实现这两个方法:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//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 userwhere id = #{id}</select><delete id="deleteUserById" parameterType="int">deletefrom userwhere id = #{id};</delete>
</mapper>
(3)测试类:
/** 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;@Beforepublic 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*/@Testpublic 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*/@Testpublic 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*/@Testpublic void testSecondNoCache2() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream1 = Resources.getResourceAsStream(resource);InputStream inputStream2 = Resources.getResourceAsStream(resource);//工厂1SqlSessionFactory sessionFactory1 = new SqlSessionFactoryBuilder().build(inputStream1);SqlSession sqlSession1 = sessionFactory1.openSession();UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);//工厂2SqlSessionFactory 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);}@Afterpublic 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 文件开启二级缓存,默认开启,可以省略
<settings><!-- 开启二级缓存的支持 --><setting name="cacheEnabled" value="true"/>
</settings>
2.配置相关的Mapper映射文件 开启局部缓存(必须有)
<!-- 开启二级缓存的支持 --><cache></cache>