1.为什么要对Hibernate的对象分为几种状态:
状态是对对象所处所处情境的描述,在对hibernate定义了几种状态之后即方便了为人所达成共识,同时也能更好的理解hibernate的工作机制。
2.如何区分Hibernate的几种状态:
开始的时候我根据下面两个是否进行判断:
1)对象是否在Session缓存中
2)在数据表中是否有记录
可以上述条件进行组合的形式来穷尽四种种状态,但是并不够完全合理。因为四个状态是可以进行转换的,以数据保存流程的形式来区分更为合理,同时也能够使这四种状态包含了对象可能的所有情况 ,看下面一张图。
案例:
news实体类:
package com.liuyongqi.MavenHibernateDemo2.entity;
import java.io.Serializable;
/**
* 新闻实体类
* @author Administrator
* @data 2018年7月31日
* @time 上午10:05:13
*/
public class News implements Serializable{
/**
*
*/
private static final long serialVersionUID = -7170520651423556216L;
private Integer nid ;
private String ntitle ;
private String ncontext ;
private String ndate ;
public News() {
super();
// TODO Auto-generated constructor stub
}
public News(String ntitle, String ncontext, String ndate) {
super();
this.ntitle = ntitle;
this.ncontext = ncontext;
this.ndate = ndate;
}
public News(Integer nid, String ntitle, String ncontext, String ndate) {
super();
this.nid = nid;
this.ntitle = ntitle;
this.ncontext = ncontext;
this.ndate = ndate;
}
public Integer getNid() {
return nid;
}
public void setNid(Integer nid) {
this.nid = nid;
}
public String getNtitle() {
return ntitle;
}
public void setNtitle(String ntitle) {
this.ntitle = ntitle;
}
public String getNcontext() {
return ncontext;
}
public void setNcontext(String ncontext) {
this.ncontext = ncontext;
}
public String getNdate() {
return ndate;
}
public void setNdate(String ndate) {
this.ndate = ndate;
}
@Override
public String toString() {
return "News [nid=" + nid + ", ntitle=" + ntitle + ", ncontext=" + ncontext + ", ndate=" + ndate + "]";
}
}
News.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-8-1 16:03:37 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.liuyongqi.MavenHibernateDemo2.entity.News" table="NEWS">
<id name="nid" type="java.lang.Integer">
<column name="NID" />
<generator class="native" />
</id>
<property name="ntitle" type="java.lang.String">
<column name="NTITLE" />
</property>
<property name="ncontext" type="java.lang.String">
<column name="NCONTEXT" />
</property>
<property name="ndate" type="java.lang.String">
<column name="NDATE" />
</property>
</class>
</hibernate-mapping>
SessionFactoryUtil工具类:
package com.liuyongqi.MavenHibernateDemo2.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* 提供了开启和关闭session的方法
* @author Administrator
* @data 2018年8月1日
* @time 下午3:32:56
*/
public class SessionFactoryUtil {
//ThreadLocal为每个线程提供一个单独的存储空间
private static ThreadLocal<Session> threadLocal=new ThreadLocal<Session>();
//私有化静态变量,静态变量只实例化一次
private static SessionFactory sessionFactory;
//实例化一次sessionFactory
static {
Configuration configure = new Configuration().configure();
sessionFactory=configure.buildSessionFactory();
}
//私有化构造方法
private SessionFactoryUtil() {
}
//打开session的方法
public static Session openSession() {
//从ThreadLocal中拿取一个session
Session session = threadLocal.get();
if(null==session) {
//sessionFactory打开一个session
session=sessionFactory.openSession();
//把session又放入ThreadLocal中
threadLocal.set(session);
}
return session;
}
//关闭资源
public static void closeSession() {
//从ThreadLocal中拿取一个session
Session session = threadLocal.get();
if(null==session) {
if(session.isOpen()) {
//关闭session
session.close();
}
threadLocal.set(null);
}
}
public static void main(String[] args) {
Session session = openSession();
System.out.println(session);
System.out.println("ok");
}
}
临时状态---持久化状态(与主键的生成策略相关)
save():设置对象的id,不会报错
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//临时状态
News news = new News();
//临时状态---持久化状态(与主键的生成策略相关)
//save():设置对象的id,不会报错
news.setNid(1);
news.setNtitle("sssgggggggsss");
news.setNcontext("sssgggggggggggggggggddddddddddddddddsss");
news.setNdate("2018-08-05");
session.save(news);
transaction.commit();
测试结果:
Hibernate:
insert
into
NEWS
(NTITLE, NCONTEXT, NDATE)
values
(?, ?, ?)
persist():设置对象的id,会报错
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//临时状态
News news = new News();
//临时状态---持久化状态(与主键的生成策略相关)
//persist():设置对象的id,会报错
news.setNid(1);
news.setNtitle("hhhhhhhh");
news.setNcontext("hhhhhhhhdddddddddddddddd");
news.setNdate("2018-08-05");
session.persist(news);
transaction.commit();
测试结果:
持久化状态---游离化状态
close() 将session中所有对象移除
evict() 将单个对象从session中移除
游离化状态---持久化状态
update() 如果要更新一个持久化状态的对象,则可以不用调用update()方法,如果要更新一个游离化状态的对象,则要调用update()方法
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//游离化状态---持久化状态
//update() 如果要更新一个持久化状态的对象,则可以不用调用update()方法,如果要更新一个游离化状态的对象,则要调用update()方法
News news2 = session.get(News.class, 105);
news2.setNtitle("gggddgggg");
session.update(news2); //默认关闭了一次session, 先从持久化状态---游离化状态,后从游离化状态---持久化状态
transaction.commit();
测试结果:
Hibernate:
select
news0_.NID as NID1_0_0_,
news0_.NTITLE as NTITLE2_0_0_,
news0_.NCONTEXT as NCONTEXT3_0_0_,
news0_.NDATE as NDATE4_0_0_
from
NEWS news0_
where
news0_.NID=?
saveOrupdate() 如果数据库中没有记录则添加,如果指定了id,则修改
修改:
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//saveOrupdate() 如果数据库中没有记录则添加,如果指定了id,则修改
News news2 = session.get(News.class, 106);
news2.setNtitle("kkkkkk");
news2.setNcontext("kkkkkkdddddddddddddddd");
news2.setNdate("2018-08-05");
session.saveOrUpdate(news2);
transaction.commit();
测试结果:
Hibernate:
select
news0_.NID as NID1_0_0_,
news0_.NTITLE as NTITLE2_0_0_,
news0_.NCONTEXT as NCONTEXT3_0_0_,
news0_.NDATE as NDATE4_0_0_
from
NEWS news0_
where
news0_.NID=?
Hibernate:
update
NEWS
set
NTITLE=?,
NCONTEXT=?,
NDATE=?
where
NID=?
添加:
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
News news2=new News();
news2.setNtitle("kkkkkk");
news2.setNcontext("kkkkkkdddddddddddddddd");
news2.setNdate("2018-08-05");
session.saveOrUpdate(news2);
transaction.commit();
测试结果:
Hibernate:
insert
into
NEWS
(NTITLE, NCONTEXT, NDATE)
values
(?, ?, ?)
持久化状态---删除状态,游离化状态---删除状态(delete())
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//持久化状态---删除状态,游离化状态---删除状态(delete())
News news2 = session.get(News.class, 107);
if(news2!=null) {
session.delete(news2);
}
测试结果:
Hibernate:
select
news0_.NID as NID1_0_0_,
news0_.NTITLE as NTITLE2_0_0_,
news0_.NCONTEXT as NCONTEXT3_0_0_,
news0_.NDATE as NDATE4_0_0_
from
NEWS news0_
where
news0_.NID=?
无---持久化状态
get()
(1)及时加载:立刻调用sql语句
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//无---持久化状态
//get()
//(1)及时加载:立刻调用sql语句
//(2)如果数据库中没有相对应的记录,则返回null
//(3)session关闭之后,还可以使用对象
News news2 = session.get(News.class, 107);
System.out.println("aaa");
System.out.println("bbb");
System.out.println(news2);
session.close();
测试结果:
Hibernate:
select
news0_.NID as NID1_0_0_,
news0_.NTITLE as NTITLE2_0_0_,
news0_.NCONTEXT as NCONTEXT3_0_0_,
news0_.NDATE as NDATE4_0_0_
from
NEWS news0_
where
news0_.NID=?
aaa
bbb
News [nid=107, ntitle=sssgggggggsss, ncontext=sssgggggggggggggggggddddddddddddddddsss, ndate=2018-08-05 00:00:00.0]
(2)如果数据库中没有相对应的记录,则返回null
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//无---持久化状态
//get()
//(1)及时加载:立刻调用sql语句
//(2)如果数据库中没有相对应的记录,则返回null
//(3)session关闭之后,还可以使用对象
News news2 = session.get(News.class, 109);
System.out.println("aaa");
System.out.println("bbb");
session.close();
测试结果:
Hibernate:
select
news0_.NID as NID1_0_0_,
news0_.NTITLE as NTITLE2_0_0_,
news0_.NCONTEXT as NCONTEXT3_0_0_,
news0_.NDATE as NDATE4_0_0_
from
NEWS news0_
where
news0_.NID=?
aaa
bbb
null
(3)session关闭之后,还可以使用对象
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//无---持久化状态
//get()
//(1)及时加载:立刻调用sql语句
//(2)如果数据库中没有相对应的记录,则返回null
//(3)session关闭之后,还可以使用对象
News news2 = session.get(News.class, 107);
System.out.println("aaa");
System.out.println("bbb");
session.close();
System.out.println(news2);
测试结果:
Hibernate:
select
news0_.NID as NID1_0_0_,
news0_.NTITLE as NTITLE2_0_0_,
news0_.NCONTEXT as NCONTEXT3_0_0_,
news0_.NDATE as NDATE4_0_0_
from
NEWS news0_
where
news0_.NID=?
aaa
bbb
News [nid=107, ntitle=sssgggggggsss, ncontext=sssgggggggggggggggggddddddddddddddddsss, ndate=2018-08-05 00:00:00.0]
load()
(1)延迟加载:不会立刻调用sql语句,用的时候则调用sql语句
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//load()
//(1)延迟加载:不会立刻调用sql语句,用的时候则调用sql语句
//(2)如果数据库中没有相对应的记录,则报错
//(3)session关闭之后,会出现懒加载的问题
News news2 = session.load(News.class, 106);
System.out.println("aaa");
System.out.println("bbb");
System.out.println(news2);
session.close();
测试结果:
aaa
bbb
Hibernate:
select
news0_.NID as NID1_0_0_,
news0_.NTITLE as NTITLE2_0_0_,
news0_.NCONTEXT as NCONTEXT3_0_0_,
news0_.NDATE as NDATE4_0_0_
from
NEWS news0_
where
news0_.NID=?
News [nid=106, ntitle=kkkkkk, ncontext=kkkkkkdddddddddddddddd, ndate=2018-08-05 00:00:00.0]
(2)如果数据库中没有相对应的记录,则报错
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//load()
//(1)延迟加载:不会立刻调用sql语句,用的时候则调用sql语句
//(2)如果数据库中没有相对应的记录,则报错
//(3)session关闭之后,会出现懒加载的问题
News news2 = session.load(News.class, 109);
System.out.println("aaa");
System.out.println("bbb");
System.out.println(news2);
session.close();
测试结果:
(3)session关闭之后,会出现懒加载的问题
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//load()
//(1)延迟加载:不会立刻调用sql语句,用的时候则调用sql语句
//(2)如果数据库中没有相对应的记录,则报错
//(3)session关闭之后,会出现懒加载的问题
News news2 = session.load(News.class, 109);
System.out.println("aaa");
System.out.println("bbb");
session.close();
System.out.println(news2);
测试结果:
解决方法:在映射文件中加上lazy="false"
测试结果:
Hibernate:
select
news0_.NID as NID1_0_0_,
news0_.NTITLE as NTITLE2_0_0_,
news0_.NCONTEXT as NCONTEXT3_0_0_,
news0_.NDATE as NDATE4_0_0_
from
NEWS news0_
where
news0_.NID=?
aaa
bbb
News [nid=106, ntitle=kkkkkk, ncontext=kkkkkkdddddddddddddddd, ndate=2018-08-05 00:00:00.0]
好了,今天测试九到这里了,谢谢大家的浏览!
如果大家想浏览我的下一篇文章,请留言
此文章属于原创,不准转载:https://blog.csdn.net/LYQ2332826438