Hibernate -- 操作持久化对象

知识点2: session概述

Session 接口是 Hibernate 向应用程序提供的操纵对数据库的最主要的接口,它提供了基本的保存,更新, 删除和加载Java对象的方法.

知识点3:理解session的缓存

Session 接口的实现中包含一系列的 Java 集合, 这些Java集合构成了 Session缓存.只要Session 实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期
sessionsave()方法持久化一个对象时,该对象被载入缓存,以后即使程序中不再引用该对象,只要缓存不清空,该对象仍然处于生命周期中。当试图load()对象时,会判断缓存中是否存在该对象,有则返回。没有在查询数据库

知识点4:清理session的缓存

Session 具有一个缓存,位于缓存中的对象称为持久化对象,它和数据库中的相关记录对应. Session能够在某些时间点,按照缓存中对象的变化来执行相关的 SQL语句, 来同步更新数据库,这一过程被称为清理缓存(flush)
默认情况下 Session 在以下时间点清理缓存:
当应用程序调用 Transaction commit()方法的时,该方法先清理缓存(session.flush()),然后在向数据库提交事务(tx.commit())
当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生了变化,会先清理缓存,以保证查询结果能够反映持久化对象的最新状态
显式调用 Sessionflush()方法.
区别:

     flush:进行清理缓存(此时缓存中的数据并不丢失)的操作,让缓存和数据库同步执行一些列sql语句,但不提交事务,

     commit:先调用flush()方法,然后提交事务.则意味着提交事务意味着对数据库操作永久保存下来。

     reresh:刷新,session和数据库同步,执行查询,把数据库的最新信息显示出来,更新本地缓存的对象状态.

     clear:清空缓存,等价于list.removeAll();

知识点5:在hibernate中java对象的状态

Hibernate 把对象分为 4 种状态持久化状态临时状态游离状态删除状态.

Session 的特定方法能使对象从一个状态转换到另一个状态

 

 

知识点15: 操纵持久化对象-get()  load()

都可以根据给定的 OID 从数据库中加载一个持久化对象
区别:
当数据库中不存在与 OID 对应的记录时, load()方法抛出 ObjectNotFoundException异常, get() 方法返回 null
两者采用不同的延迟检索策略

 

示例代码:

javabean 及 配置文件参考上篇blog的 Customer.java Order.java Customer.hbm.xml hibernate.cfg.xml Order.hbm.xml

知识点示例代码:

AppFlushClearRefreshCommit.java

package cn.itcast.state;

import java.util.Iterator;
import java.util.Set;

