精华内容
下载资源
问答
  • Redis 是完全开源免费的,遵守BSD协议,是个高性能的key-value数据库 Redis 与其他 key – value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载...
  • 本文主要介绍在SpringBoot项目中如何使用Mybatis的一级二级缓存,为了演示方便,本文的数据库采用H2内存数据库,数据库连接池默认使用SpringBoot2.X自带的hikariCP。 正确的使用Mybatis缓存可以有效减少多余的...

    本文主要介绍在SpringBoot项目中如何使用Mybatis的一级、二级缓存,为了演示方便,本文的数据库采用H2内存数据库,数据库连接池默认使用SpringBoot2.X自带的hikariCP。 正确的使用Mybatis缓存可以有效减少多余的数据库查询操作,节约IO。 接下来我们从实践出发,看一看mybatis的一级,二级缓存如何使用,相关代码请查阅:https://github.com/zhengxl5566/springboot-demo.git

    1、概念介绍

    什么是一级缓存 在日常开发过程中,经常会有相同的sql执行多次查询的情况,mybatis提供了一级缓存来优化这些查询,避免多次请求数据库。 一级缓存在mybatis中默认是开启的并且是session级别,它的作用域为一次sqlSession会话。

    什么是二级缓存 相对于一级缓存,二级缓存的作用域更广泛,它不止局限于一个sqlSession,可以在多个sqlSession之间共享,事实上,它的作用域是namespace。 mybatis的二级缓存默认也是开启的,但由于他的作用域是namespace,所以还需要在mapper.xml中开启才能生效

    缓存的优先级 通过mybatis发起的查询,作用顺序为:二级缓存->一级缓存->数据库 ,其中任何一个环节查到不为空的数据,都将直接返回结果

    缓存失效 当在一个缓存作用域中发生了update、insert、delete 动作后,将会触发缓存失效,下一次查询将命中数据库,从而保证不会查到脏数据。

    2、代码演示

    一级缓存

    默认情况下,mybatis开启并使用了一级缓存。 单元测试用例:

    /**

    * 开启事务,测试一级缓存效果

    * 缓存命中顺序:二级缓存---> 一级缓存---> 数据库

    **/

    @Test

    @Transactional(rollbackFor = Throwable.class)

    public void testFistCache(){

    // 第一次查询,缓存到一级缓存

    userMapper.selectById(1);

    // 第二次查询,直接读取一级缓存

    userMapper.selectById(1);

    }

    执行结果:

    c92126a5d4647aacf0604a44e34bd0d0.png

    可以看到,虽然进行了两次查询,但最终只请求了一次数据库,第二次查询命中了一级缓存,直接返回了数据。 这里有两点需要说明一下: 1、为什么开启事务 由于使用了数据库连接池,默认每次查询完之后自动commite,这就导致两次查询使用的不是同一个sqlSessioin,根据一级缓存的原理,它将永远不会生效。 当我们开启了事务,两次查询都在同一个sqlSession中,从而让第二次查询命中了一级缓存。读者可以自行关闭事务验证此结论。 2、两种一级缓存模式 一级缓存的作用域有两种:session(默认)和statment,可通过设置local-cache-scope 的值来切换,默认为session。 二者的区别在于session会将缓存作用于同一个sqlSesson,而statment仅针对一次查询,所以,local-cache-scope: statment可以理解为关闭一级缓存。

    二级缓存

    默认情况下,mybatis打开了二级缓存,但它并未生效,因为二级缓存的作用域是namespace,所以还需要在Mapper.xml文件中配置一下才能使二级缓存生效

    单表二级缓存 下面对userMapper.xml配置一下,让其二级缓存生效,只需加入cache标签即可

    单元测试用例:

    /**

    * 测试二级缓存效果

    * 需要*Mapper.xml开启二级缓存

    **/

    @Test

    public void testSecondCache(){

    userMapper.selectById(1);

    userMapper.selectById(1);

    }

    执行结果:

    d9182b801494a7b0f8e0192fe5722788.png 这里可以看到,第二次查询直接命中了缓存,日志还打印了该缓存的命中率。读者可以自行关闭二级缓存查看效果,通过注掉对应mapper.xml的cache标签,或者 cache-enabled: false 均可

    多表联查二级缓存 接下来演示多表联查的二级缓存,user表left join user_order表 on user.id = user_order.user_id 我们考虑这样一种情况,该联查执行两次,第二次联查前更新user_order表,如果只使用cache配置,将会查不到更新的user_orderxi,因为两个mapper.xml的作用域不同,要想合到一个作用域,就需要用到cache-ref userOrderMapper.xml

    userMapper.xml

    单元测试用例:

    /**

    * 测试多表联查的二级缓存效果

    * 需要*Mapper.xml设定引用空间

    **/

    @Test

    public void testJoin(){

    System.out.println(userMapper.selectJoin());

    System.out.println(userMapper.selectJoin());

    UserOrder userOrder = new UserOrder();

    userOrder.setGoodName("myGoods");

    userOrder.setUserId(1);

    userOrderMapper.saveOrder(userOrder);

    System.out.println(userMapper.selectJoin());

    }

    执行结果:

    491a540e29d095586d9ec132b39eb49f.png

    首先查询了两次user表,第二次命中二级缓存,然后更新user_order表,使缓存失效,第三次查询时命中数据库。

    综上,mybatis的单机缓存就介绍完了,读者可以自行下载样例工程验证。

    总结:

    mybatis默认的session级别一级缓存,由于springboot中默认使用了hikariCP,所以基本没用,需要开启事务才有用。但一级缓存作用域仅限同一sqlSession内,无法感知到其他sqlSession的增删改,所以极易产生脏数据 二级缓存可通过cache-ref让多个mapper.xml共享同一namespace,从而实现缓存共享,但多表联查时配置略微繁琐。 所以生产环境建议将一级缓存设置为statment级别(即关闭一级缓存),如果有必要,可以开启二级缓存

    注意:如果应用是分布式部署,由于二级缓存存储在本地,必然导致查询出脏数据,所以,分布式部署的应用不建议开启。

    参考资料:

    展开全文
  • mysql级缓存和二级缓存

    千次阅读 2019-08-05 19:10:14
    一级缓存: 也称本地缓存,sqlSession级别的缓存。一级缓存是一直开启的;与数据库同次回话期间查询到的数据会放在本地缓存中。 如果需要获取相同的数据,直接从缓存中拿,不会再查数据库。 一级缓存失效的四种...

    一级缓存:

    也称本地缓存,sqlSession级别的缓存。一级缓存是一直开启的;与数据库同一次回话期间查询到的数据会放在本地缓存中。

    如果需要获取相同的数据,直接从缓存中拿,不会再查数据库。

    一级缓存失效的四种情况:

    1.sqlSession不同。
        2.sqlSession相同,查询条件不同。因为缓存条件不同,缓存中还没有数据。
        3.sqlSession相同,在两次相同查询条件中间执行过增删改操作。(因为中间的增删改可能对缓存中数据进行修改,所以不能用)
        4.sqlSession相同,手动清空了一级缓存。(如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。)
    二级缓存:全局缓存;基于namespace级别的缓存。一个namespace对应一个二级缓存。

    工作机制:1.一个会话,查询一条数据,这个数据会被放在当前会话的一级缓存中。

    2,如果会话被关闭了,一级缓存中的数据会被保存带二级缓存。新的会话查询信息就会参照二级缓存。

    3.sqlSession > Employee>employee

    sqlSession >DepartmentMapper=>Department

    不同的namespace查出的数据会放在自己对应的缓存中。

    效果:查出的数据首先放在一级缓存中,只有一级缓存被关闭或者提交以后,一级缓存数据才会转移到二级缓存

    使用步骤:

    1.开启全局缓存配置。

    2.因为是namespace级别,需要搭配每个xxxMapper.xml中配置二级缓存

    eviction:缓存的回收策略:

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

    FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

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

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

    flushInterval:缓存刷新间隔。缓存多久清空一次,默认不清空。设置一个毫秒值。

    readOnly:是否只读。true:mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。

    mybatis为了加快获取速度,直接就会将数据在缓存中的引用交给用户。不安全,速度快。

    false:mybatis觉得获取的数据可能被修改。mybatis会利用序列化和反序列化的技术克隆一份新的数据给用户。安全,速度快。

    size:缓存放多少元素。

    type:指定自定义缓存全类名。实现cache接口即可。

    3.pojo需要实现序列换接口。

    和缓存相关的配置/属性:

    1.cacheEnabled:如果是false,关闭二级缓存,不关闭一级缓存。

    2.每个select标签都有userCache="true"属性:对一级缓存没有影响。设置为false,二级缓存失效。

    3.每个增删改标签都有flushCache="true"属性:一级缓存和二级缓存都会被清空。

    4.在查询标签中flushCache="false"属性:如果设置为true,查完会清空,一级二级缓存都会被清空,都不会用缓存。

    5.sqlSession.clearn():跟session有关,只会清除一级缓存。

    6.localCacheScope:本地缓存作用域。

    一级缓存SESSION:当前会话的所有数据保存到回话缓存中。STATEMENT:禁用一级缓存。

    缓存首先一进来去查二级缓存,二级缓存没有去找一级缓存,一级缓存没有去找数据库。二级缓存----->一级缓存-------->数据库。

    自定义缓存 implements Cache,重写接口中的保存等方法,比如说保存到redis.

    展开全文
  • mysql一二级缓存

    2020-10-16 16:43:53
    个nameSpace(同个mapper.xml)对应二级缓存级缓存失效后会将数据存入二级缓存 级缓存查不到,会去查二级缓存 不同mapper(不同二级缓存)缓存相互独立 默认使用LRU算法。 <cache eviction="F

    一级缓存

    相同sqlsession以相同查询条件查询,第二次查询会使用第一次查询的,已加入缓存的结果。

    会有一些情况使一级缓存失效:

    1. 查询条件不同
    2. 不是同一个sqlsession
    3. 同一个sqlsession,,但是两次查询中间穿插增删改
      在这里插入图片描述

    二级缓存

    只能在单表操作内使用二级缓存。不可以一张表在多个mapper内操作,或一个mapper内操作多个表。并且建议查询远大于增删改时使用。

    一个nameSpace(同一个mapper.xml)对应一个二级缓存。

    1. 一级缓存失效后会将数据存入二级缓存
    2. 一级缓存查不到,会去查二级缓存
    3. 不同mapper(不同二级缓存)缓存相互独立

    默认使用LRU算法。

    <cache
      eviction="FIFO"
      flushInterval="60000"
      size="512"
      readOnly="true"/>
    

    可以设置刷新时间、设置置换策略(FIFO,LRU,SOFT,WEAK)、size、readOnly

    在这里插入图片描述

    展开全文
  • mysql一二级缓存介绍

    千次阅读 2020-05-18 11:22:47
    Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存一级缓存只是相对于同个SqlSession而言。所以在参数和SQL完全一样的情况下,我们使用同个SqlSession对象调用个Mapper方法,往往只执行...

    Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言。所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。

    补充说明:
    SqlSession的生命周期
    每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理作用域中,比如 Serlvet 架构中的 HttpSession。如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中。换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。下面的示例就是一个确保 SqlSession 关闭的标准模式:

    例子:

        /**     
        * 一级缓存 同一个sesion对象针对同一份数据的查询 产生的缓存     
        * * 第一次查询时 调用数据 获取数据后     
        * 通过session设置到一级缓存中    
        *  * 第二次查询时 通过session 一级缓存判断是否存在 相同主键的数据值 如果存在 直接返回引用 否则查询数据库     
        * * @throws Exception     */    
        private static List<Student> test1() throws Exception {
            StudentMapper mapper = DBTools.getSession().getMapper(StudentMapper.class);
            List<Student> students = mapper.studentList("11");
            List<Student> students1 = mapper.studentList("11");
            System.out.println(students == students1);
            return students;
        }
    
    

    以上例子可以看到,只要是在同一个Session并且条件相同的条件下,他就只会调用一次查询的sql

    为什么要使用一级缓存,不用多说也知道个大概。但是还有几个问题我们要注意一下。

    1、一级缓存的生命周期有多长?

    a、MyBatis在开启一个数据库会话时,会 创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象。Executor对象中持有一个新的PerpetualCache对象;当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。

    b、如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用。

    c、如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用。

    d、SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用

    2、怎么判断某两次查询是完全相同的查询?

    mybatis认为,对于两次查询,如果以下条件都完全一样,那么就认为它们是完全相同的两次查询。

    2.1 传入的statementId

    2.2 查询时要求的结果集中的结果范围

    2.3. 这次查询所产生的最终要传递给JDBC java.sql.Preparedstatement的Sql语句字符串(boundSql.getSql() )

    2.4 传递给java.sql.Statement要设置的参数值

    二级缓存:

    MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。

    MyBatis的缓存机制整体设计以及二级缓存的工作模式


    工作机制说明

    • 1.一个会话,查询一条数据,这个数据会被放在当前会话的一级缓存中。
    • 2,如果会话被关闭了,一级缓存中的数据会被保存带二级缓存。新的会话查询信息就会参照二级缓存。
    • 3.sqlSession > Employee>employee sqlSession >DepartmentMapper=>Department 不同的namespace查出的数据会放在自己对应的缓存中。

    效果:查出的数据首先放在一级缓存中,只有一级缓存被关闭或者提交以后,一级缓存数据才会转移到二级缓存

    SqlSessionFactory层面上的二级缓存默认是不开启的,二级缓存的开席需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。 也就是要求实现Serializable接口,配置方法很简单,只需要在映射XML文件配置就可以开启缓存了使用标签,如果我们配置了二级缓存就意味着:

    • 映射语句文件中的所有select语句将会被缓存。
    • 映射语句文件中的所欲insert、update和delete语句会刷新缓存。
    • 缓存会使用默认的Least Recently Used(LRU,最近最少使用的)算法来收回。
    • 根据时间表,比如No Flush Interval,(CNFI没有刷新间隔),缓存不会以任何时间顺序来刷新。
    • 缓存会存储列表集合或对象(无论查询方法返回什么)的1024个引用
    • 缓存会被视为是read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全的被调用者修改,不干扰其他调用者或线程所做的潜在修改。

    例子:

    一、创建一个POJO Bean并序列化

    由于二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样,所以需要给缓存的对象执行序列化。(如果存储在内存中的话,实测不序列化也可以的。)

    package cn.et.demo05.model;
    
    import java.io.Serializable;
    
    public class Student implements Serializable {
        private String id;
        private String name;
        private String age;
        private String sex;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    }
    

    二、在 mybatis.xml中开启二级缓存

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <settings>
            <!--这个配置使全局的映射器(二级缓存)启用或禁用缓存-->
            <setting name="cacheEnabled" value="true" />
            .....
        </settings>
        ....
    </configuration>
    

    三、在映射文件中开启二级缓存

    ** mybatis默认缓存类FifoCache
    FifoCache: 内存数据不足时 需要一种机制 保证内存不出现溢出 需要将旧的数据清除 最先插入的数据 最先清除
    LRU: 最近使用次数最少的 被优先清除
    LFU: 最近一段时间内使用次数最少
    eviction=“FIFO” 回收策略为先进先出
    flushInterval=“60000” 自动刷新时间60s
    size=“512” 最多缓存512个引用对象
    readOnly="true 只读**

    ** type 指定自己实现的cache的路径**

        <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="cn.et.demo05.mapper.StudentMapper">
            <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"
                   type="cn.et.demo05.mapper.RedisCache"></cache>
        </mapper>
    

    四、创建一个自己实现的cache类,在这里我们是通过redis进行缓存的

    package cn.et.demo05.mapper;
     
    import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
    import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
    import org.apache.ibatis.cache.Cache;
    import redis.clients.jedis.Jedis;
     
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
     
    public class RedisCache implements Cache {
        /**
         * 序列化
         * 封装一个方法 用来给对象写到redis里面
         * 	jedis.set(主键,objectTobyteArray(student对象))
         * @throws IOException
         */
        public static byte[] objectToByteArray(Object object) throws IOException {
            ByteOutputStream boss =new ByteOutputStream();
            ObjectOutputStream oos =new ObjectOutputStream(boss);
            oos.writeObject(object);
            return boss.getBytes();
        }
     
        /**
         * 反序列化
         * byte [] bt=get("主键")
         * student s =byteArrayToObject(bt)
         * 反序列化字节数组为对象
         * @throws IOException
         * @throws ClassNotFoundException
         */
        public static Object byteArrayToObject(byte[] bt) throws Exception{
            ByteInputStream bis =new ByteInputStream(bt,bt.length);
            ObjectInputStream ois =new ObjectInputStream(bis);
            return ois.readObject();
        }
     
        /**
         * 操作redis对象
         */
        Jedis jedis =new Jedis("localhost",6379);
     
    // 缓存的id
        private String cacheId;
     
    //  需要一个构造方法
        public RedisCache(String cacheId){
            this.cacheId=cacheId;
        }
     
     
        public String getId() {
            return cacheId;
        }
     
        /**
         * mybatis读取数据时 将数据库中读取的数据 通过putObject设置到缓存中
         */
        public void putObject(Object key, Object value) {
            try {
                //写入到redis 通过用byte数组的方式写入到redis
                jedis.set(objectToByteArray(key),objectToByteArray(value));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        /**
         * mybatis自动调用getObject检查是否缓存中存在
         */
        public Object getObject(Object key) {
            try {
                byte[] bs = jedis.get(objectToByteArray(key));
                if (bs==null) {
                    return null;
                }
                return byteArrayToObject(bs);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
     
        /**
         * mybatis缓存策略 自动判断内存大小,内存不够时,调用该方法,然后来决定删除一些过期或者久远的数据
         * @param key
         * @return
         */
        public Object removeObject(Object key) {
            Object object = getObject(key);
            try {
                jedis.del(objectToByteArray(key));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return object;
        }
     
    //  清空缓存 session被关闭的时候会调用这个方法 一般不要去清理他
        public void clear() {
    //        jedis.flushDB();
        }
     
    //  这个方法不会被调用
        public int getSize() {
            return 0;
        }
     
    //  二级缓存中的锁
        public ReadWriteLock getReadWriteLock() {
            return new ReentrantReadWriteLock();
        }
    }
    

    五、编写一个测试类

        /**
         * 二次缓存 同一个sessionFactory下的不同session 并且需要sqlSession1 close掉 可以共享数据,
         * @throws Exception
         */
        private static List<Student> test2()throws Exception{
            SqlSessionFactory sessionFactory = DBTools.getSessionFactory();
     
            SqlSession sqlSession1 = sessionFactory.openSession();
            StudentMapper mapper1 = sqlSession1.getMapper(StudentMapper.class);
            List<Student> student1 = mapper1.studentList("2");
            sqlSession1.close();
     
            SqlSession sqlSession2 = sessionFactory.openSession();
            StudentMapper mapper2 = sqlSession2.getMapper(StudentMapper.class);
            List<Student> student2 = mapper2.studentList("2");
     
     
            System.out.println(student1 == student2);
            return student1;
        }
    

    第一次他会去自己实现的cache类中调用getObject方法,查询redis里面是否有缓存,如果没有他会去调用一次sql语句去数据库里面查询出数据,然后调用setObject方法,给缓存写入到redis里面。

    运行效果:

    第二次调用效果:

    他会去调用getObject方法,发现redis里面有数据,然后就不会去数据库里面查询了,这样大大降低了数据库的压力

    展开全文
  • mysql一二级缓存

    2020-05-04 15:38:29
    sqlsession了,你可以理解为和数据库的次会话,但是sqlsession了**不是线程安全的,也就是他不能作为类的静态变量或者实例变量,最好的呢就是在方法中sqlsessionfactory.opensession(),然后和数据库会话完了呢...
  • hibernate二级缓存级缓存与二级缓存 1.hibernate级缓存 hibernate的级缓存是session级别的缓存,级缓存hibernate默认启用且不能被卸载,个事务内有效。 特点: 使用级缓存的目的是为了...
  • MyBatis 的级缓存和二级缓存

    千次阅读 2020-04-22 18:26:11
    文章目录、前言二、级缓存三、二级缓存3.1、开启二级缓存:四、测试一下五、总结: 、前言 先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,...
  • MyBatis的级缓存和二级缓存的区别

    千次阅读 2020-06-20 10:16:46
    一级缓存 ■ 两个级别 SqlSession级别的缓存,实现在同个会话中数据的共享 Statement级别的缓存,可以理解为缓存只对当前执行的这个Statement有效,执行完后就会清空缓存 ■ 一级缓存的生命周期和SqlSession...
  • MyBatis实战(5)缓存机制(级缓存、二级缓存

    千次阅读 多人点赞 2019-11-30 09:49:01
    这篇博客对Mybatis中的级缓存和二级缓存做了比较详细的阐述,并有完整的代码实现。
  • spring boot + mysql +mybatis +redis(二级缓存)实例------------------------------------------------------------
  • Mybatis级缓存与二级缓存

    千次阅读 2019-01-01 15:31:16
    mybatis的有两种缓存,级缓存和二级缓存。两个缓存的不同点和相同点总结如下 不同点: 级缓存存在于一个SqlSession之内,二级缓存存在于不同的SqlSession之间 级缓存不需要手动开启,属于默认开启状态;...
  • MyBatis中的级缓存和二级缓存介绍

    千次阅读 多人点赞 2017-06-13 20:07:22
    先说缓存,合理使用缓存是优化...一级缓存 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有个数据结构用于存储缓存数据。不同的sqlSession之间的缓存数据区域是互相不影响的。也
  • 前两天总结了一下二级缓存和查询缓存的关系,但是又有个新的问题,就是查询缓存缓存到二级缓存的数据,在第三次(第次缓存中没有数据,查询数据库将对应的ID值存入到二级缓存中去,第二次如果是同个Session...
  • 一级缓存:  也称本地缓存,sqlSession级别的缓存。一级缓存是一直开启的;与数据库同一次会话期间查询到的数据会放在本地缓存中。  如果需要获取相同的数据,直接从缓存中拿,不会再查数据库。  一级缓存失效...
  • mybatis 面试:级缓存和二级缓存

    千次阅读 2020-02-20 17:14:45
    其中级缓存默认是开启的,二级缓存是要手动配置开启的, 但是本人这里不建议在实际生产中用mybatis的缓存,还是建议在外部实现自己的缓存,如使用redis等; 级缓存 1:级缓存是默认开启的; 2:底层其实是基于...
  • 一、mybatis缓存基本介绍 1、缓存:将相同查询条件的sql...2、mybatis的查询缓存又分为一级缓存和二级缓存,一级缓存的作用范围为同一个sqlsession,而二级缓存的作用范围为同一个namespace和mapper。 二、一级缓...
  • 数据库,三级缓存详解

    千次阅读 2020-02-26 17:02:09
    一级缓存: 也称本地缓存,sqlSession级别的缓存。一级缓存是一直开启的;与数据库同次回话期间查询到的数据会放在本地缓存中。 如果需要获取相同的数据,直接从缓存中拿,不会再查数据库。 一级缓存失效的四种...
  • SpringBoot+Mybatis整合Redis做MySQL二级缓存次接触Redis有说的不对的地方欢迎大家指正,代码亲测可以食用。文章是在vscode中用markdown插件写完的,后来想想还是发在csdn上吧,就直接站题过来了,排版或者...
  • 级缓存测试: // 级缓存默认开启,二级缓存的开启需要配置 // 级缓存的作用域:当前session @Test public void test1() { StuInfoMapper stuMapper = sqlSession.getMapper(StuInfoMapper.class); StuInfo ...
  • 文章目录MyBatis缓存机制Spring+MyBatis开启二级缓存1. 创建MyBatis核心配置文件,在settings中开启二级缓存2. 在spring的核心配置文件中,sqlSessionFactory的bean中,将mybatis的配置粘入3. 在mapper.xml映射文件...
  • MyBatis二级缓存 MySql缓存机制MyBatis级缓存MyBatis级缓存是sesssion会话级别的缓存,是基于当前SqlSession对象的,MyBatis级缓存实际上是以当前sql为key对执行语句进行缓存(跟mysql缓存一样,修改任何参数的...
  • 像大多数的持久化框架一样,Mybatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能 Mybatis 中缓存分为级缓存,二级缓存 Mybatis 级缓存 Mybatis 二级缓存 ...
  • 前言 现在的JAVA行业,貌似已经是...之前整合过了springboot+mybatis,前几天看到个面试的问个问题,Mybatis的级缓存,二级缓存。我想这个应该也是个重点吧,所以今天决定来详细解读一下神秘的一二级缓存
  • MyBatis级缓存和二级缓存使用场景和失效策略 级缓存: 默认为级缓存,作用域为SqlSessison,基于PerpetualCache的HashMap本地缓存。 实现方式:mysql次去数据库查数据的时候会往sqlsession里面写份,第...
  • 一级缓存 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有个数据结构用于存储缓存数据。不同的sqlSession之间的缓存数据区域是互相不影响的。也就是他只能作用在同个...
  • 一级缓存 Mybatis的一级缓存存放在SqlSession的生命周期,在同个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入个Map对象中。 如果同个SqlSession中执行...
  • Mybatis中级缓存和二级缓存的区别

    千次阅读 2019-09-18 21:52:48
    一级缓存 mybatis默认是一级缓存 一级缓存指的就是Session缓存,也就是在同个SqlSession中,不同的sqlSession中的缓存是互相不能读取的。 第次在database中查询会保存在缓存中,第次或者n次都是在缓存中获取 ...
  • mybaits级缓存和二级缓存的实现

    千次阅读 2018-12-10 20:32:00
    近来看了一下关于mybaits的一些缓存讲解的文章,然后自己也顺着文章看了一下mybaits底层的源码。 (本文部分内容转载于美团的 聊聊MyBatis缓存...首先谈的肯定是mybaits的工作原理,大家都知道mybaits有一级缓存和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 129,911
精华内容 51,964
关键字:

mysql一级缓存二级缓存

mysql 订阅
友情链接: draft_of_ECMA368ECMA369.rar