Hibernate之session接口(二)

1.对象的几种状态

在所有之前,说明一下,对于hibernate,它的对象有三种状态,transient、persistent、detached

下边是常见的翻译办法:

transient:瞬时态或者临时态

(new DeptPo(1,”行政部”,20,”行政相关”),该po的实例和session没有关联,该po的实例处于transient)

persistent:持久化状态

(和数据库中记录想影射的Po实例,它的状态是persistent, 通过get和load等得到的对象都是persistent)

detached:脱管状态或者游离态

(1)当通过get或load方法得到的po对象它们都处于persistent,但如果执行delete(po)时(但不能执行事务),该 po状态就处于detached, (表示和session脱离关联),因delete而变成游离态可以通过save或saveOrUpdate()变成持久态

(2)当把session关闭时,session缓存中的persistent的po对象也变成detached

因关闭session而变成游离态的可以通过lock、save、update变成持久态

持久态实例可以通过调用 delete()变成游离状态。

通过get()或load()方法得到的实例都是持久化状态的。

游离状态的实例可以通过调用lock()或者replicate()进行持久化。

save()和persist()将会引发SQL的INSERT,delete()会引发SQLDELETE,

而update()或merge()会引发SQL UPDATE。对持久化(persistent)实例的修改在刷新提交的时候会被检测到,它也会引起SQL UPDATE。

saveOrUpdate()或者replicate()会引发SQLINSERT或者UPDATE

可以通过session提供的方法用于改变对象的状态。

save()方法:

1.使一个临时对象成为持久化对象。

2.为对象分配ID。

3.在 flush缓存的时候发送一条insert语句。

4.save之前设置的ID是无效的。

5.持久化对象的ID是不可修改的。

@Test

public void testSave() {

News news = new News();

news.setAuthor("wenyu2");

news.setDate(new Date());

news.setTitle("php");

news.setId(23);//该行设置无效

System.out.println(news);

session.save(news);

System.out.println(news);

news.setId(45);//改行抛出异常。

persist()方法:

与save方法类似的是persist()方法, persist()方法也可以执行insert操作,但是跟save的区别是,若在persist之前设置了ID值, 则抛出异常,不会insert操作。

@Test

public void testPersist() {

News news = new News();

news.setAuthor("wangwu");

news.setDate(new Date());

news.setTitle("py");

news.setId(34);//抛异常,不会执行insert操作。

session.persist(news);

}

get()方法:该方法会立即查询加载数据库中的对象(立即执行select语句)。但是若是该记录在数据库中不存在那么返回一个null(没有即没有很直接)。

@Test

public void testGet() {

News news = (News) session.get(News.class, 4);

session.close();//若是手动关闭session,下面的打印也会成功。

System.out.println(news);

}

Load()方法:该方法功能和get相同,但是属于延迟加载的方法。

也就是说,执行load方法之后,若是不使用该对象那么不会执行select语句,仅仅返回一个代理对象。与此同时若是查询的记录在数据库中不存在,那么会抛出异常(找不到对象),可以理解为返回代理对象之后,该代理对象无法找到与之匹配的真实对象,即抛异常。

若是在使用对象之前手动关闭了session,在使用对象的时候会抛出懒加载异常。而get却是可以打印出来。

@Test

public void testLoad() {

News news = (News) session.load(News.class, 4);

System.out.println(news.getClass().getName());

session.close();

System.out.println(news);//调用的时候抛出懒加载异常。

}

update方法:

1.若更新一个持久化对象,不需要显示的调用update方法,因为在Transaction 的commit方法之前会先执行flush操作(出发update语句)。

2.当session关闭或者执行了evict方法,将对象从session 缓存中移除,那么该对象处于游离状态,此时需要显示调用update()方法,这个update()显示调用的时候,不论对象的属性是否发生变化都会执行update语句,在跟触发器协同工作的时候,为了避免这个问题,我们可以使用在hbm.xml文件中设置select-before-date值为true,检测是否有改变,若是没有改变那么不会发送update语句。(该方式不常用)。

若数据表中没有该记录,但是还是执行update的话,会导致异常。

当update方法关联一个游离状态的对象时,如果session中已经存在相同ID的持久化对象,会抛异常,因为session 中不能存在两个OID相同的对象。

@Test

public void testUpdate() {

News news = (News) session.get(News.class, 4);

transaction.commit();

session.close();// 至此news对象是一个游离状态的。

// news.setId(6);//该行会抛异常,ID在数据表中不存在。

session = sessionFactory.openSession();

transaction = session.beginTransaction();

// news.setAuthor("JDBC");// news既不在原来的session缓存中,也不在新的缓存中。

// News news2=(News)session.get(News.class, 5);//

session.update(news);// 也就是需要通过显示的执行update方法,将该对象变为持久状态。

}

saveOrUpdate()方法:

根据是否有OID 来判断是采用save操作还是update操作。 若OID不为空但是没有对应的记录,会抛异常。

@Test

public void testSaveOrUpdate() {

News news = (News) new News("FF", "ff", new Date());

news.setId(34);//若该ID在数据库中没有对应的记录,抛异常。

session.saveOrUpdate(news);

}


delete方法:

可删除一个游离对象,也可以删除一个持久化对象。session 的delete方法处理过程:

计划执行一条delete语句,把对象从session缓存中删除,该对象成为删除状态。

hibernate.use.identifier.rollback属性,默认值为false,若设置为true,将改变delete行为,那么会把对象的OID置为空,成为临时对象。

@Test

public void testDelete() {

News news = (News) session.get(News.class, 11);

session.delete(news);

// session.update(news);//删除状态的不可以进行update操作。

System.out.println(news);

}


Evict()方法:

@Test

public void testEvict() {

News news1 = (News) session.get(News.class, 9);

News news2 = (News) session.get(News.class, 8);

news1.setTitle("uu");

news2.setTitle("mm");

session.evict(news2);// 从缓存中移除对象,该对象成为游离状态对象。

session.update(news2);// 该对象若是要update的话,需要显示的调用,因为该对象已经属于游离对象。

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容