• MyBatis 的缓存机制


    缓存机制可以减轻数据库的压力,原理是在第一查询时,将查询结果缓存起来,之后再查询同样的sql,

    不是真的去查询数据库,而是直接返回缓存中的结果。

    缓存可以降低数据库的压力,但同时可能无法得到最新的结果数据。

    1.数据库缓存的实现:

    通过第三方工具实现缓存:

      Redis内存数据库 - 可以实现缓存

    通过MyBatis提供的缓存机制来实现缓存:

      一级缓存:

    缓存只在一个事务中有效,即同一个事务中先后执行多次同一个查询,只在第一次真正去查库,并将结果缓存,之后的查询都直接获取缓存中的中数据。如果是不同的事务,则缓存无效。

      二级缓存:

    缓存在全局有效,一个事务查询一个sql得到结果,会被缓存起来,之后只要缓存未被清楚,则其他事务如果查询同一个sql,得到的将会是之前缓存的结果。二级缓存作用范围大,作用时间长,可能造成的危害也更大,所以在开发中一般很少启用Mybatis的二级缓存。

    2.MyBatis的一级缓存

    MyBatis的一级缓存默认就是开启的

        // 根据配置文件创建sqlSessionFactory
        private SqlSessionFactory factory = null;
        @Before
        public void before() throws Exception{
            //1.读取MyBatis核心配置文件
            InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
            //2.根据配置文件创建sqlSessionFactory
            factory = new SqlSessionFactoryBuilder().build(in);
        }
        
        /**
         * 一级缓存
         */
        @Test
        public void test16(){
            //1.创建sqlSession
            SqlSession session = factory.openSession();
            //2.执行操作
            List<User> list1 = session.selectList("cn.tedu.mybatis.beans.UserMapper.queryAll");
            List<User> list2 = session.selectList("cn.tedu.mybatis.beans.UserMapper.queryAll");
            //3.打印结果
            System.out.println(list1);
            System.out.println(list2);
        }

    测试结果:

    2018-10-27 14:41:53,932 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryAll] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@18987a33]
    2018-10-27 14:41:53,932 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryAll] - ==>  Preparing: select * from user 
    2018-10-27 14:41:53,957 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryAll] - ==> Parameters: 
    [User [id=1, name=aaa, age=19], User [id=2, name=bbb, age=29], User [id=4, name=ddd, age=22], User [id=5, name=eee, age=33], User [id=7, name=cjj, age=24]]
    [User [id=1, name=aaa, age=19], User [id=2, name=bbb, age=29], User [id=4, name=ddd, age=22], User [id=5, name=eee, age=33], User [id=7, name=cjj, age=24]]

    只在第一次查询时走了数据库,后续的查询走缓存。

    配置禁止一级缓存

        <select id="queryAll" flushCache="true" resultType="Alias_User">
            <include refid="saUser"/>
        </select>
    2018-10-27 14:48:08,832 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryAll] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@427eb6e2]
    2018-10-27 14:48:08,833 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryAll] - ==>  Preparing: select * from user 
    2018-10-27 14:48:08,857 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryAll] - ==> Parameters: 
    2018-10-27 14:48:08,874 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryAll] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@427eb6e2]
    2018-10-27 14:48:08,874 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryAll] - ==>  Preparing: select * from user 
    2018-10-27 14:48:08,874 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryAll] - ==> Parameters: 
    [User [id=1, name=aaa, age=19], User [id=2, name=bbb, age=29], User [id=4, name=ddd, age=22], User [id=5, name=eee, age=33], User [id=7, name=cjj, age=24]]
    [User [id=1, name=aaa, age=19], User [id=2, name=bbb, age=29], User [id=4, name=ddd, age=22], User [id=5, name=eee, age=33], User [id=7, name=cjj, age=24]]

    3.MyBatis的二级缓存

    MyBatis的二级缓存默认是关闭的

        // 根据配置文件创建sqlSessionFactory
        private SqlSessionFactory factory = null;
        @Before
        public void before() throws Exception{
            //1.读取MyBatis核心配置文件
            InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
            //2.根据配置文件创建sqlSessionFactory
            factory = new SqlSessionFactoryBuilder().build(in);
        }
        
        /**
         * 缓存机制:二级缓存
         */
        @Test
        public void test17(){
            //1.第一次事务
            SqlSession session1 = factory.openSession();
            User user1 = session1.selectOne(
                    "cn.tedu.mybatis.beans.UserMapper.queryOne",1);
            session1.commit();
            //2.第二次事务
            SqlSession session2 = factory.openSession();
            User user2 = session2.selectOne(
                    "cn.tedu.mybatis.beans.UserMapper.queryOne",1);
            session2.commit();
            //3.打印结果
            System.out.println(user1);
            System.out.println(user2);
        }

    测试结果:

    2018-10-27 14:49:58,913 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryOne] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@58648016]
    2018-10-27 14:49:58,913 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryOne] - ==>  Preparing: select * from user where id = ? 
    2018-10-27 14:49:58,935 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryOne] - ==> Parameters: 1(Integer)
    2018-10-27 14:49:58,959 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryOne] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@35f03691]
    2018-10-27 14:49:58,959 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryOne] - ==>  Preparing: select * from user where id = ? 
    2018-10-27 14:49:58,959 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryOne] - ==> Parameters: 1(Integer)
    User [id=1, name=aaa, age=19]
    User [id=1, name=aaa, age=19]

    配置选项开启二级缓存

    在sqlMapConfig.xml配置

        <!-- 开启二级缓存 -->
        <settings>
            <setting name="cacheEnabled" value="true"/>
        </settings>

    在映射文件中配置

    想要被二级缓存缓存的bean必须实现序列化接口

    测试类:

    运行结果:

    2018-10-27 14:57:36,745 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryOne] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@1dd49247]
    2018-10-27 14:57:36,746 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryOne] - ==>  Preparing: select * from user where id = ? 
    2018-10-27 14:57:36,772 [main] DEBUG [cn.tedu.mybatis.beans.UserMapper.queryOne] - ==> Parameters: 1(Integer)
    User [id=1, name=aaa, age=19]
    User [id=1, name=aaa, age=19]
  • 相关阅读:
    springboot嵌入式servlet容器的自动配置以及原理
    简单认识springboot的错误处理机制
    使用springboot来编写web项目的一些实现
    spring-cloud-starter-openfeign 源码详细讲解
    简述application.properties和application.yml 以及 @ConfigurationProperties 和@PropertySource @Value 和@ImportResource的用法,区别
    Ribbon源码分析(二)-- 服务列表的获取和负载均衡算法分析
    git的详细使用,项目创建到同步远程仓库,版本回退,忽略文件,分支创建,分支合并,分支名称修改,冲突解决,项目迁移
    Ribbon源码分析(一)-- RestTemplate 以及自定义负载均衡算法
    eureka源码--服务的注册、服务续约、服务发现、服务下线、服务剔除、定时任务以及自定义注册中心的思路
    eureka集群的搭建
  • 原文地址:https://www.cnblogs.com/chuijingjing/p/9861264.html
Copyright © 2020-2023  润新知