10 10Hibernate之对象状态

Hibernate的开发理论来源就是EJB 2.x Entity Bean(实体Bean),在实体Bean里面有一个特点,每当调用了对象中的setter()方法,那么就可以自动的进行数据更新。所以Hibernate本身也具备此类操作,那么在Hibernate之中为了更好的理解POJO类的对象所处的状态,专门提供有三种状态:
(1)瞬时态(Transient):对象保存在内存之中,并没有在数据库之中进行存储,也就是说如果对象一直没有存储,那么就有可能被GC回收,回收之后就像不存在一样;
(2)持久态(Persistent):将内存中的对象保存在数据库之中,或者某一个对象通过数据库读取,此时Session如果没有关闭,那么就是持久态,持久态的最大特征就是属性的变化将引起数据库的变化;
(3)游离态(Detached):如果Session关闭了,那么已经读取出来的数据就变为游离态,这个时候对象保存在内存之中,如果长时间不使用将被GC回收,与瞬时态最大区别只有一点:此时数据库之中有对应数据。
范例:瞬时态——此时没保存

package org.lks.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.lks.pojo.Member;

public class TestMemberDemo {
	public static void main(String[] args) throws ParseException {
		Member member = new Member();
		member.setMid("3181301102");	
		member.setMname("hhy");
		member.setMage(20);
		member.setMbirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1999-08-21"));
		member.setMsalary(10000.0);
		member.setMnote("big fool!");
	}
}

整个的代码操作过程之中,Member对象只存在于内存之中,并没有利用Session进行保存。
范例:由瞬时态变为持久态——只需要使用save()方法保存

package org.lks.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.Member;

public class TestMemberDemo {
	public static void main(String[] args) throws ParseException {
		Member member = new Member();
		member.setMid("31813011021");	
		member.setMname("hhy");
		member.setMage(20);
		member.setMbirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1999-08-21"));
		member.setMsalary(10000.0);
		member.setMnote("big fool!");
		//进行数据库保存,所以由瞬时态变为了持久态
		System.out.println(HibernateSessionFactory.getSession().save(member));
		HibernateSessionFactory.getSession().beginTransaction().commit();
	}
}

31813011021
Hibernate: 
    insert 
    into
        hedb.member
        (mage, mbirthday, mname, mnote, msalary, mid) 
    values
        (?, ?, ?, ?, ?, ?)

如果某一个对象处于持久态的状态下,只需要调用setter方法就可以更新了。
范例:观察持久态的操作形式

package org.lks.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.Member;

public class TestMemberDemo {
	public static void main(String[] args) throws ParseException {
		Member member = new Member();
		member.setMid("31813011022");	
		member.setMname("hhy");
		member.setMage(20);
		member.setMbirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1999-08-21"));
		member.setMsalary(10000.0);
		member.setMnote("big fool!");
		//进行数据库保存,所以由瞬时态变为了持久态
		System.out.println(HibernateSessionFactory.getSession().save(member));
		HibernateSessionFactory.getSession().beginTransaction().commit();
		//此时Session并没有关闭
		member.setMsalary(100.0);
		HibernateSessionFactory.getSession().beginTransaction().commit();
		HibernateSessionFactory.closeSession();
		System.exit(0);
	}
}

31813011022
Hibernate: 
    insert  → HibernateSessionFactory.getSession().save(member)
    into
        hedb.member
        (mage, mbirthday, mname, mnote, msalary, mid) 
    values
        (?, ?, ?, ?, ?, ?)
Hibernate: 
    update   →  member.setMsalary(100.0);
        hedb.member 
    set
        mage=?,
        mbirthday=?,
        mname=?,
        mnote=?,
        msalary=? 
    where
        mid=?

因为现在Session没有关闭,对象属于持久态的状态,所以可以直接利用setter更新数据。

实际上在Session里面存在有get()与load()两个操作方法,这两个操作方法都是根据ID进行数据查询,如果说现在使用ID查询的话,那么对象也处于持久态(前提:不关闭Session)。
范例:观察持久态

package org.lks.test;

import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.Member;

public class TestMemberGet {
	public static void main(String[] args) {
		//在Session没有关闭之前处于持久态
		Member vo = (Member) HibernateSessionFactory.getSession().get(Member.class, "3171301102");
		//此时Session现在并没有关闭,对象为持久态
		vo.setMsalary(10000.0);
		vo.setMnote("super big fool!");
		HibernateSessionFactory.getSession().beginTransaction().commit();
	}
}

Hibernate: 
    select  →   HibernateSessionFactory.getSession().get(Member.class, "3171301102");
        member0_.mid as mid1_0_0_,
        member0_.mage as mage2_0_0_,
        member0_.mbirthday as mbirthda3_0_0_,
        member0_.mname as mname4_0_0_,
        member0_.mnote as mnote5_0_0_,
        member0_.msalary as msalary6_0_0_ 
    from
        hedb.member member0_ 
    where
        member0_.mid=?
Hibernate: 
    update  →  vo.setMsalary(10000.0);  vo.setMnote("super big fool!");
        hedb.member 
    set
        mage=?,
        mbirthday=?,
        mname=?,
        mnote=?,
        msalary=? 
    where
        mid=?

如果在进行一些登录操作的时候,可能会更新某一个用户最后一次登录日期,那么就可以利用持久态实现这类的操作。
范例:游离态

package org.lks.test;

import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.Member;

public class TestMemberDetached {
	public static void main(String[] args) {
		//在Session没有关闭之前处于持久态
		Member vo = (Member) HibernateSessionFactory.getSession().get(Member.class, "3171301102");
		//此时Session关闭了,关闭之后变为游离态
		HibernateSessionFactory.closeSession();
		//此时Session现在并没有关闭,对象为持久态
		vo.setMsalary(10000.0);
		vo.setMnote("super big fool!");
		HibernateSessionFactory.getSession().beginTransaction().commit();
	}
}

Hibernate: 
    select  →   HibernateSessionFactory.getSession().get(Member.class, "3171301102");
        member0_.mid as mid1_0_0_,
        member0_.mage as mage2_0_0_,
        member0_.mbirthday as mbirthda3_0_0_,
        member0_.mname as mname4_0_0_,
        member0_.mnote as mnote5_0_0_,
        member0_.msalary as msalary6_0_0_ 
    from
        hedb.member member0_ 
    where
        member0_.mid=?

因为现在变为了游离态,所以所有数据的修改不会影响到数据库中的实体数据。

口诀:
(1)瞬时态与游离态无法更新数据;
(2)持久态可以更新,但是必须在Session关闭之前完成更新;
切换方法:
(1)瞬时态→持久态:save()方法、update()方法;
(2)持久态→游离态:关闭Session;
(3)游离态→瞬时态:delete()操作;

面试题:请解释Hibernate对象的三种状态?
(1)Hibernate对象数据分别有:瞬时态、持久态、游离态;
(2)瞬时态指的是对象只在内存中保存,数据库没有对应数据;
(3)持久态指的是在对象保存或者取得之后不关闭Session的情况下,可以利用setter进行数据修改;
(4)游离态指的是对象读取完成或保存成功之后关闭了Session后的状态,此时数据库有对应数据。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值