Mybatis缓存使用

一、Mybatis缓存分一级缓存,二级缓存,简单来说,

1、一级缓存,指在同一SqlSession中,SqlSession未关闭,两次查询sql语句相同,第二次不会查询数据库,直接从缓存中获取,默认开启一级缓存

2、二级缓存,指在不同SqlSession中,SqlSession未关闭,两次查询sql语句相同,第二次不会查询数据库,直接从缓存中获取,需要启动配置,

并且缓存的对象需要实现java.io.Serializable接口。

二、测试并使用缓存

1、添加依赖包,参考上篇文章 Mybatis+mysql入门使用

2、初始化数据库和初始数据,以mysql为例

DROP DATABASE IF EXISTS moy_mybatis;
CREATE DATABASE moy_mybatis CHARACTER SET UTF8;
USE moy_mybatis;

DROP TABLE  IF EXISTS t_test;

CREATE TABLE t_test(
    id int(11) AUTO_INCREMENT,
    create_time DATE comment ‘创建时间‘,
    modify_time DATE comment ‘修改时间‘,
    content VARCHAR (50) comment ‘内容‘,
    PRIMARY KEY (id)
);

INSERT INTO t_test (create_time,modify_time,content)
            VALUES (NOW(),NOW(),1);

3、新建实体类TestEntity

package com.moy.mybatis3.entity;

import java.io.Serializable;
import java.util.Date;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/20  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public class TestEntity implements Serializable{
    private Integer id;
    private Date createTime;
    private Date modifyTime;
    private String content;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getModifyTime() {
        return modifyTime;
    }

    public void setModifyTime(Date modifyTime) {
        this.modifyTime = modifyTime;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "TestEntity{" +
                "id=" + id +
                ", createTime=" + createTime +
                ", modifyTime=" + modifyTime +
                ", content=‘" + content + ‘\‘‘ +
                ‘}‘;
    }
}

4、新建实体对应配置文件Test.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.moy.mybatis3.mapper.TestMapper">
    <!--开启二级缓存-->
    <!--<cache></cache>-->
    <select id="get" parameterType="int" resultType="TestEntity">
        SELECT id,create_time as createTime,modify_time as modifyTime ,content
        FROM t_test WHERE id=#{id}
    </select>
</mapper>

5、编写接口TestMapper

package com.moy.mybatis3.mapper;

import com.moy.mybatis3.entity.TestEntity;

import java.io.Serializable;
import java.util.List;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/20  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public interface TestMapper {

    TestEntity get(Serializable id);
}

6、为了方便测试,编写一个获取SqlSession的工具类Mybatis3Utils