import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class AppFlushClearRefreshCommit {
	private static  SessionFactory sf=null;
	
	static{
		   Configuration config=new Configuration();
	       config.configure("cn/itcast/state/hibernate.cfg.xml");
	       config.addClass(Customer.class);
	       config.addClass(Order.class);
	       sf=config.buildSessionFactory();
	}
		
	    /*
	     * 知识点4_1:清理session的缓存  测试flush方法的使用
	     */
		@Test
		public  void testFlush(){
			   Session session=sf.openSession();
			   Transaction tx=session.beginTransaction();
			   
			   Customer c=new Customer();
			   c.setName("曹操");
			   
			   session.save(c);
			   
			   /*
			    * 清理缓存,刷新session的一级缓存中数据到数据库中,让缓存中的数据跟数据库同步 方向缓存--->数据库
			    *         缓存中的数据不丢失
			    */
			   
			   session.flush();  //会产生insert语句,此时已经在数据库中,但数据库还没有确认
			 
			   tx.commit();  //数据库确认插入的数据
			   session.close();
		}
		
		/*
		 * 知识点4_2:清理session的缓存  测试flush和clear方法的使用
		 */
		@Test
		public  void testFlushClear(){
			   Session session=sf.openSession();
			   Transaction tx=session.beginTransaction();
			   
			   //从数据库查询出的客户放置到session的一级缓存中
			   Customer c4=(Customer)session.get(Customer.class, 4); //select
			   
			   //清理缓存,缓存中的数据不丢失
			   session.flush();
			   //从session的一级缓存中获取要查询的数据
			   Customer c5=(Customer)session.get(Customer.class, 4);  //不会产生select语句
			   
			   //清空缓存,session的一级缓存中的数据丢失
			   session.clear();
			   
			   //缓存中已经没有数据了,需要重新查询数据库
			   Customer c6=(Customer)session.get(Customer.class, 4);  //会产生select语句
			   
			   tx.commit();  //数据库确认插入的数据
			   session.close();
		}
		
		/*
		 * 知识点4_4:清理session缓存    测试refresh方法的使用
		 */
		@Test
		public  void tesRefresh(){
			   Session session=sf.openSession();
			   Transaction tx=session.beginTransaction();
			   
			   Customer c4=(Customer)session.get(Customer.class, 4); //select
			   c4.setName("马超");
			   
			   //刷新数据库中的数据和缓存中的同步,方法向从数据库----> 缓存,产生select语句
			   session.refresh(c4);
			   
			   tx.commit();  //数据库确认插入的数据
			   session.close();
		}
				
	   /*
	    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
	    */
		@Test
		public  void testCacheMode11(){
			   Session session=sf.openSession();
			   Transaction tx=session.beginTransaction();
			   
			   //设置缓存的模式是自动模式
			   Customer c=new Customer();
			   c.setName("秦琼");
			   
			   session.save(c);
			   
			   tx.commit();  //产生insert语句
			   
			   session.close();
		}
		
		   /*
		    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
		    */
			@Test
			public  void testCacheMode12(){
				   Session session=sf.openSession();
				   Transaction tx=session.beginTransaction();
				   
				   //设置缓存的模式是自动模式
				   Customer c=new Customer();
				   c.setName("秦琼");
				   session.save(c);
				   
				   session.flush();//产生insert语句
				   tx.commit();  
				   
				   session.close();
			}
			
			
		 /*
		    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
		    */
			@Test
			public  void testCacheMode13(){
				   Session session=sf.openSession();
				   Transaction tx=session.beginTransaction();
				   
				   //设置缓存的模式是从不清理缓存
				   session.setFlushMode(FlushMode.NEVER);
				   
				   Customer c=new Customer();
				   c.setName("秦琼");
				   session.save(c);
				   
				   //该方法不清理缓存,不会产生insert语句,此时数据不能插入到数据库中
				   tx.commit();  
				   
				   session.close();
			}
			
			
			 /*
			    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
			    */
				@Test
				public  void testCacheMode14(){
					   Session session=sf.openSession();
					   Transaction tx=session.beginTransaction();
					   
					   //设置缓存的模式是从不清理缓存
					   session.setFlushMode(FlushMode.NEVER);
					   
					   Customer c=new Customer();
					   c.setName("秦琼");
					   session.save(c);
					  
					   //该方法清理缓存
					   session.flush(); //产生insert语句
					   
					   //该方法不清理缓存
					   tx.commit();  
					   
					   session.close();
				}
				
				
			   /*
			    * 知识点4_5:清理session的缓存(设置缓存的清理模式)
			    */
				@Test
				public  void testBatchData(){
					   Session session=sf.openSession();
					   Transaction tx=session.beginTransaction();
					   
					   //设置缓存的模式是从不清理缓存
					   session.setFlushMode(FlushMode.NEVER);
					   
					   for(int i=0;i<100000;i++){
						   Customer c=new Customer();
						   c.setName("朱仝"+i);
						   session.save(c);
						   if(i%1000==0){
							   //清理缓存,数据已经存在数据库,就是没有确认
							   session.flush();
							   //清空缓存
							   session.clear();
						   }
					   }
					   
					   //清理缓存
					   session.flush();
					   
					   //该方法不清理缓存
					   tx.commit();  
					   
					   session.close();
				}
					
}

AppState.java

