zoukankan      html  css  js  c++  java
  • Hibernate>session flush方法

    session flush方法

    1、session flush方法主要做了两件事:
      * 清理缓存
      * 执行sql
    2、session在什么情况下执行flush
      * 默认在事务提交时
      * 显示的调用flush
      * 在执行查询前,如:iterate
    3、hibernate按照save(insert),update、delete顺序提交相关操作,即actionQueue中的insertion,updation,deletion. 可以用session.flush打断,让它先干完一部分。
    4、
    session:中对象:
    actionQueue: 存放的是各种类型的临时的sql语句,在flush时执行
    persistenceContext:存放persistence状态的对象,还有一个existsInDatebase表示该persistence对象是否存到数据库.
    如save一个uuid主键生成策略的对象,则存放到persistenceContext中,但existsInDatebase却为false.
    注意:
    (a). persistenceContext中的对象,如果existsInDatebase=false,则它的insert sql语句在actionQueue中的insertions中,如果existsInDatebase=true,则insert sql已经执行过了.
    (b). flush在清理缓存时,先执行actionQueue中的各种sql语句,然后再查看persistenceContext中的persistence对象(这个对象可以看成是数据库中对象的快照),看它们的对象属性是否已经更改,如果更改了则会再执行update语句.

    例子:

    user1 ,user2, user3 Id生成策略分别是uuid,native(自增),和assigned

    package com.ncepu.hibernate;
    
    import java.util.Date;
    
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    
    import com.ncepu.hibernate.HibernateUtils;
    import com.ncepu.hibernate.User1;
    import com.ncepu.hibernate.User2;
    import com.ncepu.hibernate.User3;
    
    import junit.framework.TestCase;
    
    public class SessionFlushTest extends TestCase {
    	
    	/**
    	 * 测试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("zhang3");
    			
    			session.save(user);
    			
    			user.setName("wangwu");
    			session.update(user);
    			
    //			User3 user3 = new User3();
    //			user3.setId("002");
    //			user3.setName("zhaosi");
    //			session.save(user3);
    			user.setId("002");
    			user.setName("3");
    			
    			//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);
    		}
    	}		
    }
    

    数据库的隔离级别:http://blog.csdn.net/ncepustrong/article/details/7948231



     

  • 相关阅读:
    【负载均衡】1.负载均衡介绍
    1.tcpdump、wireshark常用用法
    10.prometheus PromQL
    9.prometheus pushgateway介绍与部署
    服装行业生产按客户订制的解决方案
    课程总结
    第十四周课程总结&实验报告
    第十三周学习总结
    第十二周总结
    时间过得好快,第十一周就要截止了。不该遗憾的,要开心,要努力。
  • 原文地址:https://www.cnblogs.com/xqzt/p/5637188.html
Copyright © 2011-2022 走看看