hibernate之对象的状态(示例)

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

猜你喜欢

转载自blog.csdn.net/LYQ2332826438/article/details/81431325
今日推荐