package com.moy.mybatis3.utils;

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 java.io.IOException;
import java.io.Reader;
import java.util.Objects;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/19  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public abstract class Mybatis3Utils {

    public static final SqlSessionFactory sqlSessionFactory;
    public static final ThreadLocal<SqlSession> sessionThread = new ThreadLocal<>();

    static {
        try {
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static SqlSession getCurrentSqlSession() {
        SqlSession sqlSession = sessionThread.get();
        if (Objects.isNull(sqlSession)) {
            sqlSession = sqlSessionFactory.openSession();
            sessionThread.set(sqlSession);
        }
        return sqlSession;
    }

    public static void closeCurrentSession() {
        SqlSession sqlSession = sessionThread.get();
        if (Objects.nonNull(sqlSession)) {
            sqlSession.close();
        }
        sessionThread.set(null);
    }
}

7、新建mybatis配置信息文件mybatis-config.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>

    <settings>
        <!--打印sql日志去控制台-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
        <package name="com.moy.mybatis3.entity"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/moy_mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/Test.xml"></mapper>
    </mappers>
</configuration>     

8、编写测试类TestMapperTest,测试一级缓存,控制台只会第一次查询打印sql日志,二次不会打印sql日志

package com.moy.mybatis3.mapper;

import com.moy.mybatis3.entity.TestEntity;
import com.moy.mybatis3.utils.Mybatis3Utils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import static org.junit.Assert.*;

/**
 * [Project]:moy-gradle-project  <br/>
 * [Email]:[email protected]  <br/>
 * [Date]:2018/2/20  <br/>
 * [Description]:  <br/>
 *
 * @author YeXiangYang
 */
public class TestMapperTest {

    SqlSession sqlSession;
    TestMapper testMapper;

    @Before
    public void before() {
        sqlSession = Mybatis3Utils.getCurrentSqlSession();
        testMapper = sqlSession.getMapper(TestMapper.class);
    }

    @After
    public void after() {
        Mybatis3Utils.closeCurrentSession();
    }

    @Test
    public void testFirstCache() {
        // 一级缓存(默认开启)
        // 在同一session中,session未关闭,
        // 两次查询sql语句相同,第二次不会查询数据库
        System.out.println("一级缓存 sqlSession--->" + sqlSession);
        System.out.println(testMapper.get(1));
        System.out.println(testMapper.get(1));
    }
}

9、测试二级缓存,取消Test.xml的<cache></cache>注释,添加测试方法

    @Test
    public void testSecondCache() {
        // 二级缓存 (需要开启缓存设置)
        // 在不同session中,
        // 两次查询sql语句相同,第二次不会查询数据库
        System.out.println("二级缓存 sqlSession--->" + sqlSession);
        System.out.println(testMapper.get(1));
        Mybatis3Utils.closeCurrentSession();

        sqlSession = Mybatis3Utils.getCurrentSqlSession();
        testMapper = sqlSession.getMapper(TestMapper.class);
        System.out.println("二级缓存 sqlSession--->" + sqlSession);
        System.out.println(testMapper.get(1));
    }

10、使用<cache></cache>元素配置缓存介绍

<!--
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="false"/>
创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。可用的收回策略有以下几种, 默认的是 LRU:
1. LRU – 最近最少使用的:移除最长时间不被使用的对象。
2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
flushInterval:刷新间隔时间,可以被设置为任意的正整数,单位毫秒。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
size:内存资源数目,可以被设置为任意正整数。默认值是1024。
readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是 false。
 -->

yexiangyang

[email protected]


原文地址:https://www.cnblogs.com/moy25/p/8457402.html

时间: 2024-11-05 11:53:56

Mybatis缓存使用的相关文章

Mybatis缓存报错org.apache.ibatis.exceptions.PersistenceException

错误信息如下: org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: org.apache.ibatis.cache.CacheException: Error deserializing object. Cause: java.lang.ClassNotFoundException: com.kytsoft.model.Adminlink ### Cause: org.apa

MyBatis学习总结(七)——Mybatis缓存(转载)

孤傲苍狼 只为成功找方法,不为失败找借口! MyBatis学习总结(七)--Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空. 2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,Hash

Mybatis缓存处理机制

一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空. 2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如

MyBatis学习总结(七)——Mybatis缓存

一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空. 2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如

MyBatis学习总结(六)——Mybatis缓存

一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空. 2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如

mybatis的sql 缓存,去除mybatis缓存

第二次用到mybaits,还是被同一个问题坑了几个小时,所以一定要把这个问题分享给大家.网友很多都是说了一大堆的配置,都是在mybatis.xml中配置.但是,我是没有用mybatis.xml的,我的配置都是在每个**mapper.xml中配置,无非就是一个关联实体类的路径,和一个别名. 在mybatis框架中,在SqlSession未关闭之前,在一个session里面,如果执行相同的select语句,mybatis不会重新查询数据库,而是直接返回缓存在内存中的查询结果,这个是与MyBatis的

MyBatis基础:MyBatis缓存(5)

1. MyBatis缓存简介 MyBatis提供支持一级缓存及二级缓存. 一级缓存: 2.MyBatis一级缓存

MyBatis缓存介绍

一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 相同提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存.其存储作用域为 Session.当 Session flush 或 close 之后,该Session中的全部 Cache 就将清空. 2. 二级缓存与一级缓存其机制同样,默认也是採用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),而且可自己定义存储源,如

MyBatis缓存禁用失败

问题:MyBatis缓存无法禁用,同一个session的select查询结果一样,但是数据库其实已改变. 尝试达到想要的目的: 1.msgmapper.xml里的select标签加上 <select id="queryMsg" resultMap="msgResulMap" flushCache="true" useCache="false"> select * from msg where msg_id = #{

MyBatis——Mybatis缓存

原文:http://www.cnblogs.com/xdp-gacl/p/4270403.html MyBatis学习总结(七)--Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空. 2. 二级缓存与一级缓存其机制相