Hibernate session浅见(3)

来源:互联网 发布:知乎 cos 编辑:程序博客网 时间:2024/04/30 05:49

      程序通过Hibernare来加载保存修改删除或者是更新数据的时候,可能会导致数据库层的一些触发器引起相关的操作,也可能会引发Hibernare拦截器的一些相关操作。

 

 

   我们知道Hibernare按照常规的方式进行批量的操作会导致大量的持久化对象加载到内存当中,从而消耗大量的内存空间,极有可能会导致内存的空间的不足而产生错误。

 

   数据库中的出发器在与Hibernare协同工作的时候可能会带来许多负面的问题:

  1: 触发器导致Session的缓存中的持久化对象与数据库中的对应数据出现不一致的现象

  2: Session的update可能会盲目的触发或者说是激活触发器

 

先简述下  1: 触发器导致Session的缓存中的持久化对象与数据库中的对应数据出现不一致的现象

下面举个简单的例子和解决这类问题的解决方案:

假设有一个这样的bean类Customer 

文件Custome.java

 

 

 

Customer.hbm.xml

 

 

 

 

 

下面是测试类:

 

 

 

 

控制台输出信息为:

 

测试testDirect()时控制台输出的信息:

 

 

drop table if exists CUSTOMERS

create table CUSTOMERS (ID bigint not null, NAME varchar(15), REGISTER_DATE datetime, primary key (ID))

Hibernate: select max(ID) from CUSTOMERS

1->RegisterDate:  Sat Jul 10 21:58:25 CST 2010

2->customer.getRegisterDate(): Sat Jul 10 21:58:25 CST 2010

两者引用同一地址(对象)?   true

Hibernate: insert into CUSTOMERS (NAME, ID) values (?, ?)

 

测试testFlush()时控制台输出的信息:

 

drop table if exists CUSTOMERS
create table CUSTOMERS (ID bigint not null, NAME varchar(15), REGISTER_DATE datetime, primary key (ID))
Hibernate: select max(ID) from CUSTOMERS
1->RegisterDate:  Sat Jul 10 21:59:40 CST 2010
2->customer.getRegisterDate(): Sat Jul 10 21:59:40 CST 2010
----------------------------
Hibernate: insert into CUSTOMERS (NAME, ID) values (?, ?)
3->customer.getRegisterDate(): Sat Jul 10 21:59:40 CST 2010
4->cus.getRegisterDate(): Sat Jul 10 21:59:40 CST 2010
两者引用同一地址(对象)?   true

测试testFlushAndRefresh()时控制台输出的信息:

 

drop table if exists CUSTOMERS
create table CUSTOMERS (ID bigint not null, NAME varchar(15), REGISTER_DATE datetime, primary key (ID))
Hibernate: select max(ID) from CUSTOMERS
1->RegisterDate:  Sat Jul 10 22:01:37 CST 2010
2->customer.getRegisterDate(): Sat Jul 10 22:01:37 CST 2010
----------------------------
Hibernate: insert into CUSTOMERS (NAME, ID) values (?, ?)
Hibernate: select customer0_.ID as ID0_0_, customer0_.NAME as NAME0_0_, customer0_.REGISTER_DATE as REGISTER3_0_0_ from CUSTOMERS customer0_ where customer0_.ID=?
3->customer.getRegisterDate(): null
4->cus.getRegisterDate(): null
两者引用同一地址(对象)?   true

查询mysql 获取的信息(以上的每个方法 都是如下结果)

 

mysql> select * from  customers;

+----+---------+---------------+

| ID | NAME    | REGISTER_DATE |

+----+---------+---------------+

|  1 | macower | NULL          |

+----+---------+---------------+

1 row in set (0.00 sec)

 

 

很明显Session并没有将REGISTER_DATE字段进行赋值。直接保存或者清理缓存时仍然会发现数据库中的记录和Session缓存的记录存在不一致的情况,只要当进行refresh()迫使Session的缓存和数据库同步的时候才能保证在缓存中得到的数据是真实的数据。

 

