ITPub博客

首页 > 应用开发 > Java > hibernate

hibernate

原创 Java 作者:tbase 时间:2008-05-26 15:39:27 0 删除 编辑
4. hibernate如何根据pojo来更新数据库

4.0
在commit/flush之前,hibernate不会对pojo对象作神秘的处理。4.0.1 在select查询出pojo时,hibernate根据“字段--属性”的对应关系,用字段的值填充pojo的属性;然后根据“关系标记”生成sql语句从relationTable中查询出满足条件的relationPojo,并把这些relatinPojo放到“关系属性”中。这个过程是机械的。

4.0.2
在pojo对象被查出来后,到commit(或flush)之前,它将是一个普通的java对象,hibernate不会做额外的手脚。比如,不会限制你设置一个属性的值为null或其它任何值在集合类Set的add(object)操作时, 不会改变object的值,不会检查参数object是否是一个pojo对象设置mainPojo的一个“桥属性”的值,不会自动设置relationPojo的对应的“桥属性”的值。执行session.delete(pojo)时,pojo本身没有变化,他的属性值也没有变化。执行session.save(pojo)时,如果pojo的id不是hibernate或数据库生成,则它的值没有变化。如果pojo的id是hibernate或数据库生成,则hibernate会把id给pojo设上去。

extend:
对lazy=true的set,hibernate在进行set的操作(调用java.util.Set中声明的方法)时会先inialize这个set,仅此而已。而inialize仅仅是从数据库中捞出set的数据。 如果一个set已经被inialize了,那么对它进行的操作就是java.util.Set接口中定义的语义。
另外,如果id由hibernate来生成,那么在save(pojo)时,hibernate会改变该pojo,会设置它的id,这可能改变该pojo的hashCode,详细地讨论见帖《》

mapping
文件中标记的某些属性及pojo对象的操作会对数据库操作产生影响,这些影响都是在commit时才会起作用。而在commit前pojo的状态不受它们的影响。
不过,待commit之时,将由hibernate完全掌控,它好像知道pojo对象从创建到commit这中间的所有变化。


4.01.
关联更新
"
关系标记"对应的属性是一个pojo或一个pojo的集合,修改“关系属性”的值能会导致更新mainTable表,也可能会更新relationTable表。
这种更新暂叫“关联更新”。


4.1.inverse
属性的作用(假定没有设置cascade属性)
4.1.1 “
只有集合标记(set/map/list/array/bag)才有inverse属性”。
————
不妨以标记set为例,具体为“一个地区(Address表)的学校(School表)” -- address.schoolSet。

4.1.2 “set
的inverse属性决定是否把对set的改动反映到数据库中去。
inverse=false————
反映;inverse=true————不反映”
inverse
属性默认为false
对和子标记,这两条都适用。不管是对set做什么操作,4.1.2都适用。

4.1.3
当inverse=false时,hibernate如何将对set的改动反映到数据库中:
对set的操作主要有:(1)新增元素 address.getSchoolSet().add(oneSchool);(2)删除元素 address.getSchoolSet().remove(oneSchool);(3)删除set address.setSchoolSet(null);(4)设新set address.setSchoolSet( newSchoolSet);(5)转移set otherSchoolSet = otherAddress.getSchoolSet();
otherAddress.setSchoolSet(null);
address.setSchoolSet(otherSchoolSet);
(6)改变set中元素的属性的值 如果是改变key属性,这会导致异常如果改变的是普通的属性,则hibernate认为set没有变化(在后面可以看出缘由)。所以这种情形不予考虑。
改变set后,hibernate对数据库的操作根据是关系还是关系而有不同。
对one-to-many,对school set的改动,会改变表SCHOOL中的数据:
#SCHOOL_ID
是school表的主键,SCHOOL_ADDRESS是school表中的地址栏位
#
表School的外键为SCHOOL_ADDRESS,它对应表Address的主键ADDRESS_ID(11)insert oneSchool———— sqlInsertRowString:
update SCHOOL set SCHOOL_ADDRESS=? where SCHOOL_ID=?
(
仅仅update foreign-key的值。)(22)delete oneSchool———— sqlDeleteRowString:
update SCHOOL set SCHOOL_ADDRESS=null where SCHOOL_ID=?
(很奇怪,把foreign-key设置为null不知道有什么实际意义?)(33)delete 属于某一address的所有school ————sqlDeleteString:
update SCHOOL set SCHOOL_ADDRESS=null where SCHOOL_ADDRESS=?
(44)update ————sqlUpdateRowString:"", no need
对many-to-many,对school set的改动,会改变关系表ADDRESS_SCHOOL中的数据:
#“
地区————学校”的关系为多对多的关系有点牵强,只是为了方便与上面的one-to-many作比较
#
假设有一个关系表ADDRESS_SCHOOL,有两个字段ADDRESS_ID, SCHOOL_ID,
#
这两个字段分别对应ADDRESS和SCHOOL两表的key(11)insert的SQL语句为: insert into ADDRESS_SCHOOL(ADDRESS_ID, SCHOOL_ID)
values(?,?)
(22)delete的SQL语句为: delete from ADDRESS_SCHOOL
where ADDRESS_ID=? AND SCHOOL_ID=?
(33)delete all的SQL语句为: delete from ADDRESS_SCHOOL
where ADDRESS_ID=?
(44)update的sql语句为 ————sqlUpdateRowString:
update ADDRESS_SCHOOL set ADDRESS_ID=?
where ADDRESS_ID=? AND SCHOOL_ID=?
对set的操作(1),hibernate会执行(11)sqlInsertRowString对set的操作(2),hibernate会执行(22)sqlDeleteRowString

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/249132/viewspace-1004635/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    28
  • 访问量
    159610