MyBatis 教程

MyBatis 开启二级缓存

本文将介绍怎样开启 MyBatis 的二级缓存。MyBatis 要开启二级缓存很简单,过程如下:

1)在 mybatis-cfg.xml 文件的 <settings> 中配置 <setting name="cacheEnabled" value="true" />,启用 MyBatis 全局缓存配置。

2)在 Mapper XML 文件中添加 <cache /> 标签,该标签可以配置缓存策略、刷新时间、缓存数量等。

示例代码

(1)MyBatis 配置文件 mybatis-cfg.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>
    <properties resource="database.properties"/>
    <settings>
        <!-- 全局映射器启用缓存 -->
        <setting name="cacheEnabled" value="true" />
    </settings>
    <environments default="MySqlDatabase" >
        <environment id="MySqlDatabase" >
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/hxstrive/mybatis/cache/demo2/UserMapper.xml" />
    </mappers>
</configuration>

上面配置文件使用 “<setting name="cacheEnabled" value="true" />” 开启 MyBatis 全局缓存。

(2)定义JavaBean实体 UserBean.java,代码如下:

package com.hxstrive.mybatis.cache.demo2;

import java.io.Serializable;

public class UserBean implements Serializable {
   private Integer userId;
   private String name;
   private String sex;
   private Integer age;
   // 忽略 getter 和 setter
}

注意:上面定义的 UserBean 需要实现 java.io.Serializable 接口,因为缓存需要序列化和反序列化。

(3)定义 Mapper 接口和配置文件,如下:

a、UserMapper.java

package com.hxstrive.mybatis.cache.demo2;

import java.util.List;

public interface UserMapper {
   List<UserBean> findAll();
}

b、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.hxstrive.mybatis.cache.demo2.UserMapper">
   <!-- 开启二级缓存 -->
   <cache />
   
   <!-- 映射结果 -->
   <resultMap id="RESULT_MAP" type="com.hxstrive.mybatis.cache.demo2.UserBean">
      <id column="user_id" jdbcType="INTEGER" property="userId" />
      <result column="name" jdbcType="VARCHAR" property="name" />
      <result column="sex" jdbcType="VARCHAR" property="sex" />
      <result column="age" jdbcType="INTEGER" property="age" />
   </resultMap>
   
   <!-- 查询所有用户信息 -->
   <select id="findAll" resultMap="RESULT_MAP" useCache="true">
      select `user_id`, `name`, `sex`, `age` from `user`
   </select>
</mapper>

上面通过 “<cache />” 配置开启 MyBatis 的二级缓存,这里的 <cache> 不是必须的,因为在前面使用了 “<setting name="cacheEnabled" value="true" />” 开启全局缓存。

(4)客户端代码如下:

package com.hxstrive.mybatis.cache.demo2;

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.InputStream;
import java.util.List;

public class CacheDemo {
   public static void main(String[] args) throws Exception {
      String cfgName = "com/hxstrive/mybatis/cache/demo2/mybatis-cfg.xml";
      InputStream input = Resources.getResourceAsStream(cfgName);
      SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
      SqlSessionFactory sqlFactory = factoryBuilder.build(input);
      getUserInfo(sqlFactory.openSession());
      getUserInfo(sqlFactory.openSession());
   }
   
   private static void getUserInfo(SqlSession sqlSession) {
      System.out.println("查询用户信息:");
      UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
      List<UserBean> userBeanList = userMapper.findAll();
      for(UserBean userBean : userBeanList) {
         System.out.println(userBean + " -- " + userBean.getName());
      }
      sqlSession.close();
   }
}

上面客户端代码中的 getUserInfo 方法将分别在不同的 SqlSession 中执行,这是因为 MyBatis 的二级缓存是 SqlSessionFactory 级别的。

运行客户端代码输出如下:

2020-09-07 13:11:03,400 DEBUG [org.apache.ibatis.logging.LogFactory] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
2020-09-07 13:11:03,411 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - PooledDataSource forcefully closed/removed all connections.
2020-09-07 13:11:03,411 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - PooledDataSource forcefully closed/removed all connections.
2020-09-07 13:11:03,411 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - PooledDataSource forcefully closed/removed all connections.
2020-09-07 13:11:03,412 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - PooledDataSource forcefully closed/removed all connections.
查询用户信息:
2020-09-07 13:11:03,516 DEBUG [org.apache.ibatis.cache.decorators.LoggingCache] - Cache Hit Ratio [com.hxstrive.mybatis.cache.demo2.UserMapper]: 0.0
2020-09-07 13:11:03,530 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Opening JDBC Connection
2020-09-07 13:11:04,058 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - Created connection 1663411182.
2020-09-07 13:11:04,058 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6325a3ee]
2020-09-07 13:11:04,066 DEBUG [com.hxstrive.mybatis.cache.demo2.UserMapper.findAll] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@6325a3ee]
2020-09-07 13:11:04,067 DEBUG [com.hxstrive.mybatis.cache.demo2.UserMapper.findAll] - ==>  Preparing: select `user_id`, `name`, `sex`, `age` from `user` 
2020-09-07 13:11:04,199 DEBUG [com.hxstrive.mybatis.cache.demo2.UserMapper.findAll] - ==> Parameters: 
2020-09-07 13:11:04,256 DEBUG [com.hxstrive.mybatis.cache.demo2.UserMapper.findAll] - <==      Total: 3
com.hxstrive.mybatis.cache.demo2.UserBean@6737fd8f -- Helen
com.hxstrive.mybatis.cache.demo2.UserBean@72b6cbcc -- 张小凡
com.hxstrive.mybatis.cache.demo2.UserBean@a7e666 -- 叶星云
2020-09-07 13:11:04,259 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6325a3ee]
2020-09-07 13:11:04,259 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@6325a3ee]
2020-09-07 13:11:04,260 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - Returned connection 1663411182 to pool.
查询用户信息:
2020-09-07 13:11:04,260 DEBUG [org.apache.ibatis.cache.decorators.LoggingCache] - Cache Hit Ratio [com.hxstrive.mybatis.cache.demo2.UserMapper]: 0.5
com.hxstrive.mybatis.cache.demo2.UserBean@6737fd8f -- Helen
com.hxstrive.mybatis.cache.demo2.UserBean@72b6cbcc -- 张小凡
com.hxstrive.mybatis.cache.demo2.UserBean@a7e666 -- 叶星云

仔细查看上面的输出结果,第一次查询创建了一个连接 “Created connection 1663411182”,而第二次连接并没有创建连接,而是直接从缓存中获取,此时缓存命中率为 0.5(Cache Hit Ratio [com.hxstrive.mybatis.cache.demo2.UserMapper]: 0.5)。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号