当前位置: 首页 > news >正文

Hibernate的FlushMode

一、Session中FlushMode的设置:

在事务开启前设置FlushMode属性,方法:

// session.setFlushMode(FlushMode.Always|AUTO|COMMIT|NEVER|MANUAL)。@Service
public class TestService {Logger log = LoggerFactory.getLogger(getClass());@AutowiredEntityManager entityManager;public FlushModeType getFlushModeType() { // entityManager.setFlushMode(FlushModeType.AUTO);       return entityManager.getFlushMode();}
}

SpringBoot 中 application.yml 配置: 

spring:jpa:properties:org:hibernate:# FlushMode#   ALWAYS 和 AUTO的区别:#   当hibernate缓存中的对象被改动之后, 会被标记为脏数据(即与数据库不同步了)。#   当 session设置为FlushMode.AUTO时, hibernate 在进行查询的时候会判断缓存中的数据是否为脏数据,#   是则刷数据库, 不是则不刷, 而always是直接刷新, 不进行任何判断。很显然 auto 比 always 要高效得多。#   ALWAYS: 每次进行查询、提交事务、session.flush()的时候都会刷数据库#   AUTO: 设置成auto之后, 当程序进行查询、提交事务或者调用session.flush()的时候, 都会使缓存和数据库进行同步, 也就是刷新数据库#   COMMIT: 提交事务或者session.flush()时, 刷新数据库;查询不刷新#   MANUAL: 如果FlushMode是MANUAL或NEVEL, 在操作过程中hibernate会将事务设置为readonly, 所以在增加、删除或修改操作过程中会出现错误#   NEVER: 已经废弃了, 被MANUAL取代了flushMode: AUTO

FlushMode有5个值可选:

1  NEVEL   

已经废弃了,被MANUAL取代了

2 MANUAL 

spring3.x中的opensessioninviewfilter已经将默认的FlushMode设置为MANUAL了;如果FlushMode是MANUAL或NEVEL,在操作过程中hibernate会将事务设置为readonly,所以在 增加、删除或修改 操作过程中会出现如下错误:
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read - only mode (FlushMode.NEVER)  -  turn your Session into FlushMode.AUTO or remove  ' readOnly '  marker from transaction definition;解决办法网上有很多;1 配置事务,spring会读取事务中的各种配置来覆盖hibernate的session中的FlushMode;2 先编程式修改FlushMode,比如session.setFlushMode(FlushMode.AUTO); 这样hibernate就会自动去除readonly限制;3 直接修改opensessioninviewfilter过滤器的配置,配置过滤器的时候配置
<filter><filter-name>openSession</filter-name><filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class><init-param><param-name>flushMode</param-name><param-value>AUTO</param-value></init-param></filter>

3 AUTO

设置成auto之后,当程序进行查询、提交事务或者调用session.flush()的时候,都会使缓存和数据库进行同步,也就是刷新数据库

4 COMMIT

提交事务或者session.flush()时,刷新数据库;查询不刷新

5 ALWAYS

每次进行查询、提交事务、session.flush()的时候都会刷数据库
这里需要说一下和AUTO的区别,当hibernate缓存中的对象被改动之后,会被标记为脏数据(即与数据库不同步了)。当session设置为FlushMode.AUTO时,hibernate在进行查询的时候会判断缓存中的数据是否为脏数据,是则刷数据库,不是则不刷,而always是直接刷新,不进行任何判断。很显然auto比always要高效得多。

JPA的FlushModeType只有两种:

1、COMMIT:仅当提交事务时才能进行刷新

2、AUTO:(默认)在执行查询时进行刷新

二、Session中flush()方法说明:

可以强制进行从内存到数据库的同步,方法session.flush()

例: 

/** * flush 强制与数据库同步 */  
@Test  
public void testFlush(){  Session session =  HibernateUitl.getSessionFactory().getCurrentSession();  session.beginTransaction();  Teacher t = (Teacher) session.get(Teacher.class, 3);  t.setName("yyy");  t.setName("yyyyy");  session.getTransaction().commit();  
}  

看这段代码,我们setName() 2次, 但程序只会更改数据库一次,在commit时。

/** * flush 强制与数据库同步 */  
@Test 
public void testFlush(){  Session session =  HibernateUitl.getSessionFactory().getCurrentSession();  session.beginTransaction();  Teacher t = (Teacher) session.get(Teacher.class, 3);  t.setName("yyy");  session.flush();//有flush会执行2次UPDAE,没有会只执行一次  t.setName("yyyyy");  session.getTransaction().commit();  
}  

我们在第2次setName()时 执行session.flush()

再看hibernate 执行的sql 语句

Hibernate: updateTeacher setbirthday=?,name=?,title=? whereid=?
Hibernate: updateTeacher setbirthday=?,name=?,title=? whereid=?

执行了2次Update

所以看出来flush方法会强制与数据库同步。

flush方法是可以设置的,也就是fulsh什么时候执行是可以设置的(第一条有说明)。

二、Session中Clear()方法说明:

无论是 Load 还是 Get 都会首先查找缓存(一级缓存) 如果没有,才会去数据库查找,调用Clear() 方法,可以强制清除Session缓存。

例:

public void testClear(){  Session session =  HibernateUitl.getSessionFactory().getCurrentSession();  session.beginTransaction();  Teacher t = (Teacher) session.get(Teacher.class, 3);  System.out.println(t.getName());  Teacher t2 = (Teacher) session.get(Teacher.class, 3);  System.out.println(t2.getName());  session.getTransaction().commit();  
}  

这里虽然用了2个get方法(get方法会立即执行sql语句),但因为第一次执行了会缓存一个ID为3的实体,所以虽然有2个get方法只执行一次SQL语句。

public void testClear(){  Session session =  HibernateUitl.getSessionFactory().getCurrentSession();  session.beginTransaction();  Teacher t = (Teacher) session.get(Teacher.class, 3);  System.out.println(t.getName());  session.clear();//这里不clear只会执行一次sql语句,有clear会执行2次  Teacher t2 = (Teacher) session.get(Teacher.class, 3);  System.out.println(t2.getName());  session.getTransaction().commit();  
}  

这里在第2次get前执行session.clear(), 我们把 hibernate show_sql 出来,它就会执行2次sql语句了。

所以session.clear()会清除缓存。

http://www.lryc.cn/news/89260.html

相关文章:

  • 二线程序员的出路
  • MKS SERVO4257D 闭环步进电机_系列2 菜单说明
  • 使用Actor-Critic的DDPG强化学习算法控制双关节机械臂
  • 黑马学生入职B站1年,晒出21K月薪:我想跳槽华为
  • 一文看懂GPT风口,都有哪些创业机会?
  • chatgpt赋能python:Python中的不确定尾数问题
  • 杜绝开源依赖风险,许可证扫描让高效合规「两不误」
  • 【sop】含储能及sop的多时段配网优化模型
  • nodjs使用阿里云镜像安装
  • C++ Primer Plus 第二章习题
  • 两分钟学会 制作自己的浏览器 —— 并将 ChatGPT 接入
  • HEVC中,mvd怎么写进码流的?
  • 隐形黑客潜入美国和关岛关键基础设施而未被发现
  • 设计模式—“接口隔离”
  • 【C++学习】异常
  • 如何理解TCP是面向字节流协议?
  • 机器学习期末复习 线性模型
  • Worker及XMLHttpRequest简单使用说明
  • 零基础如何入门网络安全?2023年专业学习路线看这篇就够了
  • 《操作系统》by李治军 | 实验5.pre - switch_to 汇编代码详解
  • c++11基础
  • Linux:centos:修改临时ip永久ip
  • 如何真正开启docker远程访问2375
  • nodejs连接mysql
  • 异构跨库数据同步还在用Datax?来看看这几个开源的同步方案
  • msvcp140.dll丢失怎么办?msvcp140.dll重新安装的解决方法
  • mysql超全语法大全
  • 【VR】手柄定位技术
  • TDengine 启动 taosAdapter,提供基于6041端口的RESTful 接口,建立REST 连接
  • SY8205同步降压DCDC可调电源模块(原理图和PCB)