首页 > 编程知识 正文

hibernate二级缓存机制(hibernate二级缓存配置)

时间:2023-05-04 12:09:14 阅读:71634 作者:366

区别:

1.Hibernate是全自动ORM映射工具,使用Hibernate查询相关对象或相关集合对象时,可以直接基于对象关系模型获取,因此是全自动的。 在查询相关对象或相关集合对象时,MyBatis必须手动编写sql。 但是,MyBatis可以灵活地配置在XML或注释中执行的sql语句,将java对象映射到sql语句以生成最终执行的sql,最后重新映射sql执行的结果以生成java对象。 这是半自动ORM映射工具。

2.Mybatis学习门槛低,简单易学,非常适合程序员直接编写原生态sql,能够严格控制sql的执行性能,灵活性强,对关系数据模型要求不高的软件开发,如进但是,mybatis假定不能实现数据库无关性,如果需要实现支持多个数据库的软件,则需要定制多个sql映射文件,这将导致工作量巨大。

3 .如果在hibernate上开发hibernate对象/关系映射能力强、数据库无关性好、对关系模型要求高的软件(例如需求固定的定制软件) 因此,他的数据库可移植性很好,Mybatis必须更换数据库,大幅修改许多sql语句。 但是,Hibernate的缺点是学习门槛高,门槛更高,熟悉如何设计O/R映射。

原文链接: https://blog.csdn.net/banzuanhu/article/details/110201816

一级缓存(内置缓存均默认打开)1:一级缓存默认打开

2 )基础实际上是基于hashmap的本地内存缓存

3 )作用域是session (其实应该是一个方法中更准确地说是与一个数据库的会话,一个方法提交两次事务后会出现两个session吗? );

4 )会话关闭或刷新时缓存为空

5 )不同sqlsession或hibernatesession之间的缓存互不影响,线程独占共享;

导致的问题

数据一致性问题:

例如,对同一数据有更新操作。

如果sqlsessionA执行更新操作,与sqlsessionA对应的1级缓存将为空。是否存在疑问? sqlsessionA应该首先执行查询操作,并且一级缓存不为空。 然后,在sqlsessionB更新操作之后,sqlsessionA是否再次查询数据不一致性? 稍后测试)

如果sqlsessionB执行了更新操作,则此更新操作不会显示在sqlsessionA中。

其实此时sqlsessionA复检的数据是过期的失效数据

发生数据不匹配建议

1 )单个sqlsession的生命周期不能太长;

2 )对同一语句的更新尽量使用相同的sql,即相同的sqlsession时

3 :建议关闭L1缓存。

Hibernate一级缓存是HibernateSession,session,字面上的对话。 这里显示了APP应用程序和数据库之间的交互(会话)。

因此,除非第一个查询需要运行select的sql,否则在每次交互过程中,如果涉及对同一对象的查询(代码中有几个位置可以查询名为" mldrjb "的数据)

语句查询数据库,然后直接从缓存中检索数据,而无需执行sql语句。

代码验证:

//证明主缓存存在@ testpublicvoidtest2({ session session=hibernate utils.getsession ); session对象的session.beginTransaction (); 获取goods1对象时,主缓存中没有数据,因此发送SQL语句并查询数据库内容的GoodsGoods1=(Goods ) session.get ) Goods.class,1 ); system.out.println(goodS1; 获取goods2对象时,不发出SQL语句,而是从会话缓存获取数据GoodsGoods2=(Goods ) session.get ) Goods.class,1 ); session.getTransaction ().commit ),根据//id从缓存中获取对象system.out.println(Goods2); session.close (; }会话缓存什么时候清理?

1,commit ) )方法被调用时。 因为提交表示与此数据库的会话已完成,并且不会重用。

2 )查询时清除缓存,保证查询结果反映对象的最新状态。

3,调用显示的session的flush方法区域清除缓存。

会话清理缓存的特殊情况:

当对象使用native生成器时,缓存将立即清理并在数据库中插入记录。

Mybatis缓存SqlSessio也是如此

demo包括

>

@Test
    public void test1(){
        InputStream is = TestUser.class.getClassLoader().getResourceAsStream("application.xml");

        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

        SqlSession sqlSession = sqlSessionFactory.openSession();

        System.out.println("===========================================");
        User user1 = sqlSession.selectOne("getUserById",1001);
        System.out.println(user1);
        System.out.println("===========================================");
        User user2 = sqlSession.selectOne("getUserById",1001);
        System.out.println(user2);
        System.out.println("===========================================");
        sqlSession.close();
    }
 

 从打印的sql来看,在同一个SqlSession中,查询2次相同的数据时(实际上是通过mapper.xml找到的同一条sql语句),只会在第一次查询时,打印出一次sql,后面就从缓存直接拿了。这就是一级缓存的作用 。

可以通过mapper.xml中标签属性屏蔽一级缓存:flushCache="true" (默认是false,意为不清除缓存,也就是开启一级缓存的意思)具体如下:

 

对比:Hibernate一级缓存,判断是否相同数据是根据缓存里 的对象id,如果是hibernate

通过hql语句或者sql语句去查询,则一级缓存没有起作用,还是每次都会执行查询。、

而Mybatis一级缓存,,是通过sql来判断是否为相同数据,也就是如果2次的sql语句一致,第二次就直接从缓存里拿。(当然前提也是在一次事务会话,事务提交后缓存也就清楚了,当然也可以手动清除缓存,和hibernate几乎一样的道理)

具体可以参考

https://blog.csdn.net/chengqiuming/article/details/100179998

 

二级缓存(外置缓存,都是默认关闭)

默认情况下默认也是采用 PerpetualCache,HashMap存储,SessionFactory 不会启用这个缓存插件,外置缓存中的数据是数据库数据的复制(可以缓存整个数据库?),外置缓存的物理介质可以是内存或硬盘。

二级缓存被多个SqlSession或HibernateSession共享,是一个全局的变量,线程共享,存在于SessionFactory的生命周期,是由SessionFactory管理的?

二级缓存坑的地方:

Mybatis:

你在OrderMapper.XML 和 UserMapp.XML的文件 都操作了User表的话,

会撒娇的魔镜使用OrderMapper.XML的SQL更新User表的时候,其他的SeqSession在OrderMapper.XML可以查到User表最新的数据,但是在UserMapp.XML查不到最新的数据

原因就是 二级缓存是基于某个XXXMapper.xml,每个Mapper直接独立,所以 不同Mapper操作同一张表的时候 (哪怕执行的是同一条sql,也要区分多个缓存对象?一级缓存也会吗??), 使用二级缓存会造成脏读

这也就是没什么人开启二级缓存的主要原因
原文链接:https://blog.csdn.net/weixin_35910783/article/details/113679318

 

当然二级缓存也不建议使用,mysql都默认关闭了,更何况我们呢。

缓存建议使用redis,mamcache等

 

 

参考:原文链接:https://blog.csdn.net/u010953880/article/details/104412646

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。