zoukankan      html  css  js  c++  java
  • 15-一级缓存

    一、Mybatis 中的缓存

    1.什么是缓存

    存在内存中的临时数据。

    2.为什么使用缓存

    减少与数据库交互次数,提高执行效率

    3.什么样的数据能使用缓存,什么样的数据不能使用缓存

    适用于缓存:

    1. 经常查询并且不经常改变。
    2. 数据的正确与否对最终结果影响不大的。

    不适用于缓存:

    1. 经常改变的数据。
    2. 数据的正确与否对最终结果影响很大。
    3. 例如:商品的库存,银行的汇率,股市的牌价。

    3.Mybatis 中的一级缓存和二级缓存

    一级缓存:

    1. 它指的是 Mybatis 中 SqlSession 对象的缓存。
    2. 当我们执行查询之后,查询的结果会同时存入到 SqlSession 为我们提供一块区域中。
    3. 该区域的结构时一个 Map 。当我们再次查询同样的数据,mybatis 会先去 sqlsession 中查询是否有,有的话直接拿出来用。
    4. 当 SqlSession 对象消失时,mybatis 的一级缓存也就消失了。

    二、一级缓存

    一级缓存分析

    一级缓存是 sqlsession 范围的缓,当调用 sqlsession 的修改、添加、删除、commit()、close()等方法时,就会清空一级缓存

    1.一级缓存测试

    Ⅰ测试类代码

        /**
         * 一级缓存
         */
        @Test
        public void testFirstLevelCache(){
            User user1=userDao.findById(1);
            System.out.println(user1);
            User user2=userDao.findById(1);
            System.out.println(user2);
            System.out.println(user1==user2);
        }
    

    Ⅱ输出结果

    Opening JDBC Connection
    [DEBUG] 2019-08-16 10:37:32,206 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:424)
    Created connection 11902257.
    [DEBUG] 2019-08-16 10:37:32,209 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==>  Preparing: select *from user where id=? 
    [DEBUG] 2019-08-16 10:37:32,233 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==> Parameters: 1(Integer)
    [DEBUG] 2019-08-16 10:37:32,254 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    <==      Total: 1
    domain.User@19dc67c2
    [DEBUG] 2019-08-16 10:37:32,254 method:org.apache.ibatis.transaction.jdbc.JdbcTransaction.close(JdbcTransaction.java:90)
    Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@b59d31]
    [DEBUG] 2019-08-16 10:37:32,255 method:org.apache.ibatis.datasource.pooled.PooledDataSource.pushConnection(PooledDataSource.java:381)
    Returned connection 11902257 to pool.
    [DEBUG] 2019-08-16 10:37:32,255 method:org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:136)
    Opening JDBC Connection
    [DEBUG] 2019-08-16 10:37:32,255 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:416)
    Checked out connection 11902257 from pool.
    [DEBUG] 2019-08-16 10:37:32,256 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==>  Preparing: select *from user where id=? 
    [DEBUG] 2019-08-16 10:37:32,256 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==> Parameters: 1(Integer)
    [DEBUG] 2019-08-16 10:37:32,257 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    <==      Total: 1
    domain.User@62bd765
    false
    

    可以看到上面的两个对象是同一个,并且返回是 true

    而且他只发起了一次查询,第一次查询,第二次是从缓存中取出

    如果 sqlsession 关闭则一级缓存关闭

    2.关闭一级缓存

    两种方法有所区别:

    第一种方法是关闭 sqlsession ,重新建立一个

    第二种是不关闭 sqlsession ,只清除缓存

    Ⅰ第一种方法:

        /**
         * 关闭一级缓存
         */
        @Test
        public void testFirstLevelCache2(){
            User user1=userDao.findById(1);
            System.out.println(user1);
            sqlSession.close();
            //再次获取 sqlsession
           sqlSession= factory.openSession(true);
            userDao=sqlSession.getMapper(IUserDao.class);
    
            User user2=userDao.findById(1);
            System.out.println(user2);
            System.out.println(user1==user2);
        }
    

    输出日志:

    Opening JDBC Connection
    [DEBUG] 2019-08-16 10:37:32,255 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:416)
    Checked out connection 11902257 from pool.
    [DEBUG] 2019-08-16 10:37:32,256 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==>  Preparing: select *from user where id=? 
    [DEBUG] 2019-08-16 10:37:32,256 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==> Parameters: 1(Integer)
    [DEBUG] 2019-08-16 10:37:32,257 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    <==      Total: 1
    domain.User@62bd765
    false
    

    Ⅱ第二种方法:

        @Test
        public void testFirstLevelCache2(){
            User user1=userDao.findById(1);
            System.out.println(user1);
            
            sqlSession.clearCache();
            userDao=sqlSession.getMapper(IUserDao.class);
    
            User user2=userDao.findById(1);
            System.out.println(user2);
            System.out.println(user1==user2);
        }
    

    输出日志:

    Opening JDBC Connection
    [DEBUG] 2019-08-16 10:41:08,333 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:424)
    Created connection 11902257.
    [DEBUG] 2019-08-16 10:41:08,336 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==>  Preparing: select *from user where id=? 
    [DEBUG] 2019-08-16 10:41:08,365 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==> Parameters: 1(Integer)
    [DEBUG] 2019-08-16 10:41:08,386 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    <==      Total: 1
    domain.User@19dc67c2
    [DEBUG] 2019-08-16 10:41:08,387 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==>  Preparing: select *from user where id=? 
    [DEBUG] 2019-08-16 10:41:08,389 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==> Parameters: 1(Integer)
    [DEBUG] 2019-08-16 10:41:08,392 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    <==      Total: 1
    domain.User@62bd765
    false
    

    2.在两个相同查询中间进行增、删、改

    一级缓存分析

    一级缓存是 sqlsession 范围的缓,当调用 sqlsession 的修改、添加、删除、commit()、close()等方法时,就会清空一级缓存

    Ⅰ改代码

        /**
         * 测试缓存的同步
         */
        @Test
        public void testClearCache(){
            //1.根据 id 查询用户
            User user1=userDao.findById(1);
            System.out.println(user1);
    
            //2.跟新用户信息
            user1.setUsername("update user");
            user1.setAddress("北京市海淀区");
            userDao.updateUser(user1);
    
            User user2=userDao.findById(1);
            System.out.println(user2);
    
            System.out.println(user1==user2);
        }
    

    输出日志:

    Opening JDBC Connection
    [DEBUG] 2019-08-16 10:56:30,917 method:org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:424)
    Created connection 11902257.
    [DEBUG] 2019-08-16 10:56:30,922 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==>  Preparing: select *from user where id=? 
    [DEBUG] 2019-08-16 10:56:30,946 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==> Parameters: 1(Integer)
    [DEBUG] 2019-08-16 10:56:30,962 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    <==      Total: 1
    domain.User@19dc67c2
    [DEBUG] 2019-08-16 10:56:30,964 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==>  Preparing: update user set username=?,address=? where id=? 
    [DEBUG] 2019-08-16 10:56:30,964 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==> Parameters: update user(String), 北京市海淀区(String), 1(Integer)
    [DEBUG] 2019-08-16 10:56:30,982 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    <==    Updates: 1
    [DEBUG] 2019-08-16 10:56:30,983 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==>  Preparing: select *from user where id=? 
    [DEBUG] 2019-08-16 10:56:30,983 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    ==> Parameters: 1(Integer)
    [DEBUG] 2019-08-16 10:56:30,984 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143)
    <==      Total: 1
    domain.User@78a2da20
    false
    
  • 相关阅读:
    数组实现栈
    栈应用实例单词逆序
    使用JXMapViewer将地图集成到swing app中
    使用xbee连接地面站和飞控
    QWT编译、配置、使用(Qt Creator)
    Qt跨线程调用错误解析及解决办法
    SVN版本服务器搭建(服务端+客户端)
    opencv配置过程 (cmake,vs2013,qt 5.4)
    基数排序/Go实现
    c/c++ 编译器内存对齐问题
  • 原文地址:https://www.cnblogs.com/zuiren/p/11406148.html
Copyright © 2011-2022 走看看