Hibernate持久化对象的解析1

问题?持久化对象是什么?

主要解析,在对hibernate进行数据交互的时候,是如何进行的:在这里就需要提出持久哈对象这个概念了。


在上面这张图,我们就可以看出,在我们对进行cud操作的时候,持久化对象处于临时状态。而只有当它进入session的相关方法的时候,才进入了hibernate,这个时候对象就转变为持久化状态了,然后它才会检查数据的正确性,但是不进行SQL语句(两个持久化对象不同,但是标识符相同,这种情况是不允许产生的。在同一个事物中是不允许出现同一个主键的).而在事务进行提交到DB的时候才会产生SQL语句。最后一个是断开连接,也就是对象处于托管状态。

或者看下一个图:



细节看案例如:(可以先看看上一篇文章hibernate环境的搭建)

package cn.itcast.hibernate.sh.generator;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.itcast.hibernate.sh.domain.Person;
import cn.itcast.hibernate.sh.utils.HiberanteUtils;

public class GeneratorTest extends HiberanteUtils{
	/**
	 * 	Hibernate: select max(pid) from Person
		Hibernate: insert into Person (pname, psex, pid) values (?, ?, ?)
		
		说明:
		   1、主键的类型必须是数字
		   2、主键的生成是由hibernate内部完成的,程序员不需要干预
		   3、这种生成机制效率比较低
	 */
	@Test
	public void testIncrement(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Person person = new Person();
		person.setPname("上海第一期班长");
		person.setPsex("女");
		
		/**
		 * 参数必须持久化对象
		 */
		session.save(person);
		
		transaction.commit();
		session.close();
	}
	
	/*
	 * Hibernate: insert into Person (pname, psex) values (?, ?)
	 * 说明
	 *   1、新的主键的产生是由数据库完成的,并不是由hibernate或者程序员完成的
	 *   2、该表必须支持自动增长机制
	 *   3、效率比较高
	 */
	@Test
	public void testIdentity(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Person person = new Person();
		person.setPname("MR_LI13");
		person.setPsex("女");
		
		/**
		 * 参数必须持久化对象
		 */
		session.save(person);
		
		transaction.commit();
		session.close();
	}
	
	/**
	 * 由程序设置主键
	 */
	@Test
	public void testAssigned(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Person person = new Person();
		person.setPname("MR_LI13");
		person.setPsex("女");
		
		/**
		 * 参数必须持久化对象
		 */
		session.save(person);
		
		transaction.commit();
		session.close();
	}
	
	/**
	 * 1、UUID是由hibernate内部生成的
	 * 2、主键的类型必须是字符串
	 */
	@Test
	public void testUUID(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		
		Person person = new Person();
		person.setPname("MR_LI13");
		person.setPsex("女");
		
		/**
		 * 参数必须持久化对象
		 */
		session.save(person);
		
		transaction.commit();
		session.close();
	}
	
	
	/**
	 * hibernate内部是根据主键生成器来生成主键的,在客户端设置主键不一定起作用,在

assigned的时候起作用
	 */
	@Test
	public void testIdentity_ID(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Person person = new Person();
		person.setPid(1L);
		person.setPname("aa");
		person.setPsex("aa");
		session.save(person);
		transaction.commit();
		session.close();
	}
}

看下一个案例:

package cn.itcast.hibernate.sh.state;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.itcast.hibernate.sh.domain.Person;
import cn.itcast.hibernate.sh.utils.HiberanteUtils;

public class StateTest extends HiberanteUtils{
	/**
	 * session.save方法把一个临时状态的对象转化成持久化状态的对象
	 */
	@Test
	public void testSavePerson(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Person person = new Person();
		person.setPname("afds");
		person.setPsex("af");
		session.save(person);
		transaction.commit();
		session.close();
	}
	
	/**
	 * session.update方法可以把一个对象的状态变成持久化状态
	 */
	@Test
	public void testUpdate(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Person person2 = new Person();//临时状态
		person2.setPid(1L);//临时状态
		session.update(person2);//持久化状态
		transaction.commit();
		session.close();
	}
	
	/**
	 * 当session.get方法得到一个对象的时候,是不需要再执行 update语句,因为已经是持久化

状态
	 * 当一个对象是一个持久化对象的时候,当进行提交的时候,hibernate内部会让该对象和快照

进行对比,如果一样,则不发出update语句
	 * 如果不一样,则发出update语句
	 */
	@Test
	public void testGet(){
		Session session = sessionFactory.openSession();
		//Transaction transaction = session.beginTransaction();
		Person person = (Person)session.get(Person.class, 1L);//持久化
		person.setPname("tt");
		//session.update(person);
		//transaction.commit();
		session.close();
	}
	
	/**
	 * session.clear方法把所有的对象从session中清空
	 */
	@Test
	public void testClear(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Person person = (Person)session.get(Person.class, 1L);
		person.setPname("asd");
		session.clear();//把session中所有的对象清空
		session.update(person);//把对象从脱管状态转化成持久化状态
		transaction.commit();
		session.close();
	}
	
	/**
	 * session.evict把一个对象从session中清空
	 */
	@Test
	public void testEvict(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Person person = (Person)session.get(Person.class, 1L);
		person.setPname("asdsss");
		session.evict(person);//脱管状态
		session.update(person);//把对象的状态转化成持久化状态
		transaction.commit();
		session.close();
	}
	
	
	/**
	 * 一个对象是否是持久化对象是针对某一个session而言的
	 */
	@Test
	public void testSession(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Person person = (Person)session.get(Person.class, 1L);
		person.setPname("asfd");
		transaction.commit();
		session.close();
		session =  sessionFactory.openSession();
		transaction =  session.beginTransaction();
		person.setPname("aaaaaaa");//person对象对于94的session来说是一个临时状态的

对象
		//session.update(person);
		transaction.commit();
		session.close();
	}
	
	/**
	 * 当执行transaction.commit的时候,hibernate内部会检查session
	 *    1、如果一个对象为临时状态的对象,则session不会管
	 *    2、如果一个对象是持久化状态的对象,如果有ID值,并且和数据库对应,那么先把该对

<span style="white-space:pre">	</span>象与快照进行对比,如果一致,则什么都不做,如果不一致,则发出update语句
	 *    3、如果一个对象是持久化状态的对象,如果没有ID值,则会发出save语句
	 */
	@Test
	public void testMuplyOption(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Person person = new Person();
		person.setPname("rrr");
		person.setPsex("asdfasdf");
		
		Person person3 = new Person();
		person3.setPname("rrr");
		person3.setPsex("asdfasdf");
		
		
		session.save(person);
		Person person2 = (Person)session.get(Person.class, 1L);
		person2.setPname("afds45");
		transaction.commit();
		session.close();
	}
	
	//最后在这里说一下,如果主键类型为indentity类型的,及时在提交事务前持久化对象呗去掉了,最后也<span style="white-space:pre">	</span>//会在数据库发生SQL语句,这是因为这个主键的增长是数据库生成的,不用通过SQL语句。
	@Test
	public void testMutiplyOption2(){
		Session session = sessionFactory.openSession();
		Transaction transaction = session.beginTransaction();
		Person person = new Person();
		person.setPname("asdfads");
		person.setPsex("er");
		session.save(person);
		transaction.commit();
		session.evict(person);
		session.close();
		
		
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
		session.update(person);
		session.clear();
		transaction.commit();
		session.close();
		//看看这个方法又走了那些状态
	}
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值