hibernate对象状态

hibernate对象状态有三种

瞬时(临时)对象

持久化对象

脱离(游离)对象


临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。(数据库和session中都不存在)

持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。(数据库和session中都存在)


游离状态(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对象。(数据库中存在,而session中不存在)


临时状态与游离状态的区别:一般情况下,临时状态的对象无主键并且没有持久化,游离状态的对象有主键没有被持久化


对象转换关系图:


代码示例

/**
	 * save:由临时状态-->持久化状态 1.save方法执行后,必须保证id存在, 所以根据主键生成方式的不同向数据库发送不同的sql语句
	 * 1>由hibernate生成主键 发送select 调用完flush才发送insert 2>由底层数据库生成 发送insert
	 * 2.save之前给临时状态设id,没卵用 3.持久化状态的对象不允许修改id
	 */
	@Test
	public void testSave() {
		News news = new News("yinhe", "hebi", new Date());
		news.setNewsId(11);
		session.save(news);
	}
	/**persist:由临时状态-->持久化状态 
	 *	与save的不同: 如果在persist之前 设置了临时对象的id 那么会抛出异常
	 */
	@Test
	public void testPersist(){
		News news = new News("yinhe", "hebi", new Date());
		news.setNewsId(11);
		session.persist(news);
	}
	/**
	 * 游离状态-->持久化状态 get和load: 1.get直接检索 load延迟检索
	 * get方法执行后会直接返回一个news对象,而load返回的是news对象的代理对象 当使用news时,再查询数据库
	 * 2.如果数据表没有对应的数据:
	 * 		get:返回null
	 * 		load:拋出异常
	 * 3.当使用news之前关闭了session:
	 * 		1>get:不受影响,因为立即检索
	 * 		2>load:抛出懒加载异常,
	 * 			解决方式:在session关闭(commit)之前使用news,或者实例化news对象
	 * 			Hibernate.initialize(news1);
	 */
	@Test
	public void testGet() {
		News news1 = (News) session.get(News.class, 2);
		
		session.getTransaction().commit();
		System.out.println(news1);
	}
	@Test
	public void testLoad() {
		News news1 = (News) session.load(News.class, 2);
		Hibernate.initialize(news1);
		session.getTransaction().commit();
		System.out.println(news1);
	}
	/**
	 * evict:持久化对象-->游离对象
	 * 
	 */
	@Test
	public void testEvict(){
		News news1 = (News) session.get(News.class, 1);
		News news2 = (News) session.get(News.class, 2);
		//清除news1对应的缓存
		session.evict(news2);
		//查询id为7的记录,观察select语句发送与否
		News news3 = (News) session.get(News.class, 2);
	}
	/**Update:将游离状态-->持久化状态
	 * 如果更新持久化状态的对象,我们 不需要显式的调用update语句  在commit时,
	 * 			会通过flush方法将缓存中的对象更新到数据库中,通过flush,可能会发送update语句
	 * 更新游离对象:
	 * 	1.确保更新的对象的id在数据表中,如果不在,抛出异常
	 * 	2.不论和数据库记录是否一致,都发update命令,那么如何
	 * 	  防止都发送update呢?
	 * 	  了解:在对象关系映射文件中的class节点添加select-before-update属性,默认为false
	 *   设置为true后,会在每次update之前查询缓存中的内容是否与数据库记录一致,
	 *   如果一致不再发送update语句
	 * 	3.session中不能有两个id相同的同一个类对象
	 */
	@Test
	public void testUpdate(){
		//更新持久化对象
//		News news1 = (News) session.get(News.class, 2);
//		news1.setTitle("asd");
		//1.确保更新的对象的id在数据表中,如果不在,抛出异常
//		News news = new News("qwe", "777", new Date());
//		news.setNewsId(2);
//		session.update(news);
		//2.
//		News news1 = (News)session.get(News.class, 2);
//		session.clear();
//		session.update(news1);
		//3.
		News news1 = (News) session.get(News.class, 2);
		news1.setContent("aaaaaa");
		session.clear();
		News news2 = (News) session.get(News.class, 2);
		session.update(news1);
	}
	/**
	 * saveOrUpdate()
	 * 1.临时对象:save
	 * 游离对象:update 如果id和数据库不对应,抛出异常
	 * 2.unsaved-value 如果设成50,
	 * 	  会将id为50的游离对象看作临时对象
	 */
	@Test
	public void saveOrUpdate(){
		News news1 = new News("1", "2", new Date());
		news1.setNewsId(2);
		session.saveOrUpdate(news1);
	}
	/**
	 * 删除:delete  如果删除一个id在数据库中不对应的 那么会抛出异常
	 * 持久化对象:不受unsaved-value影响
	 * 游离对象:受unsaved-value影响 
	 * 		        如果游离对象id与unsaved-value一致,
	 * 			那么系统会将此游离对象作为临时对象
	 */
	@Test
	public void delete(){
		News news1 = new News("1", "2", new Date());
		news1.setNewsId(2);
		session.delete(news1);
//		News news2 = (News)session.get(News.class, 10);
//		session.delete(news2);
	}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值