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后的状态,此时数据库有对应数据。