package cn.itcast.state;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class AppState {
	private static SessionFactory sf = null;

	static {
		Configuration config = new Configuration();
		config.configure("cn/itcast/state/hibernate.cfg.xml");
		config.addClass(Customer.class);
		config.addClass(Order.class);
		sf = config.buildSessionFactory();
	}

	/*
	 * 知识点5:临时对象(transient)  对象的状态
	 */
	@Test
	public void teststate() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
		
		//刚刚创建一个对象,此时就是临时对象,OID=null
		Customer c = new Customer();
		c.setName("曹操");
		System.out.println("c.getId()  "+c.getId()); //null
		
		//此时customer对象变为持久对象(持久对象有OID,OID不为空)处于session的缓存中
		session.save(c);
		System.out.println("c.getId()  "+c.getId());  //存在值

		tx.commit(); // 数据库确认插入的数据
		session.close();  //此时没有一级缓存了
		
		//session关闭后,此时c引用的对象转化为游离对象  不再处于 Session 的缓存中
		System.out.println(c.getId()+"   "+c.getName());
		
		//此时对象不再被引用,被jvm回收
		c=null;
		
/****************************************************************************************************************/		
		session = sf.openSession();
	    tx = session.beginTransaction();
	    
	    //c1在session的一级缓存中存在 是持久对象 
		Customer c1=(Customer)session.get(Customer.class, 5);
	    
		//删除c1对象
		session.delete(c1);
		//此时c1变为删除对象
	    
		tx.commit(); // 数据库确认插入的数据
		session.close();  //此时没有一级缓存了
		
		//session关闭后,此时c1为游离对象
		
/****************************************************************************************************************/
	}
	
	
	
	/*
	 * 知识点5:临时对象(transient)  对象的状态
	 *   * evict()方法:该方法能将持久对象转化为游离对象
	 */
	@Test
	public void testEvict() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	
		//c1在session的一级缓存中存在 是持久对象 
		Customer c1=(Customer)session.get(Customer.class, 5);  //产生select语句
		
		//直接从session的一级缓存中查询数据
		Customer c2=(Customer)session.get(Customer.class, 5);   //不产生select语句
	    
		//将session一级缓存中的对象转化为游离对象,此时该对象在session的一级缓存中不存在
	    session.evict(c1);
	    
	   
	    //该方法能将游离对象再转化为持久对象,此时该对象有存在session的一级缓存中
	    session.update(c1);
	    
	    //在缓存中不存在该对象,所以要查询数据库
		Customer c3=(Customer)session.get(Customer.class, 5);  //不产生select语句
		
	    
		tx.commit(); // 数据库确认插入的数据
		session.close();  //此时没有一级缓存了		
	}
}

AppMethod.java

