一级缓存与二级缓存

1.理解mybatis的缓存

  如大部分的持久化框架,mybatis也提供了一级缓存与二级缓存。

  一级缓存:基于perpetualcache的hashmap本地缓存,其存储作用为session,当session进行flush或者close之后,将该session中的cache进行清空。

  二级缓存:机制与一级缓存类似,默认采用perpetualcache,hashmap存储,不同在于存储作用域为Mapper(namespace),并且可以自定义存储。

  对于存储数据更新机制,当某一个作用域进行了C/U/D之后,默认该作用域下所有select中的缓存将被clear。

 

一:一级缓存

1.需求,目录结构

  根据id查询对应的用户记录对象。

  

 

2.准备数据

1 CREATE TABLE c_user(
2     id INT PRIMARY KEY auto_increment,
3     name VARCHAR(20),
4     age INT
5 );
6 INSERT INTO c_user(name,age) VALUES("TOM",12);
7 INSERT INTO c_user(NAME,age) VALUES("BOB",18);

 

3.创建实体类

 1 package com.cao.bean;
 2 
 3 public class CUser {
 4     private int id;
 5     private String name;
 6     private int age;
 7     public CUser() {}
 8     public CUser(int id,String name,int age) {
 9         this.id=id;
10         this.name=name;
11         this.age=age;
12     }
13     public int getId() {
14         return id;
15     }
16     public void setId(int id) {
17         this.id = id;
18     }
19     public String getName() {
20         return name;
21     }
22     public void setName(String name) {
23         this.name = name;
24     }
25     public int getAge() {
26         return age;
27     }
28     public void setSex(int age) {
29         this.age = age;
30     }
31     @Override
32     public String toString() {
33         return "CUser [id=" + id + ", name=" + name + ", age=" + age + "]";
34     }
35     
36 
37 }

 

4.映射文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper
 3     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5     <mapper namespace="procedure">
 6         <select id="getUser" parameterType="int" resultType="com.cao.bean.CUser">
 7             select * from c_user where id=#{id}
 8         </select>
 9         <update id="updateUser" parameterType="com.cao.bean.CUser">
10             update c_user set
11             name=#{name},age=#{age} where id=#{id}
12         </update>
13     </mapper>

 

5.配置文件

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
 3 
 4 <configuration>
 5   <environments default="development">
 6     <environment id="development">
 7       <transactionManager type="JDBC">
 8         <property name="" value=""/>
 9       </transactionManager>
10       <dataSource type="UNPOOLED">
11         <property name="driver" value="com.mysql.jdbc.Driver"/>
12         <property name="url" value="jdbc:mysql://127.0.0.1:3308/mybatis"/>
13         <property name="username" value="root"/>
14         <property name="password" value="123456"/>
15       </dataSource>
16     </environment>
17   </environments>
18 
19    <mappers>
20       <mapper resource="com/jun/sql/config/user.xml"/>
21    </mappers>
22 
23 </configuration>

 

6.测试类

 1 package com.jun.main;
 2 
 3 import java.io.IOException;
 4 import java.io.Reader;
 5 import java.util.HashMap;
 6 import java.util.Map;
 7 
 8 import org.apache.ibatis.io.Resources;
 9 import org.apache.ibatis.session.SqlSession;
10 import org.apache.ibatis.session.SqlSessionFactory;
11 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
12 import org.junit.Test;
13 
14 import com.cao.bean.CUser;
15 public class MainTest {
16     /**
17      * 方式一
18      * @throws Exception
19      */
20     @Test
21     public void test1() throws Exception {
22         Reader reader=Resources.getResourceAsReader("com/cao/config/Configuration.xml");
23         SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
24         SqlSession sqlSession=sqlSessionFactory.openSession(true);                //true后是自动提交
25         
26         String statement="procedure.getUser";
27         
28         CUser cuser=sqlSession.selectOne(statement, 1);
29         System.out.println(cuser);
30         //再跑一次
31         cuser=sqlSession.selectOne(statement, 1);
32         System.out.println(cuser);
33         sqlSession.close();
34     }
35     
36     
37 }

 

7.效果

  说明一级缓存是开着的。

  

 

8.调用方法进行清空缓存

  sqlSession.clearCache();

 1 package com.jun.main;
 2 
 3 import java.io.IOException;
 4 import java.io.Reader;
 5 import java.util.HashMap;
 6 import java.util.Map;
 7 
 8 import org.apache.ibatis.io.Resources;
 9 import org.apache.ibatis.session.SqlSession;
10 import org.apache.ibatis.session.SqlSessionFactory;
11 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
12 import org.junit.Test;
13 
14 import com.cao.bean.CUser;
15 public class MainTest {
16     /**
17      * 方式一
18      * @throws Exception
19      */
20     @Test
21     public void test1() throws Exception {
22         Reader reader=Resources.getResourceAsReader("com/cao/config/Configuration.xml");
23         SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
24         SqlSession sqlSession=sqlSessionFactory.openSession(true);                //true后是自动提交
25         
26         String statement="procedure.getUser";
27         
28         CUser cuser=sqlSession.selectOne(statement, 1);
29         System.out.println(cuser);
30         //再跑一次
31         cuser=sqlSession.selectOne(statement, 1);
32         System.out.println(cuser);
33         //清空缓存
34         sqlSession.clearCache();
35         cuser=sqlSession.selectOne(statement, 1);
36         System.out.println(cuser);
37         
38         sqlSession.close();
39     }
40     
41     
42 }

 

9.效果

  

 

10.增删改后清空缓存

 1 package com.jun.main;
 2 
 3 import java.io.IOException;
 4 import java.io.Reader;
 5 import java.util.HashMap;
 6 import java.util.Map;
 7 
 8 import org.apache.ibatis.io.Resources;
 9 import org.apache.ibatis.session.SqlSession;