当然,当我们将 REGISTER_DATE在Hibernare一端插入空值,在mysql一端直接写sql语句或者其他程序调用jdbc将REGISTER_DATE赋值的时候Hibernare 的Session在默认情况下是探测不到这种变化的因此,假设我们在后续中要用到 Session保存的数据我们就需要进行 缓存的清理和refres()以此来同步数据库与Session的缓存,从而才能保证数据的一致性,当然假设在后续阶段我们在当前的缓存中不会用到这个持久化的对象,此时我们也就没了必要在此处进行数据库的同步从而在一定程度上提高了一定的性能。当开启另外一个Session时候我们一样的可以查询到真实的数据。

 

 

接下来分析下 2: Session的update可能会盲目的触发或者说是激活触发器

假设在数据库中定义了有update引起的事件激活了触发器,那么我们就需要额外的谨慎的使用update和saveOrupdate()方法。

我们知道这两个对象都够将一个游离的对象重新和Session进行关联,由于Session的缓存中还不存在这个对象的快照(说白了就是我们在j2se中所讲述的深拷贝而来的对象,在Hibernare中有一个这样的方法叫做deepCopy()),因此Session就无法判断是游离对象是否与数据库的保持一致(检测的时候是拿当前对象与快照进行比对,比对的时候用的equals方法),所以Session为了保险起见,不管是游离对象的属性是否发生变化都会执行update语句,而此时执行update的时候就会激活相应的触发器,当数据并无变化的时候(或者说是游离对象的属性和数据库中的一致),显然此时的update就是多余的,那么此时激活触发器就是毫无意义,甚至带来危害。所以我们需要考虑到这种情况,幸好Hibernare提供了这个问题的解决方案。

就是在<class>标签 加一个select-before-update='true' 就行了,在Hibernate session浅见(1)中讲述了 在查询之前Hibernate会进行同步刷新数据库以此来保证数据的一致性。这样配置以后会执行一条select语句来获取这个对象的最新数据,然后进行比对,在不一致的情况下才会执行update语句,这样就避免了执行多余的update语句,以及盲目的激活相关的触发器。

 

 

总之Session是非常重要也是非常关键的一个部分,设计到整个程序中最关键的东西---数据,因此需要对其进行格外的注意,理解了Session才能开始理解Hibernare的基本设计思想,也才能保证数据的安全和一致。总之Hibernare的Session是Hibernare设计的一个杰作,需要我们认真的去体会和学习。

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 4sid密码忘记了怎么办 苹果4忘记id密码怎么办 枣核吃到肚子里怎么办 芝麻分贷款不还怎么办 德国bm家不发货怎么办 金士顿u盘坏了怎么办 箱子的密码忘了怎么办 拉杆箱密码忘了怎么办? 拉杆箱忘了密码怎么办 拉箱密码忘了怎么办 飞行箱密码忘了怎么办 旅行箱密码乱了怎么办 手机sdk版本过低怎么办 cad标注数字太小怎么办 绿萝花肥施多了怎么办 大疆4云台抖动怎么办 三证合一后社保怎么办 三证合一后税务怎么办 身份证在深圳丢了怎么办 吃虾过敏皮肤痒怎么办 吃大头虾手掌痒怎么办 孩子支气管炎咳嗽老不好怎么办 抻筋了 很疼怎么办 短信验证码删了怎么办 对减肥药产生抗体了怎么办 被担保公司骗了怎么办 大学考查课挂了怎么办 大订书机卡针了怎么办 做原创的衣服该怎么办 4s店强制上牌怎么办 小孩一读书就哭怎么办 小孩上中班还哭怎么办 14岁初中生厌学怎么办 加拿大签证拒签了怎么办 离婚后不给孩子抚养费怎么办 格力空调出现e1怎么办 联想一键恢复后怎么办 微盘密码忘记了怎么办 乐高零件丢了怎么办 tpu手机壳变黄怎么办 脚被铁钉扎了怎么办