mybatis一级缓存和二级缓存的使用

在mybatis中,有一级缓存和二级缓存的概念:

一级缓存:一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQLSession, Mabits默认开启一级缓存。在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。

这么设计的原因是避免读取脏数据:假设A查询了某商品库存为10件,并将10件库存的数据存入缓存中,之后被客户买走了10件,数据被delete了,但是下次查询这件商品时,并不从数据库中查询,而是从缓存中查询,就会出现错误。

二级缓存:二级缓存是mapper级别的,Mybatis默认是没有开启二级缓存的。 第一次调用mapper下的SQL去查询用户的信息,查询到的信息会存放代该mapper对应的二级缓存区域。

看概念什么的最烦了是不是?用代码看看呗:

 1 package top.bigking;
 2 
 3 import org.apache.ibatis.io.Resources;
 4 import org.apache.ibatis.session.SqlSession;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 7 import top.bigking.dao.DeptMapper;
 8 import top.bigking.dao.UserMapper;
 9 import top.bigking.pojo.Dept;
10 import top.bigking.pojo.User;
11 
12 import java.io.InputStream;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 
17 public class mybatisStudy_start {
18     public static void main(String[] args) throws Exception{
19         InputStream in = Resources.getResourceAsStream("mybatisStudy-config.xml");
20         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
21         SqlSession sqlSession = sqlSessionFactory.openSession(true);//true 表示 自动提交
22         DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
23         List<Dept> deptList = deptMapper.query();
24         for(Dept dept : deptList){
25             System.out.println(dept);
26         }
27         System.out.println("-----------------------------------");
28         //insert(deptMapper);
29         //update(deptMapper);
30         findById(deptMapper);
31         
32         findById(deptMapper);
33         //delete(deptMapper);
34         //findByIdDname(deptMapper);
35 
36 //        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
37 //        List<User> userList = userMapper.query();
38 //        for(User user : userList)
39 //            System.out.println(user);
40         sqlSession.close();
41 
42     }
43     private static void insert(DeptMapper deptMapper){
44         Dept dept = new Dept();
45         dept.setDeptNo(11);
46         dept.setDname("ABKing");
47         dept.setLoc("111");
48         int count = deptMapper.insert(dept);
49         System.out.println(count);
50     }
51     public static void update(DeptMapper deptMapper){
52         Dept dept = new Dept();
53         dept.setDeptNo(11);
54         dept.setDname("ABKing");
55         dept.setLoc("上海");
56         int count = deptMapper.update(dept);
57         System.out.println(count);
58     }
59     public static void findById(DeptMapper deptMapper){
60         Dept dept = deptMapper.findById(11);
61         System.out.println(dept);
62     }
63     public static void delete(DeptMapper deptMapper){
64         int count = deptMapper.delete(11);
65         System.out.println(count);
66     }
67     public static void findByIdDname(DeptMapper deptMapper){
68         Map map = new HashMap();
69         map.put("deptNo", "11");
70         map.put("dname", "ABKing");
71         Dept dept = deptMapper.findByIdDname(map);
72         System.out.println(dept);
73     }
74 }

看30行和32行,能看到调用了两次findById(deptMapper),运行,查看控制台的日志(需要log4j包)

DEBUG [main] - ==>  Preparing: select deptNo, dname, loc from Dept where deptNo=? 

只打印出了一条SQL语句

而如果我们在31行加入sqlSession.clearCache();

 1 package top.bigking;
 2 
 3 import org.apache.ibatis.io.Resources;
 4 import org.apache.ibatis.session.SqlSession;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 7 import top.bigking.dao.DeptMapper;
 8 import top.bigking.dao.UserMapper;
 9 import top.bigking.pojo.Dept;
10 import top.bigking.pojo.User;
11 
12 import java.io.InputStream;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 
17 public class mybatisStudy_start {
18     public static void main(String[] args) throws Exception{
19         InputStream in = Resources.getResourceAsStream("mybatisStudy-config.xml");
20         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
21         SqlSession sqlSession = sqlSessionFactory.openSession(true);//true 表示 自动提交
22         DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
23         List<Dept> deptList = deptMapper.query();
24         for(Dept dept : deptList){
25             System.out.println(dept);
26         }
27         System.out.println("-----------------------------------");
28         //insert(deptMapper);
29         //update(deptMapper);
30         findById(deptMapper);
31         sqlSession.clearCache();
32         findById(deptMapper);
33         //delete(deptMapper);
34         //findByIdDname(deptMapper);
35 
36 //        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
37 //        List<User> userList = userMapper.query();
38 //        for(User user : userList)
39 //            System.out.println(user);
40         sqlSession.close();
41 
42     }
43     private static void insert(DeptMapper deptMapper){
44         Dept dept = new Dept();
45         dept.setDeptNo(11);
46         dept.setDname("ABKing");
47         dept.setLoc("111");
48         int count = deptMapper.insert(dept);
49         System.out.println(count);
50     }
51     public static void update(DeptMapper deptMapper){
52         Dept dept = new Dept();
53         dept.setDeptNo(11);
54         dept.setDname("ABKing");
55         dept.setLoc("上海");
56         int count = deptMapper.update(dept);
57         System.out.println(count);
58     }
59     public static void findById(DeptMapper deptMapper){
60         Dept dept = deptMapper.findById(11);
61         System.out.println(dept);
62     }
63     public static void delete(DeptMapper deptMapper){
64         int count = deptMapper.delete(11);
65         System.out.println(count);
66     }
67     public static void findByIdDname(DeptMapper deptMapper){
68         Map map = new HashMap();
69         map.put("deptNo", "11");
70         map.put("dname", "ABKing");
71         Dept dept = deptMapper.findByIdDname(map);
72         System.out.println(dept);
73     }
74 }

