Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 388|回复: 0

MyBatis的一级缓存、二级缓存演示以及讲解,序列化异常的处理

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-5 10:13:31 | 显示全部楼层 |阅读模式

    MyBatis的缓存机制

    缓存就是内存中的一个空间,通常用来提高查询效率

    MyBatis支持两种缓存技术:一级缓存和二级缓存,其中一级缓存默认开启,二级缓存默认关闭

    一级缓存

    (1)一级缓存默认开启

    (2)是一种基于SqlSession的缓存,同一个SqlSession有效,不同的SqlSession无效

    (3)同一个id,可以走缓存;不同id,即使查询的内容相同,也不会走缓存

    //加载核心配置文件
    InputStream is = Resources.getResourceAsStream("mybatis-cfg.xml");
    //基于构建者创建工厂对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //通过工厂创建sqlSession对象:测试一级缓存
    //第一次查询
    SqlSession sqlSession1 = factory.openSession();
    List<User> list1 = sqlSession1.selectList("selAll1");
    System.out.println(list1);
    System.out.println("*************************");
    //第二次查询
    List<User> list2 = sqlSession1.selectList("selAll1");
    System.out.println(list2);
    sqlSession1.close();
    

      

    //加载核心配置文件
    InputStream is = Resources.getResourceAsStream("mybatis-cfg.xml");
    //基于构建者创建工厂对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //通过工厂创建sqlSession对象:测试一级缓存
    SqlSession sqlSession1 = factory.openSession();
    List<User> list1 = sqlSession1.selectList("selAll1");
    System.out.println(list1);
    System.out.println("***********不同id,即使内容相同,也不走缓存**************");
    List<User> list2 = sqlSession1.selectList("selAll2");
    System.out.println(list2);
    sqlSession1.close();
    

      

    //加载核心配置文件
            InputStream is = Resources.getResourceAsStream("mybatis-cfg.xml");
            //基于构建者创建工厂对象
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            //通过工厂创建sqlSession对象:测试一级缓存
            SqlSession sqlSession1 = factory.openSession();
            List<User> list1 = sqlSession1.selectList("selAll1");
            System.out.println(list1);
    //        sqlSession1.close();
            System.out.println("***********不是同一个sqlSession,不会走缓存**************");
            SqlSession sqlSession2 = factory.openSession();
            List<User> list2 = sqlSession2.selectList("selAll1");
    //        System.out.println(list2);
    

      

    二级缓存

    (1)二级缓存默认关闭

    (2)是一种基于SqlSessionFactory的缓存,同一个工厂创建的SqlSession有效,不同工厂则无效

    (3)需要使用时,应在指定的namespace下进行开启

    (4)<cache>标签的属性

      eviction:缓存清除策略,常用的有LRU、FIFO、SOFT、WEAK

      flushInterval:刷新间隔,需要给定一个毫秒数,表示指定时间间隔时,会自动刷新缓存

      size:设置大小,默认是1024

      readOnly:是否只读(不写入文件),默认是false,需要实体类实现序列化接口

      type:用于自定义缓存机制,提供一个自定义类的全限定路径,自定义类需要实现CaChe接口

     

    //加载核心配置文件
    InputStream is = Resources.getResourceAsStream("mybatis-cfg.xml");
    //基于构建者创建工厂对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //通过工厂创建sqlSession对象:测试二级缓存
    SqlSession sqlSession1 = factory.openSession();
    
    List<User> list1 = sqlSession1.selectList("selAll1");
    System.out.println(list1);
    sqlSession1.close();
    
    System.out.println("***********同一个工厂的sqlSession,会走缓存**************");
    SqlSession sqlSession2 = factory.openSession();
    List<User> list2 = sqlSession2.selectList("selAll1");
    System.out.println(list2);
    

      

    “cache hit ratio”中文意思是“缓存命中率”。

    这是一个计算机术语,终端用户访问加速节点时,如果该节点有缓存住了要被访问的数据时就叫做命中,如果没有的话需要回原服务器取,就是没有命中。

    序列化问题:

    //加载核心配置文件
    InputStream is = Resources.getResourceAsStream("mybatis-cfg.xml");
    //基于构建者创建工厂对象
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
    //通过工厂创建sqlSession对象:测试二级缓存
    SqlSession sqlSession1 = factory.openSession();
    
    List<User> list1 = sqlSession1.selectList("selAll1");
    System.out.println(list1);
    sqlSession1.close();
    

      

    原因分析:

    User实现类未实现序列化

    为什么要实现序列化:

    (1)缓存机制:将查询结果保存到内存中

    (2)内存饱满,需要移出时,MyBatis就会自动将内存中的内容进行移除,但是文件很重要,不能,此时就需要进行序列化,以文件的形式将内容从内存保存到硬盘上,一个内容保存成文件的读写,必须实现序列化。

    解决方案:

    一:User实体类实现序列化

    二:在<cache>标签中添加readOnly属性

    表示:要求Mybatis对缓存内容只读不写,当需要移除的时候,直接删除,不需要进行转存。

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-1 09:55 , Processed in 0.066611 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表