MyBatis 教程

MyBatis session级别缓存

前面章节介绍了 MyBatis 的 <cache> 标签,使用该标签可以开启 MyBatis 的二级缓存。

本章节将现在看看 MyBatis 的一级缓存,也就是 session 级别的局部缓存。我们先看看实例:

(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"/>
    <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/demo1/UserMapper.xml" />
    </mappers>
</configuration>

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

package com.hxstrive.mybatis.cache.demo1;

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

(3)定义 Mapper 接口

a、UserMapper.java

package com.hxstrive.mybatis.cache.demo1;

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.demo1.UserMapper">
   <!-- 映射结果 -->
   <resultMap id="RESULT_MAP" type="com.hxstrive.mybatis.cache.demo1.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">
      select `user_id`, `name`, `sex`, `age` from `user`
   </select>

</mapper>

(4)客户端代码如下:

package com.hxstrive.mybatis.cache.demo1;

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/demo1/mybatis-cfg.xml";
      InputStream input = Resources.getResourceAsStream(cfgName);
      SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
      SqlSessionFactory sqlFactory = factoryBuilder.build(input);
      SqlSession sqlSession = sqlFactory.openSession(true);
      getUserInfo(sqlSession);
      getUserInfo(sqlSession);
   }

   private static void getUserInfo(SqlSession sqlSession) throws Exception {
      System.out.println("查询用户信息:");
      UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
      List<UserBean> userBeanList = userMapper.findAll();
      for(UserBean userBean : userBeanList) {
         System.out.println(userBean + " -- " + userBean.getName());
      }
   }

}

运行客户端代码输入结果如下:

查询用户信息:
com.hxstrive.mybatis.cache.demo1.UserBean@67b92f0a -- Helen
com.hxstrive.mybatis.cache.demo1.UserBean@2b9627bc -- 张小凡
com.hxstrive.mybatis.cache.demo1.UserBean@65e2dbf3 -- 叶星云
查询用户信息:
com.hxstrive.mybatis.cache.demo1.UserBean@67b92f0a -- Helen
com.hxstrive.mybatis.cache.demo1.UserBean@2b9627bc -- 张小凡
com.hxstrive.mybatis.cache.demo1.UserBean@65e2dbf3 -- 叶星云

通过查看上面输出结果,可以看到两次查询返回的对象是一样的,说明这些对象是被进行了缓存(mybatis session 级别缓存)。

上面两次查询均是在同一个 session 中进行的,如果我们将两次查询分别放到不同的 session 中进行会怎么样呢?将客户端代码作如下修改:

package com.hxstrive.mybatis.cache.demo1;

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 CacheDemo2 {

   public static void main(String[] args) throws Exception {
      String cfgName = "com/hxstrive/mybatis/cache/demo1/mybatis-cfg.xml";
      InputStream input = Resources.getResourceAsStream(cfgName);
      SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
      SqlSessionFactory sqlFactory = factoryBuilder.build(input);
      getUserInfo(sqlFactory);
      getUserInfo(sqlFactory);
   }

   private static void getUserInfo(SqlSessionFactory sqlFactory) throws Exception {
      System.out.println("查询用户信息:");
      SqlSession sqlSession = sqlFactory.openSession(true); // 每次查询创建一个新的 session
      UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
      List<UserBean> userBeanList = userMapper.findAll();
      for(UserBean userBean : userBeanList) {
         System.out.println(userBean + " -- " + userBean.getName());
      }
   }

}

运行上面客户端代码,输出结果如下:

查询用户信息:
com.hxstrive.mybatis.cache.demo1.UserBean@67b92f0a -- Helen
com.hxstrive.mybatis.cache.demo1.UserBean@2b9627bc -- 张小凡
com.hxstrive.mybatis.cache.demo1.UserBean@65e2dbf3 -- 叶星云
查询用户信息:
com.hxstrive.mybatis.cache.demo1.UserBean@43814d18 -- Helen
com.hxstrive.mybatis.cache.demo1.UserBean@5c5a1b69 -- 张小凡
com.hxstrive.mybatis.cache.demo1.UserBean@3701eaf6 -- 叶星云

仔细查看上面结果,你会发现两次查询返回的对象都是新对象。这是因为两次查询在不同的 session 中,mybatis 的 session 级别缓存失效了。后续章节将介绍怎样使用 <cache> 标签来开启二级缓存,二级缓存就没有 跨 session  问题。

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