`

Hibernate的clear(),flush(),evict()方法详解 .(转)

 
阅读更多

1.Clear 方法

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

例:

  1. public void testClear(){  
  2.         Session session =  HibernateUitl.getSessionFactory().getCurrentSession();  
  3.         session.beginTransaction();  
  4.         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();  
  •     }  

 

<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

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

 

  1. public void testClear(){  
  2.         Session session =  HibernateUitl.getSessionFactory().getCurrentSession();  
  3.         session.beginTransaction();  
  4.         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();  
  •     }  

 

<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

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

 

2.Flush方法

      可以强制进行从内存到数据库的同步。

例:

  1. @Test  
  2.     /** 

  •      * flush 强制与数据库同步 
  •      */  
  •     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();  
  •     }  

 

<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

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

 

  1. @Test  
  2.     /** 

  •      * flush 强制与数据库同步 
  •      */  
  •     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();  
  •     }  

 

<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

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

 

再看hibernate  执行的 sql  语句

  1. Hibernate:   
  2.     update  
  3.         Teacher   
  4.     set  

  •         birthday=?,  
  •         name=?,  
  •         title=?   
  •     where  
  •         id=?  
  • Hibernate:   
  •     update  
  •         Teacher   
  •     set  
  •         birthday=?,  
  •         name=?,  
  •         title=?   
  •     where  
  •         id=?  

 

<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

执行了2 Update

 

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

 

 

 

 

Flush方法是可以设置的,也就是 fulsh 什么时候执行是可以设置的

 

 在session.beginTransaction 前设置 FlushMode

 

session.setFlushMode(FlushMode.Always|AUTO|COMMIT|NEVER|MANUAL)

 

FlushMode 5 个值可选

Always:任何代码都会 Flush
AUTO:默认方式 自动
Commit:COMMIT
Never:始终不
MANUAL:手动方式

 

设置FlushMode  有个好处是可以节省开销,比如默认 session 只做查询时,就可以不让他与数据库同步了。

 

<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

session.evict(obj) :会把指定的缓冲对象进行清除。

  session.clear() :把缓冲区内的全部对象清除,但不包括操作中的对象。

  Hibernate 执行的顺序如下:
 (1) 生成一个事务的对象,并标记当前的 Session 处于事务状态(注:此时并未启动数据库级事务)。
 (2) 应用使用 s.save 保存对象,这个时候 Session 将这个对象放入 entityEntries ,用来标记对象已经和当前的会话建立了关联,由于应用对对象做了保存的操作, Session 还要在 insertions 中登记应用的这个插入行为(行为包括:对象引用、对象 id Session 、持久化处理类)。
 (3)s.evict 将对象从 s 会话中拆离,这时 s 会从 entityEntries 中将这个对象移出。
 (4) 事务提交,需要将所有缓存 flush 入数据库, Session 启动一个事务,并按照 insert,update,……,delete 的顺序提交所有之前登记的操作(注意:所有 insert 执行完毕后才会执行 update ,这里的特殊处理也可能会将你的程序搞得一团糟,如需要控制操作的执行顺序,要善于使用 flush ),现在对象不在 entityEntries 中,但在执行 insert 的行为时只需要访问 insertions 就足够了,所以此时不会有任何的异常。异常出现在插入后通知 Session 该对象已经插入完毕这个步骤上,这个步骤中需要将 entityEntries 中对象的 existsInDatabase 标志置为 true ,由于对象并不存在于 entityEntries 中,此时 Hibernate 就认为 insertions entityEntries 可能因为线程安全的问题产生了不同步(也不知道 Hibernate 的开发者是否考虑到例子中的处理方式,如果没有的话,这也许算是一个 bug 吧),于是一个 net.sf.hibernate.AssertionFailure 就被抛出,程序终止。

         一般我们会错误的认为 s.save 会立即执行,而将对象过早的与 Session 拆离,造成了 Session insertions entityEntries 中内容的不同步。所以我们在做此类操作时一定要清楚 Hibernate 什么时候会将数据 flush 入数据库,在未 flush 之前不要将已进行操作的对象从 Session 上拆离。解决办法是在 save 之后,添加 session.flush

分享到:
评论

相关推荐

    Hibernate中get和load方法的区别以及close(),clear()、evict()等的区别

    本文主要讨论了`get`、`load`方法以及`flush`、`clear`、`evict`等方法的区别。 首先,让我们关注`get`和`load`的区别: 1. **返回结果对比**: - `load`方法如果找不到对应的记录,会抛出`org.hibernate....

    hibernate的flush机制

    ### Hibernate的Flush机制详解 #### 引言 Hibernate作为Java领域中最流行的ORM(Object-Relational Mapping)框架之一,极大地简化了数据访问层的开发工作,使得开发者能够更专注于业务逻辑而非底层的数据交互细节...

    hibernate的flush()、refresh()、clear()针对一级缓存的操作的区别.docx

    2. `session.clear()`: 这个方法的作用是清空Session的一级缓存,包括所有缓存的对象和它们的状态。执行`clear()`后,Session不再跟踪任何对象,即使这些对象之前已经被加载或修改。这意味着,如果之后试图操作这些...

    关于flush和evict

    ### 关于flush和evict在Hibernate中的应用 #### 一、引言 在持久层框架Hibernate中,`flush()`和`evict()`方法是开发者在处理数据时经常会遇到的两个重要概念。它们对于理解Hibernate的工作机制及其缓存管理至关...

    hibernate中evict()和clear()的区别.docx

    相反,`session.clear()`方法是清除整个Session缓存,包括所有的对象。但是,这里有一个重要的区别:`clear()`方法不会影响正在处理的对象,也就是说,如果某个对象正处于持久化操作(如save、update)的过程中,...

    Hibernate的事务处理机制和flush方法的用法.docx

    在使用Hibernate进行数据库操作时,事务管理和`flush`方法的正确使用至关重要,因为它们直接影响到数据的一致性和安全性。在本文中,我们将深入探讨Hibernate的事务处理机制以及`flush`方法的用法,并分析为何在某些...

    hibernate-release-5.0.7.Final.zip官方

    session.clear(); } } tx.commit(); } catch (Exception e) { if (tx != null) tx.rollback(); e.printStackTrace(); } finally { session.close(); } ``` #### 五、常见问题解答 **Q: 如何解决 ...

    hibernate_flush 深入了解

    本文将深入探讨Hibernate的Flush过程,以及它如何与数据库事务和隔离级别相互作用。 首先,我们需要明确什么是Hibernate的Flush操作。Flush是Hibernate将内存中的对象状态同步到数据库的过程。当Session中的对象被...

    hibernate-release-5.4.17.Final.zip

    《Hibernate 5.4.17.Final:官方版本详解及应用实践》 Hibernate,作为Java领域中的一个著名对象关系映射(ORM)框架,极大地简化了数据库操作,使得开发者可以更加专注于业务逻辑而非繁琐的SQL语法。在本文中,...

    浅析Hibernate下数据批量处理方法.doc

    标题"浅析Hibernate下数据批量处理方法"和描述中提到,早期的Hibernate在批量插入时可能存在效率问题,但最新版本已经进行了优化,例如通过设置`batch_size`参数来提高批量处理的性能。`batch_size`设置的是JDBC...

    hibernate的session.flush

    `Session.flush()`方法是一个关键的操作,它强制Hibernate将内存中的对象状态同步到数据库,确保数据的一致性。这篇博客深入探讨了`Session.flush()`的工作原理和应用场景。 `Session`在Hibernate中主要有以下职责...

    hibernate.properties

    #hibernate.transaction.flush_before_completion ## Enable automatic session close at the end of transaction ## (This setting is relevant with or without the Transaction API) #hibernate.transaction....

    flush-sh4.rar_back

    标题“flush-sh4.rar_back”和描述“Write back the dirty D-caches, but not invalidate them.”涉及的是计算机系统中的缓存管理技术,特别是与数据缓存(D-cache)的刷新和有效性相关的概念。这里我们将深入探讨这...

    hibernate-5.2.15. 最新jar包

    在业务逻辑处理中,通常使用Session的beginTransaction、save/merge、flush和commit等方法来完成数据库操作。 3. **Query和Criteria API**:提供两种方式执行查询,一是HQL(Hibernate Query Language),类似于SQL...

    php-flush功能火狐无效.doc

    php-flush功能火狐无效.doc

    Hibernate Session 4种对象状态.docx

    - 第二个`testSave()`方法试图在save()之前为对象赋ID,这在Hibernate中是无效的,因为ID由Hibernate自动管理。 - 第三个`testSave()`尝试在对象已经持久化后修改ID,这是不允许的,因为它违反了数据库的唯一性约束...

    hibernate-release-5.1.16.Final.zip

    《Hibernate 5.1.16.Final框架详解与应用》 Hibernate,作为一个成熟的Java对象关系映射(ORM)框架,极大地简化了数据库操作,它将数据库操作转换为对Java对象的操作,使得开发者可以更加专注于业务逻辑。在本文中...

    Hibernate5.0用户手册中文版本.docx

    - **刷新实体状态**:为了同步数据库中的最新状态,可以使用`flush`方法。 - **变更对象状态**:对象在Hibernate中可以处于不同的状态,如游离态、托管态或持久态。开发人员需要理解这些状态及其转换,以确保正确的...

    42grant之后要跟着flush privileges吗?.pptx

    42grant之后要跟着flush privileges吗?.pptx

    hibernate各种常用方法的详解

    ### Hibernate 常用方法详解 #### 一、前言 Hibernate 是一款强大的对象关系映射(ORM)框架,它简化了 Java 应用程序与数据库之间的交互过程。本文将详细介绍 Hibernate 中常用的几种方法,包括 `save`, `update`...

Global site tag (gtag.js) - Google Analytics