package cn.itcast.state;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class AppMethod {
	
	private static SessionFactory sf = null;

	static {
		Configuration config = new Configuration();
		config.configure("cn/itcast/state/hibernate.cfg.xml");
		config.addClass(Customer.class);
		config.addClass(Order.class);
		sf = config.buildSessionFactory();
	}

	/*
	 * 知识点12: 操纵持久化对象-save()
	 */
	@Test
	public void testSave() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	    
		Customer c=new Customer();
	    c.setId(3);  //没有用途
		c.setName("西门庆");
	    session.save(c);
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点13_1: 操纵持久化对象-update()
	 */
	@Test
	public void updagePersission() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	    
		//持久对象
		Customer c=(Customer)session.get(Customer.class, 7);
		
		//游离对象
		session.evict(c);
		
		//游离对象---->持久对象  ---执行update语句
		session.update(c);
		
		tx.commit();
		session.close();
	}
	
    /*
	 * 知识点13_2: 操纵持久化对象-update()
	 *  * 在customer.hbm.xml文件的class标签中增加 select-before-update="true"(在执行更新之前查询)
	 *      * 目的:把要更新的信息又防止到session的一级缓存中,快照有一份
	 *      * 在更新时,哪缓存中的数据和快照比对,没有变化,不再产生update语句
	 */
	
	@Test
	public void updagePersissionClass() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//持久对象
		Customer c=(Customer)session.get(Customer.class, 7);
		
		//游离对象
		session.evict(c);
		
		//游离对象---->持久对象  ---执行update语句
		session.update(c);
		
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点13_3: 操纵持久化对象-update()
	 */
	@Test
	public void updagePersissionOId() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//查询数据库  c1持久对象
		Customer c1=(Customer)session.get(Customer.class, 7);
		
		//c1游离对象
		session.evict(c1);
		
		//查询数据库  c2持久对象
		Customer c2=(Customer)session.get(Customer.class, 7);
		
		//c1持久对象
		session.update(c1);
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点13_4: 操纵持久化对象-update()
	 */
	@Test
	public void updagePersissionWithNoData() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//查询数据库  c1持久对象
		Customer c1=(Customer)session.get(Customer.class, 7);
		
		//c1游离对象
		session.evict(c1);
        
		System.out.println("cccccccccccccccc");
		//手动删除数据
		
		//c1持久对象
		session.update(c1);
	    
		tx.commit();
		session.close();
	}
	
	
	/*
	 * 知识点14_2: 操纵持久化对象-saveOrupdate()
	 */
	@Test
	public void SaveOrUpdateTransient() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	    
		//临时对象
		Customer c=new Customer();
		c.setName("西门庆");

		session.saveOrUpdate(c);
	    
		tx.commit();
		session.close();
	}
	
	
	/*
	 * 知识点14_3: 操纵持久化对象-saveOrupdate()
	 *            如果是游离对象就用update方法
	 */
	@Test
	public void updagePersissionDetached() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//查询数据库  c1持久对象
		Customer c1=(Customer)session.get(Customer.class, 6);
		
		//c1游离对象
		session.evict(c1);
       
		//c1持久对象  执行update方法
		session.saveOrUpdate(c1);
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点14_4: 操纵持久化对象-saveOrupdate()
	 */
	@Test
	public void updagePersissionPersiss() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		//查询数据库  c1持久对象
		Customer c1=(Customer)session.get(Customer.class, 6);
		
		//c1持久对象  不会产生update语句
		session.saveOrUpdate(c1);
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点14_5: 操纵持久化对象-saveOrupdate()
	 *    saveOrUpdate(c)中判定对象为临时对象的标准
	 *      * 如果Id为Integer类型(private Integer id)
	 *         * 如果Id==null执行save操作
	 *         * 如果Id!=null执行update操作
	 *     *  如果javaBean中id为int类型(private int id;)此时id的默认值为0
	 *        在Customer.hbm.xml文件 配置<id name="id" type="integer" unsaved-value="0">增加unsaved-value="0"
	 *          * 如果javaBean中id属性的值与unsaved-value="0"相同,执行insert操作
	 *          * 如果javaBean中id属性的值与unsaved-value="0"不相同,执行update操作
     
	 */
	@Test
	public void SaveOrUpdateUnsaved() {
		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
	    
		//临时对象
		Customer c=new Customer();
	    
		c.setName("西门庆");

		session.saveOrUpdate(c);
		System.out.println("c.getId()  "+c.getId());
	    
		tx.commit();
		session.close();
	}
	
	/*
	 * 知识点15: 操纵持久化对象-get()  load()
	 *   * 区别
	 *      * 相同点:都是通过id查询对象
	 *      * 不同点;
	 *           * 如果id在数据库中不存在get返回null,load抛出异常
	 *           * get方法总是立即加载,load可以配置延迟和立即两种(后面讲)
	 * 
	 */
	@Test
	public void getOrLoad() {
		Session session = sf.openSession(); 
		Transaction tx = session.beginTransaction();
	    
		Customer c1=(Customer)session.load(Customer.class, 14);
	    System.out.println("c1  = "+c1);	
	
		tx.commit();
		session.close();
	}	
}



 

 

 

 

posted @ 2014-02-21 14:26  今晚打酱油_  阅读(298)  评论(0编辑  收藏  举报