• 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

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

    金麟岂是池中物,一遇风云便化龙!
  • 相关阅读:
    JMeter学习-图形化 HTML 报表概要说明
    转《Python爬虫学习系列教程》学习笔记
    PYTHON __main__
    python property
    loadrunner脚本,如何获取lr的变量以及lr变量和其他程序语言的变量的转换
    参考链接
    彻底抛弃脚本录制,LR脚本之使用web_custom_request函数自定义http请求
    如何看Analysis分析图
    Ubuntu16.04安装QQ2015
    Ubuntu16.04运行LSD-SLAM踩坑笔记
  • 原文地址:https://www.cnblogs.com/ABKing/p/11996168.html
Copyright © 2020-2023  润新知