MyBatis的缓存!!!!

  • 为什么使用缓存?

    首次访问时,查询数据库,并将数据存储到内存中;再次访问时直接访问缓存,减少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 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)测试类:

/*
 * 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 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)测试类:

/*
 * 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 文件开启二级缓存,默认开启,可以省略

<settings>
    <!-- 开启二级缓存的支持 -->
    <setting name="cacheEnabled" value="true"/>
</settings>

2.配置相关的Mapper映射文件 开启局部缓存(必须有)

 <!-- 开启二级缓存的支持 -->
    <cache></cache>

相关推荐

  1. Mybatis 缓存功能

    2023-12-26 11:00:03       25 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-26 11:00:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-26 11:00:03       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-26 11:00:03       82 阅读
  4. Python语言-面向对象

    2023-12-26 11:00:03       91 阅读

热门阅读

  1. 快速掌握TS基础知识

    2023-12-26 11:00:03       52 阅读
  2. html动态加载script

    2023-12-26 11:00:03       56 阅读
  3. C语言,数组元素逆序。

    2023-12-26 11:00:03       50 阅读
  4. 运维工程师的出路到底在哪里?

    2023-12-26 11:00:03       54 阅读
  5. Redis源码精读:哈希表

    2023-12-26 11:00:03       49 阅读
  6. Android 网络状态判断

    2023-12-26 11:00:03       64 阅读
  7. Docker面试题

    2023-12-26 11:00:03       60 阅读
  8. PHP进阶-默认参数值和可变参数列表

    2023-12-26 11:00:03       56 阅读