10 import org.apache.ibatis.session.SqlSessionFactory;
11 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
12 import org.junit.Test;
13 
14 import com.cao.bean.CUser;
15 public class MainTest {
16     /**
17      * 方式一
18      * @throws Exception
19      */
20     @Test
21     public void test1() throws Exception {
22         Reader reader=Resources.getResourceAsReader("com/cao/config/Configuration.xml");
23         SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
24         SqlSession sqlSession=sqlSessionFactory.openSession(true);                //true后是自动提交
25         
26         String statement="procedure.getUser";
27         
28         CUser cuser=sqlSession.selectOne(statement, 1);
29         System.out.println(cuser);
30         //再跑一次
31         cuser=sqlSession.selectOne(statement, 1);
32         System.out.println(cuser);
33         //清空缓存
34 //        sqlSession.clearCache();
35         //执行增删改操作
36         String statement2="procedure.updateUser";
37         int update=sqlSession.update(statement2, new CUser(1,"JACK",15));
38         sqlSession.commit();
39         System.out.println(update);
40         //再次查询
41         cuser=sqlSession.selectOne(statement, 1);
42         System.out.println(cuser);
43         
44         sqlSession.close();
45     }
46     
47     
48 }

 

11.效果

  

 

12.关闭session清空缓存

 

二:二级缓存

1.添加一个<>cache>在映射文件中

  <cache/>

 

2.新建对象(这个对象必须实现序列化接口Serializable)

  注意点。

 1 package com.cao.bean;
 2 
 3 import java.io.Serializable;
 4 
 5 public class CUser implements Serializable{
 6     private int id;
 7     private String name;
 8     private int age;
 9     public CUser() {}
10     public CUser(int id,String name,int age) {
11         this.id=id;
12         this.name=name;
13         this.age=age;
14     }
15     public int getId() {
16         return id;
17     }
18     public void setId(int id) {
19         this.id = id;
20     }
21     public String getName() {
22         return name;
23     }
24     public void setName(String name) {
25         this.name = name;
26     }
27     public int getAge() {
28         return age;
29     }
30     public void setSex(int age) {
31         this.age = age;
32     }
33     @Override
34     public String toString() {
35         return "CUser [id=" + id + ", name=" + name + ", age=" + age + "]";
36     }
37     
38 
39 }

 

 3.在映射文件中加一个cache标签

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper
 3     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5     <mapper namespace="procedure">
 6         <cache></cache>
 7         <select id="getUser" parameterType="int" resultType="com.cao.bean.CUser">
 8             select * from c_user where id=#{id}
 9         </select>
10         <update id="updateUser" parameterType="com.cao.bean.CUser">
11             update c_user set
12             name=#{name},age=#{age} where id=#{id}
13         </update>
14     </mapper>

 

4.测试类

 1 package com.jun.main;
 2 
 3 import java.io.IOException;
 4 import java.io.Reader;
 5 import java.util.HashMap;
 6 import java.util.Map;
 7 
 8 import org.apache.ibatis.io.Resources;
 9 import org.apache.ibatis.session.SqlSession;
10 import org.apache.ibatis.session.SqlSessionFactory;
11 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
12 import org.junit.Test;
13 
14 import com.cao.bean.CUser;
15 public class MainTest {
16     /**
17      * 一
18      * @throws Exception
19      */
20     @Test
21     public void test1() throws Exception {
22         Reader reader=Resources.getResourceAsReader("com/cao/config/Configuration.xml");
23         SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
24         SqlSession sqlSession=sqlSessionFactory.openSession(true);                //true后是自动提交
25         
26         String statement="procedure.getUser";
27         
28         CUser cuser=sqlSession.selectOne(statement, 1);
29         System.out.println(cuser);
30         //再跑一次
31         cuser=sqlSession.selectOne(statement, 1);
32         System.out.println(cuser);
33         //清空缓存
34 //        sqlSession.clearCache();
35         //执行增删改操作
36         String statement2="procedure.updateUser";
37         int update=sqlSession.update(statement2, new CUser(1,"JACK",15));
38         sqlSession.commit();
39         System.out.println(update);
40         //再次查询
41         cuser=sqlSession.selectOne(statement, 1);
42         System.out.println(cuser);
43         
44         sqlSession.close();
45     }
46     /**
47      * 二
48      * @throws Exception
49      */
50     @Test
51     public void test2() throws Exception {
52         Reader reader=Resources.getResourceAsReader("com/cao/config/Configuration.xml");
53         SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
54         SqlSession sqlSession1=sqlSessionFactory.openSession();            
55         SqlSession sqlSession2=sqlSessionFactory.openSession();
56         
57         String statement="procedure.getUser";
58         
59         CUser cuser=sqlSession1.selectOne(statement, 1);
60         sqlSession1.commit();
61         System.out.println(cuser);
62         //再跑一次
63         cuser=sqlSession2.selectOne(statement, 1);
64         sqlSession1.commit();
65         System.out.println(cuser);
66         
67         
68         sqlSession1.close();
69     }
70     
71     
72 }

 

5.效果

  

 

6.注意点

  如果第一个session没有提交,则没有进行二级缓存。

  当然,如果第一个session是自动提交,第二个session也没有进行二次缓存。

  所以,想实现二级缓存,需要前面的session已经提交过,并且相同的提交sql。

 

三:回收策略

1.策略

  LRU:最近最少使用,移除长时间不使用的对象

  FIFO:先进先出

  SOFT:软引用,移除基于垃圾回收状态和软引用规则的对象

  WEAK:弱引用,更积极的移除基于垃圾收集器状态和软引用规则的对象

 

2.默认

  LRU。

 

  

 

转载于:https://www.cnblogs.com/juncaoit/p/8290377.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值