`

session --------- flush() 和 evict()

阅读更多
session flush方法主要做了两件事:
* 清理缓存
* 执行sql

session在什么情况下执行flush
* 默认在事务提交时
* 显示的调用flush
* 在执行查询前,如:iterate

hibernate按照save(insert),update、delete顺序提交相关操作



/**
	 * 测试uuid主键生成策略
	 */
	public void testSave1() {
		Session session = null;
		Transaction tx = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();

			User1 user = new User1();
			user.setName("李四");
			user.setPassword("123");
			user.setCreateTime(new Date());
			user.setExpireTime(new Date());
			
			//因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理
			//不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false
			session.save(user);
			
			//调用flush,hibernate会清理缓存,执行sql
			//如果数据库的隔离级别设置为为提交读,那么我们可以看到flush过的数据
			//并且session中existsInDatebase状态为true
			session.flush();
			
			//提交事务
			//默认情况下commit操作会先执行flush清理缓存,所以不用显示的调用flush
			//commit后数据是无法回滚的
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 测试native主键生成策略
	 */
	public void testSave2() {
		Session session = null;
		Transaction tx = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();

			User2 user = new User2();
			user.setName("张三1");
			user.setPassword("123");
			user.setCreateTime(new Date());
			user.setExpireTime(new Date());
			
			//因为user的主键生成策略为native,所以调用session.save后,将执行insert语句,返回有数据库生成的id
			//纳入了session的管理,修改了session中existsInDatebase状态为true
			//如果数据库的隔离级别设置为为提交读,那么我们可以看到save过的数据
			session.save(user);
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	
	/**
	 * 测试uuid主键生成策略
	 */
	public void testSave3() {
		Session session = null;
		Transaction tx = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();

			User1 user = new User1();
			user.setName("王五");
			user.setPassword("123");
			user.setCreateTime(new Date());
			user.setExpireTime(new Date());
			
			//因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理
			//不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false
			session.save(user);
			
			//将user对象从session中逐出,即session的EntityEntries属性中逐出
			session.evict(user);
			
			//无法成功提交,因为hibernate在清理缓存时,在session的insertions集合中取出user对象进行insert操作后
			//需要更新entityEntries属性中的existsInDatabase为true,而我们采用evict已经将user从session的entityEntries
			//中逐出了,所以找不到相关数据,无法更新,抛出异常
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 测试uuid主键生成策略
	 */
	public void testSave4() {
		Session session = null;
		Transaction tx = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();

			User1 user = new User1();
			user.setName("王五");
			user.setPassword("123");
			user.setCreateTime(new Date());
			user.setExpireTime(new Date());
			
			//因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理
			//不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false
			session.save(user);
			
			//flush后hibernate会清理缓存,会将user对象保存到数据库中,将session中的insertions中的user对象
			//清除,并且设置session中existsInDatebase的状态为true
			session.flush();
			
			//将user对象从session中逐出,即session的EntityEntries属性中逐出
			session.evict(user);
			
			//可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到user对象
			//所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 测试native主键生成策略
	 */
	public void testSave5() {
		Session session = null;
		Transaction tx = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();

			User2 user = new User2();
			user.setName("张三11");
			user.setPassword("123");
			user.setCreateTime(new Date());
			user.setExpireTime(new Date());
			
			//因为user的主键生成策略为native,所以调用session.save后,将执行insert语句,返回有数据库生成的id
			//纳入了session的管理,修改了session中existsInDatebase状态为true
			//如果数据库的隔离级别设置为为提交读,那么我们可以看到save过的数据
			session.save(user);
			
			//将user对象从session中逐出,即session的EntityEntries属性中逐出
			session.evict(user);
			
			//可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到user对象
			//所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 测试assigned主键生成策略
	 * 
	 */
	public void testSave6() {
		Session session = null;
		Transaction tx = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();

			User3 user = new User3();
			user.setId("001");
			user.setName("张三");
			
			session.save(user);
			
			user.setName("王五");
			session.update(user);
			
			User3 user3 = new User3();
			user3.setId("002");
			user3.setName("李四");
			session.save(user3);
			
			//Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)
			//Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)
			//Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?
			//hibernate按照save(insert),update、delete顺序提交相关操作
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}	
	
	/**
	 * 测试assigned主键生成策略
	 * 
	 */
	public void testSave7() {
		Session session = null;
		Transaction tx = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();

			User3 user = new User3();
			user.setId("003");
			user.setName("张三");
			
			session.save(user);
			
			user.setName("王五");
			session.update(user);
			
			session.flush();
			
			User3 user3 = new User3();
			user3.setId("004");
			user3.setName("李四");
			session.save(user3);
			
			//Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)
			//Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?
			//Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)
			//因为我们在session.udpate(user)后执行了flush,所以在清理缓存时执行flush前的sql不会生成
			//sql会按照我们的意愿执行
			tx.commit();
		}catch(Exception e) {
			e.printStackTrace();
			tx.rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
分享到:
评论

相关推荐

    关于flush和evict

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

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

    在Hibernate框架中,Session是与数据库交互的主要接口,它提供了多种方法来操作对象的状态和数据。本文主要讨论了`get`、`load`方法以及`flush`、`clear`、`evict`等方法的区别。 首先,让我们关注`get`和`load`的...

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

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

    hibernate的flush机制

    然而,由于`evict()`操作将`cat`从`entityEntries`中移除,但在事务提交时(即Flush操作时),Hibernate无法找到`cat`对象的引用,从而导致`AssertionFailure`异常,提示可能的非线程安全访问或不正确的Session使用...

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

    `evict()`和`clear()`方法都是用于管理Session缓存中的对象,但它们的作用和使用场景有所不同。理解这些概念对于优化Hibernate应用程序和避免潜在问题至关重要。 首先,`session.evict(obj)`方法是用来从缓存中移除...

    hibernate 缓存机制

    一级缓存的管理方法包括`evict()`用于清除指定对象,`clear()`用于清除所有对象,`contains()`用于检查对象是否存在,以及`flush()`用于将缓存内容与数据库同步。 二级缓存是SessionFactory级别的,它可以跨多个...

    Hibernate缓存

    session.evict(customer); // 从一级缓存中移除customer对象 session.clear(); // 清空一级缓存 boolean contains = session.contains(customer); // 检查一级缓存是否包含customer session.flush(); // 刷新缓存,...

    java-hibernate持久化

    - 显式调用`session.flush()`方法。 总结来说,Hibernate的持久化机制和一级缓存是其高效处理数据库操作的关键。理解并熟练掌握这些概念,可以帮助开发者编写更高效、更易于维护的Java应用。在实际项目中,合理利用...

    hibernate缓存

    当对象的状态发生变化并调用 flush 方法时,Hibernate 会将缓存中的数据与数据库同步。 #### 五、一级缓存与二级缓存的比较 | 特性 | 一级缓存(Session 缓存) | 二级缓存(SessionFactory 缓存) | |-----------...

    Hibernate code

    综上所述,`Session.flush()`方法在Hibernate中起着至关重要的作用,它不仅能够确保数据的一致性和完整性,还能为开发者提供更多控制程序流的可能性。了解何时以及如何使用`flush()`对于开发高性能的应用程序至关...

    jsp Hibernate 函数简介.docx

    - 使用`flush()`和`clear()`或`evict()`可以及时释放内存,防止内存溢出。 综上所述,理解和熟练使用这些Hibernate函数对于在JSP中高效地操作数据库至关重要。通过合理运用,开发者可以减少与数据库的交互次数,...

    Hibernate对象持久化状态

    在 Hibernate 框架中,Java 对象的状态管理和 Session 缓存是核心概念,它们直接影响着数据的持久化过程和数据库交互效率。本篇文章将详细阐述 Hibernate 中对象的三种状态——临时状态、持久化状态和游离状态,以及...

    对象状态到管理,很好的word文档

    如果一个持久态对象的Session被关闭或者调用了`evict()`方法,那么对象将变为游离态。即使数据库中仍有记录,内存中的对象与Session缓存不再关联。若对游离态对象进行修改,需要手动使用`merge()`或`saveOrUpdate()...

    Hibernate学习

    - **Session在什么情况下执行flush**:自动执行flush的情况包括:事务提交、Session关闭、Session.evict()方法调用等。 - **数据库的隔离级别**:解释了不同隔离级别下flush行为的影响。 - **Mysql查看数据库隔离...

    西安领航核心项目Hibernate部分重点、难点总结

    使用`session.flush()`可强制执行当前点的SQL语句,避免顺序问题。 ### Close、Clear及Evict方法的区别 - **Close**:关闭Session,所有Session内的对象变为离线状态。 - **Clear**:清除Session缓存,使所有对象...

    Hibernate基础教程

    - **Session.evict(user)**:从`Session`缓存中移除指定对象。 - **解决异常**:如果从缓存中移除对象后再次操作可能会抛出异常,需要正确处理。 #### 一对多关联映射 一对多关联是指一个实体类对象与多个实体类...

    详解Hibernate的缓存机制及其配置代码

    - `flush()`:刷新缓存,确保缓存中的数据与数据库一致。 - **二级缓存**:这是一种应用级别的缓存,它的生命周期与`SessionFactory`相同,可以存储跨事务的数据,适用于那些更新不频繁的数据。二级缓存需要手动...

    hibernate 学习笔记3

    - **持久态 ↔️ 游离态**:可通过`session.evict()`、`session.close()`或`session.clear()`等方法使对象进入游离态。 - **游离态 → 持久态**:使用`session.update()`或`session.saveOrUpdate`方法将游离态对象...

    hibernate三状态

    此时,对象与数据库中的一个记录对应,并且在Session的生命周期内,对象的任何改变都会在Session关闭时通过flush()方法同步到数据库。使用Session的persist()方法可以将瞬时态对象转变为持久态。 3. **游离态...

Global site tag (gtag.js) - Google Analytics