SSM学习----Mybatis的缓存机制

文章目录

  • 前言
  • 搭建环境
    • 导入依赖
    • 编写配置文件
    • 编写实体类
    • 编写接口和映射文件
  • 一、一级缓存
    • 测试一级缓存失败
      • 1.两个会话时
      • 2.有删改查操作时
      • 3.手动清除缓存
  • 二、引入二级缓存
    • 简介
    • 工作机制
    • 使用步骤
      • 1.开启全局缓存
      • 2.配置mapper.xml
      • 测试
    • 添加了增删改的操作时
      • 注意
  • 总结


前言

MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。

MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存

  • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
  • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
  • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

    SSM学习----Mybatis的缓存机制_第1张图片

搭建环境

导入依赖

<dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

    </dependencies>
    <build>
        <!--解决maven静态资源过滤的问题-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties
                    **/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties
                    **/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
        <plugins>
            <!-- 设置jdk的版本-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

编写配置文件

<?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>
    <!--引入外部配置文件,必须写在首行-->
    <properties resource="db.properties"/>

    <!--设置-->
    <settings>
        <!--设置日志实现-->
        <setting name="logImpl" value="LOG4J"/>
        <!--开启驼峰命名转换-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <!--设置包名的方式设置别名-->
    <typeAliases>
        <package name="com.bao.pojo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="com/bao/dao/BlogMapper.xml"/>
    </mappers>
</configuration>

编写实体类

package com.bao.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {

    private String id;
    private String title;
    private String author;
    /*
     * 1.建议使用util包下的date
     * 2.属性名和字段名不一致,可通过设置mapUnderscoreToCamelCase的值为true,来开启自动驼峰命名规则映射
     * */
    private Date createTime;
    private int views;

}

编写接口和映射文件

编写接口

package com.bao.dao;

import com.bao.pojo.Blog;

public interface BlogMapper {

    /*查询一条数据*/
    Blog getBlogById(@Param("id") int id);

}

编写映射文件




    
   


一、一级缓存

一级缓存也叫本地缓存:

  • 与数据库同一次会话期间查询到的数据会放在本地缓存中。
  • 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;

测试一级缓存失败

1.两个会话时

 @Test
    public void testGetBlogById() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        SqlSession sqlSession1 = MybatisUtil.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        BlogMapper mapper1 = sqlSession1.getMapper(BlogMapper.class);
        Blog blogById = mapper.getBlogById(1);
        Blog blogById1 = mapper1.getBlogById(1);
        System.out.println(blogById);
        System.out.println(blogById1);
    }

测试结果
SSM学习----Mybatis的缓存机制_第2张图片
调用了两次sql语句

2.有删改查操作时

测试代码

@Test
    public void test1() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
        Blog blogById = blogMapper.getBlogById(1);
        System.out.println(blogById);
        System.out.println("-----------");
        int i = blogMapper.deleteBlog(2);
        System.out.println(i);
        Blog blogById1 = blogMapper.getBlogById(1);
        System.out.println(blogById1);
        sqlSession.close();
    }

测试结果
SSM学习----Mybatis的缓存机制_第3张图片

3.手动清除缓存

未使用sqlSession.clearCache()前,测试代码

 @Test
    public void test2() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Blog blogById = mapper.getBlogById(1);
//        sqlSession.clearCache();
        Blog blogById1 = mapper.getBlogById(1);
        System.out.println(blogById);
        System.out.println(blogById1);
        sqlSession.close();
    }

测试结果
SSM学习----Mybatis的缓存机制_第4张图片

使用该方法后代码
 @Test
    public void test2() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Blog blogById = mapper.getBlogById(1);
        sqlSession.clearCache();
        Blog blogById1 = mapper.getBlogById(1);
        System.out.println(blogById);
        System.out.println(blogById1);
        sqlSession.close();
    }

测试结果
SSM学习----Mybatis的缓存机制_第5张图片

二、引入二级缓存

简介

二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存

基于namespace级别的缓存,一个mapper.xml文件对应一个二级缓存

工作机制

一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;

如果当前会话关闭了,这个会话对应的一级缓存就没了;

但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中,新的会话查询信息,就可以从二级缓存中获取内容;

不同的mapper查出的数据会放在自己对应的缓存(map)中;

使用步骤

1.开启全局缓存

<setting name="cacheEnabled" value="true"/>

2.配置mapper.xml

<!--配置二级缓存-->
    <cache  eviction="FIFO"
            flushInterval="60000"
            size="512"
            readOnly="true"
    />
<!--这个更高级的配置创建了一个 FIFO 缓存(文件的输入输出),每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突-->

测试

  @Test
    public void testGetBlogById() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();

        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Blog blogById = mapper.getBlogById(1);
        System.out.println(blogById);
        sqlSession.close();


        SqlSession sqlSession2 = MybatisUtil.getSqlSession();
        BlogMapper mapper1 = sqlSession2.getMapper(BlogMapper.class);
        Blog blogById1 = mapper1.getBlogById(1);

        System.out.println(blogById1);
        sqlSession2.close();
    }

测试结果
SSM学习----Mybatis的缓存机制_第6张图片

代码如下(示例):

添加了增删改的操作时

    @Test
    public void test3() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
        Blog blogById = blogMapper.getBlogById(1);
        System.out.println(blogById);
        System.out.println("-----------");
        int i = blogMapper.deleteBlog(3);
        System.out.println(i);
        SqlSession sqlSession1 = MybatisUtil.getSqlSession();
        BlogMapper blogMapper1 = sqlSession1.getMapper(BlogMapper.class);
        Blog blogById1 = blogMapper1.getBlogById(1);
        System.out.println(blogById1);
        System.out.println(blogById == blogById1);
        sqlSession.close();
    }

测试结果
SSM学习----Mybatis的缓存机制_第7张图片

注意

可能出现实体类未序列化问题,需要实体类继承序列化接口。

总结

- 只要开启了二级缓存,在同一个Mapper中的查询,可以在二级缓存中拿到数据

  • 查出的数据都会被默认先放在一级缓存中
  • 只有会话提交或者关闭以后,一级缓存中的数据才会转到二级缓存中

你可能感兴趣的:(java,mybatis)