【HIbernate学习】HIbernate实例的三种状态(三)

Session 的主要功能是为映射实体类的实例提供创建,读取和删除操作。这些实例可能在给定时间点时存在于以下三种状态之一:

  • 瞬时状态: 一种新的持久性实例,被 Hibernate 认为是瞬时的,它不与 Session 相关联,在数据库中没有与之关联的记录且无标识符值。临时状态对象是通过实例化的方式注入到内存中,也就是通过New的方式来开辟内存。临时对象是孤立在内存上的,它不与数据库中的数据有任何关系。
  • 持久状态:可以将一个瞬时状态实例通过与一个 Session 关联的方式将其转化为持久状态实例。持久状态实例在数据库中没有与之关联的记录,有标识符值,并与一个 Session 关联。通过session.get()或者session.load()等获取的数据对象,就是持久化状态的对象。注意:如果对持久化对象进行了修改,并没有执行事务提交,这时持久化对象的数据不会同步到数据库中的。
  • 脱管状态:一旦关闭 Hibernate Session,持久状态实例将会成为脱管状态实例。

下面我们通过几个例子来了解下这三种状态的区别。

临时状态

@Test
	public void test3() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setName("王五");
			student.setAge("22");
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

刚实例化的实体是临时状态,在session中不存在,也没有和数据库进行关联。所以执行事务提交没有任何语句打印。

@Test
	public void test3() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setName("王五");
			student.setAge("22");
			session.save(student);
			session.saveOrUpdate(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

临时状态的对象我们可以通过save()或者saveOrUpdate()方法将对象从临时状态转换为持久态。注意:执行saveOrUpdate()时,session里的实例没有任何变化,所以在提交时只打印一次插入语句。

@Test
	public void test3() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = new Student();
			student.setName("王五");
			student.setAge("22");
			session.save(student);
			student.setName("王老五");
			session.saveOrUpdate(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

当执行保存操作后,再次修改实体里面的属性值,saveOrUpdate()会执行更新操作,在提交事务时会先执行插入语句,再执行更新语句。

持久状态

@Test
	public void test1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = session.get(Student.class, "402899816753f99f016753f9a2df0000");
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

通过session.get()、session.load()、query.list()、query.iterate()可以获取持久状态的实例或者实例集合。注意:query.list()、query.iterate()方法必须用实体接收才是持久状态,这也很好理解,映射实体类的实例才有三种状态的说法。

@Test
	public void test1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = session.get(Student.class, "402899816753f99f016753f9a2df0000");
			student.setName("王四");
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

注意:持久状态的数据是和数据库有同步关联,对持久态的数据进行操作需要特别注意,修改了数据后就算不执行更新操作,在事务提交时也会修改数据库的数据,这是因为在事务提交时进行了flush操作。这也许就是在日常使用中数据无端被改的原因。

脱管状态(游离态)

@Test
	public void test4() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = session.get(Student.class, "402899816753f99f016753f9a2df0000");
			student.setName("wangsisi");
			session.evict(student);
			System.out.println(student.getName());
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	@Test
	public void test5() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = session.get(Student.class, "402899816753f99f016753f9a2df0000");
			student.setName("wangsisi");
			session.clear();
			System.out.println(student.getName());
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

当数据为持久态时,修改实体里面的属性值,在事务提交的时候会更新数据库。现在我们在事务提交前执行evict()和clear()操作,发现并没有打印更新语句。这时实例处于脱管状态,即虽然实例有数据库标识值 id,但是在session缓存中不存在与之对应的实例。当然在事务提交时,就无法从session中取出操作计划对数据库进行操作。

脱管状态》持久状态

@Test
	public void test4() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = session.get(Student.class, "402899816753f99f016753f9a2df0000");
			student.setName("wangsisi");
			session.evict(student);
			session.update(student);
			session.saveOrUpdate(student);
			System.out.println(student.getName());
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

通过update()、saveOrUpdate()方法可以使实例从脱管状态转换成持久态,实例变为持久态后,事务提交时就会执行更新操作,打印一条update语句。还有一种lock操作也可以使实例从脱管状态转换成持久态。后面我们再单独讲解。

脱管状态》临时状态  持久状态》临时状态

@Test
	public void test6() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = session.get(Student.class, "402899816753f99f016753f9a2df0000");
			session.delete(student);
			student.setName("ssngag");
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

通过delete()方法可以使实例从脱管状态或持久状态转换成临时状态。

@Test
	public void test6() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Student student = session.get(Student.class, "40289981675e6ea701675e6eaabc0000");
			session.delete(student);	
			session.save(student);
			session.getTransaction().commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}

在delete()方法后面增加保存操作,这时在删除操作后会增加插入操作,这是因为虽然session缓存里面已经没有了这个实例,但是虚拟机内存里面实例还是存在的。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值