Mybatis快速上手7、8 一级缓存和二级缓存

其他章节及开发包:https://blog.csdn.net/XIMAX/article/details/106255196

环境 :Eclipse+Tomcat9+JDK10+Mybatis-3.1.1、Navicat

一级缓存

  1. 一级缓存默认开启

  2. 一级缓存存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。

  3. 一级缓存是SqlSession级别的缓存,缓存数据存储在HashMap中,在进行第一次查询时,首先会从数据库中查询出结果,然后将结果存在一级缓存中;当我们第二次查询时,首先会查询一级缓存,如果一级缓存没有,再查询数据库。在进行CUD操作并执行了commit或关闭Sqlsession后会将缓存清空。
    -----------------------------------------------------------分割线----------------------------------------------------------------

一级缓存较为简单,不做代码赘述,看一个简单案例

@Test
 void test() throws IOException {
  SqlSessionFactory factory = MybatisUtils.getFactory();
  SqlSession session = factory.openSession();

  String statement = "com.rjxy.test7.userMapper.getUser";
  
  CUser user = session.selectOne(statement,1);
  System.out.println(user);

  user = session.selectOne(statement,1);
  System.out.println(user);
  
  System.out.println("--------------");
  
  //清理掉则不会用一级缓存
  session.clearCache();
  user = session.selectOne(statement,1);
  System.out.println(user);

  System.out.println("---------------");
  
  //关闭后再打开,不是同一session对象,不会用一级缓存
  session.close();
  session = factory.openSession();
  
  user = session.selectOne(statement,1);
  System.out.println(user);
  session.close();
  }

结果输出:

2020-05-21 12:25:00,968 [main] DEBUG [com.rjxy.test7.userMapper.getUser] - ooo Using Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbda97b]
2020-05-21 12:25:00,969 [main] DEBUG [com.rjxy.test7.userMapper.getUser] - ==>  Preparing: select * from c_user where id=? 
2020-05-21 12:25:01,031 [main] DEBUG [com.rjxy.test7.userMapper.getUser] - ==> Parameters: 1(Integer)
CUser [id=1, name=Tom, age=12]
CUser [id=1, name=Tom, age=12]
--------------
2020-05-21 12:25:01,163 [main] DEBUG [com.rjxy.test7.userMapper.getUser] - ooo Using Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbda97b]
2020-05-21 12:25:01,163 [main] DEBUG [com.rjxy.test7.userMapper.getUser] - ==>  Preparing: select * from c_user where id=? 
2020-05-21 12:25:01,163 [main] DEBUG [com.rjxy.test7.userMapper.getUser] - ==> Parameters: 1(Integer)
CUser [id=1, name=Tom, age=12]
---------------
2020-05-21 12:25:01,167 [main] DEBUG [com.rjxy.test7.userMapper.getUser] - ooo Using Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbda97b]
2020-05-21 12:25:01,167 [main] DEBUG [com.rjxy.test7.userMapper.getUser] - ==>  Preparing: select * from c_user where id=? 
2020-05-21 12:25:01,168 [main] DEBUG [com.rjxy.test7.userMapper.getUser] - ==> Parameters: 1(Integer)
CUser [id=1, name=Tom, age=12]

从结果中可以看出第一部分中,当同一session第二次查询相同内容时,没有再调用sql语句,而是直接从缓存中取出,清理掉缓存及关闭session再打开查询时又重新调用了sql语句,无法共享

二级缓存

  1. 二级缓存存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache
  2. 二级缓存是Mapper级别的缓存,拥有多个SqlSession,同一Mapper中每个SqlSession中的缓存内容共享。若要使用二级缓存则存储数据的Java类需要实现Serializable接口
  3. 在进行CUD操作并执行了commit,缓存会被清空,默认不开启,开启需要在配置文件userMapper.xml中设置“”

在这里插入图片描述
test1~8分别对应八章,本章使用包test8、tool,文件config.xml、db.properties、log4j.properties

代码

建库,建表

CREATE TABLE c_user(
 id INT PRIMARY KEY AUTO_INCREMENT, 
 NAME VARCHAR(20), 
 age INT
);
INSERT INTO c_user(NAME, age) VALUES('Tom', 12);
INSERT INTO c_user(NAME, age) VALUES('Jack', 11);

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>
  <properties resource="db.properties"></properties>

<settings>
  <setting name="cacheEnabled" value="true"/>
 </settings>
 
  <typeAliases>
    <package name="com.rjxy.test8"/>
 <typeAliases>
 
 <typeAliases>
   <package name="com.rjxy.test2"/>
 <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/rjxy/test8/userMapper.xml"/>
 <mappers>
</configuration>

userMapper8.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.rjxy.test8.userMapper8">
 <cache></cache>
 <select id="getUser" parameterType="int" resultType="CUser2">
  select * from c_user where id=#{id}
 </select>
 <update id="updateUser" parameterType="CUser2">
  update c_user set name=#{name},age=#{age} where id=#{id}
 </update>
</mapper>

CUser2.java

package com.rjxy.test8;
import java.io.Serializable;
public class CUser2 implements Serializable{
private static final long serialVersionUID = 1L;
//二级缓存需要实现序列化接口
 private int id;
 private String name;
 private int age;

public CUser2() {}
 public CUser2(int id,String name,int age) {
  this.id = id;
  this.name = name;
  this.age = age;
 }
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 @Override
 public String toString() {
  return "CUser [id=" + id + ", name=" + name + ", age=" + age + "]";
 }
 }

JTest8.java

package com.rjxy.test8;

import java.io.IOException;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;
class JTest8 {
@Test
 void test2() throws IOException {
  SqlSessionFactory factory = MybatisUtils.getFactory();
  SqlSession session1 = factory.openSession();
  SqlSession session2 = factory.openSession();

  String statement = "com.rjxy.test8.userMapper8.getUser";
  
  CUser2 user = session1.selectOne(statement,1);
  session1.commit();
  System.out.println(user);

  CUser2 user2 = session2.selectOne(statement,1);
  session2.commit();
  System.out.println(user2);
 }
}

其它

其它文件与该系列第一篇相同 链接: https://blog.csdn.net/XIMAX/article/details/106244701

输出结果

2020-05-21 13:14:02,992 [main] DEBUG [com.rjxy.test8.userMapper8.getUser] - ooo Using Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbda97b]
2020-05-21 13:14:02,993 [main] DEBUG [com.rjxy.test8.userMapper8.getUser] - ==>  Preparing: select * from c_user where id=? 
2020-05-21 13:14:03,098 [main] DEBUG [com.rjxy.test8.userMapper8.getUser] - ==> Parameters: 1(Integer)
CUser [id=1, name=Tom, age=12]
CUser [id=1, name=Tom, age=12]

可以看出,第二次查询与第一次查询所用的是同一个mapper文件不同的session,但第二次查询没有调用sql语句

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值