此时查看控制台的日志

DEBUG [main] - ==>  Preparing: select deptNo, dname, loc from Dept where deptNo=? 
DEBUG [main] - ==> Parameters: 11(Integer)
DEBUG [main] - <==      Total: 1
Dept{deptNo=11, dname='ABKing', loc='111'}
DEBUG [main] - ==>  Preparing: select deptNo, dname, loc from Dept where deptNo=? 

可以看到打印出了两条SQL语句,这足以证明,使用了sqlSession.clearCache();之后,缓存被清空了

 接下来证明二级缓存:

应当明确的是,二级缓存是mapper级别的缓存,使用同一个Mapper.class的的Mapper类和SqlSession类都共用同一个二级缓存

代码如下:

 1 package top.bigking;
 2 
 3 import org.apache.ibatis.io.Resources;
 4 import org.apache.ibatis.session.SqlSession;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 7 import top.bigking.dao.DeptMapper;
 8 import top.bigking.dao.UserMapper;
 9 import top.bigking.pojo.Dept;
10 import top.bigking.pojo.User;
11 
12 import java.io.InputStream;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 
17 public class mybatisStudy_start {
18     public static void main(String[] args) throws Exception{
19         InputStream in = Resources.getResourceAsStream("mybatisStudy-config.xml");
20         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
21         SqlSession sqlSession = sqlSessionFactory.openSession(true);//true 表示 自动提交
22         SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
23         DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
24         DeptMapper deptMapper1 = sqlSession1.getMapper(DeptMapper.class);
25         List<Dept> deptList = deptMapper.query();
26         for(Dept dept : deptList){
27             System.out.println(dept);
28         }
29         System.out.println("-----------------------------------");
30         //insert(deptMapper);
31         //update(deptMapper);
32         findById(deptMapper);
33         sqlSession.close();
34         //sqlSession.clearCache();
35         findById(deptMapper1);
36         sqlSession1.close();
37         //delete(deptMapper);
38         //findByIdDname(deptMapper);
39 
40 //        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
41 //        List<User> userList = userMapper.query();
42 //        for(User user : userList)
43 //            System.out.println(user);
44         //sqlSession.close();
45 
46     }
47     private static void insert(DeptMapper deptMapper){
48         Dept dept = new Dept();
49         dept.setDeptNo(11);
50         dept.setDname("ABKing");
51         dept.setLoc("111");
52         int count = deptMapper.insert(dept);
53         System.out.println(count);
54     }
55     public static void update(DeptMapper deptMapper){
56         Dept dept = new Dept();
57         dept.setDeptNo(11);
58         dept.setDname("ABKing");
59         dept.setLoc("上海");
60         int count = deptMapper.update(dept);
61         System.out.println(count);
62     }
63     public static void findById(DeptMapper deptMapper){
64         Dept dept = deptMapper.findById(11);
65         System.out.println(dept);
66     }
67     public static void delete(DeptMapper deptMapper){
68         int count = deptMapper.delete(11);
69         System.out.println(count);
70     }
71     public static void findByIdDname(DeptMapper deptMapper){
72         Map map = new HashMap();
73         map.put("deptNo", "11");
74         map.put("dname", "ABKing");
75         Dept dept = deptMapper.findByIdDname(map);
76         System.out.println(dept);
77     }
78 }

在DeptMapper.xml中

    <select id="findById" resultType="Dept" useCache="true">
        select deptNo, dname, loc from Dept where deptNo=#{deptNo}
    </select>

通过useCache可以使用二级缓存

在mybatisStudy-config.xml中,在properties标签下,添加

   <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

这是全局设置,表示开启二级缓存

查看控制台输出的日志:

DEBUG [main] - ==>  Preparing: select deptNo, dname, loc from Dept where deptNo=? 
DEBUG [main] - ==> Parameters: 11(Integer)
DEBUG [main] - <==      Total: 1
Dept{deptNo=11, dname='ABKing', loc='111'}
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a9273a8]

可以看到,由于使用了二级缓存,我们的日志中,只出现了一条SQLQL语句

而如果我们把DeptMapper.xml中的代码改为:

  <select id="findById" resultType="Dept" useCache="false">
        select deptNo, dname, loc from Dept where deptNo=#{deptNo}
    </select>

表示不使用二级缓存

运行,查看控制台:

DEBUG [main] - ==>  Preparing: select deptNo, dname, loc from Dept where deptNo=? 
DEBUG [main] - ==> Parameters: 11(Integer)
DEBUG [main] - <==      Total: 1
Dept{deptNo=11, dname='ABKing', loc='111'}
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a9273a8]
DEBUG [main] - Returned connection 2056418216 to pool.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Checked out connection 2056418216 from pool.
DEBUG [main] - ==>  Preparing: select deptNo, dname, loc from Dept where deptNo=? 
DEBUG [main] - ==> Parameters: 11(Integer)
DEBUG [main] - <==      Total: 1
Dept{deptNo=11, dname='ABKing', loc='111'}
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a9273a8]

可以看到两条SQL语句

可是我们的代码中,并没有使用到清空一级缓存的函数sqlSession.clearCache();

由此可证明,这里是二级缓存的开关 

参考:

https://m.w3cschool.cn/kzsow/kzsow-qmod2gri.html

https://www.cnblogs.com/happyflyingpig/p/7739749.html

https://www.cnblogs.com/yuluoxingkong/p/8205858.html

https://www.cnblogs.com/charlypage/p/9747145.html

----------------------------------------------------------------------------
大家好,我是ABKing

金麟岂是池中物,一遇风云便化龙!
欢迎与我交流技术问题

猜你喜欢

转载自www.cnblogs.com/ABKing/p/11996168.html
今日推荐