当前位置:首页 > hibernate学习文档
? ORM关系映射(Annotation版)
1. 一对一 单向 外键关联 映射
a) 项目:Wife-Hansband
b) Annotation:@OneToOne,@JoinColumn c) 对象中:Handsband中有Wife对象 d) 数据库:在Handsband中有WifeId 2. 一对一 双向 外键关联 映射
a) 项目:Wife-Hansband
b) Annotation:@OneToOne,@JoinColumn,mappedBy属性
c) 对象中:Handsband中有Wife对象,Wife对象中有Handsband对象 d) 数据库:在Handsband中有WifeId
注:在双向关联时一定要设置mappedBy
3. 多对一 单向 映射
a) 项目:Son-Mother
b) Annotation:@ManyToOne,@JoinColumn
c) 对象中:Son中有Mother的引用JoinColumn定义的motherid d) 数据库中:son表中有motheridid,mother中没有引用 4. 一对多 单向 映射
a) 项目:Mother-Son
b) Annotation:@OneToMany,@JoinColumn
c) 对象中:Mother中有Son的引用集合Set,为JoinColumn定义的motherid,
解释为以在多方mother为主,在son中建立外键 d) 数据库中:son表中有motherid,mother中没有引用 5. 一对多/多对一 双向 映射
a) 项目:Mother-Son
b) Annotation:多端(Son)@ManyToOne,@JoinColumn
一端(Mother)@OneToMany(mappedBy=”mother”)
c) 对象中:Mohter中有Son的引用集合Set,Son中有mother的引用 d) 数据库中:与多对一一样,在son中建立外键 6. 多对多 单向 映射
a) 项目:Teacher-Student(单向映射例子为Teacher中有Student的集合,但Student
中没有Teacher的引用,理解为老师知道教哪些学生,但学生不知道被哪些老师教)
b) Annotation:Teacher端:
@ManyToMany
@JoinTable(name=\,
joinColumns={@JoinColumn(name=\)}, inverseJoinColumns={@JoinColumn(name=\)}
public Set
return studentSet;}
c) 对象中:Teacher中有Student的集合set,Student中没有Teacher的引用 d) 数据库中:建立中间表做引用 7. 多对多 双向 映射
a) 项目:Teacher-Student(单向映射例子为Teacher中有Student的集合, Student
中有Teacher的引用,理解为老师知道教哪些学生,学生也知道被哪些老师教) b) Annotation:Teacher端:
@ManyToMany
@JoinTable(name=\,
joinColumns={@JoinColumn(name=\)}, inverseJoinColumns={@JoinColumn(name=\)}
public Set
return studentSet;}
Student端:@ManyToMany(mappedBy=\) public Set
c) 对象中:Teacher中有Student的集合set,Student中有Teacher的Set集合引用 d) 数据库中:与多对多单向一样,建立中间表做引用
? ORM CURD
1. CUD---(Cascade) 级联Cascade操作与CUD有关,与R无关
a) 项目:多对一 关联 Son-Mother 在多端Son中有Mother的引用,Mother中没
有Son的引用。创建Transient对象Son、Mother,分别
session.save(mohter),session.save(son) ,然后尝试只保存son,看mother是否被保存,结论是默认不会级联保存。报错(org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.myjava.model.Mother,意为不能保存一个没有被保存的瞬时对象),这时需要配置级联关系解决该问题 b) Annotation:Mother端:
@ManyToOne(cascade={CascadeType.ALL})
public Mother getMother() { return mother;}
cascade有是一个数组类型,Cascade是一个枚举类型。常用ALL,PERSIS,REMOVE 三个类型,ALL是指所有CURD情况均级联,PERSIS为只在保存时级联,REMOVE指只在删除时级联
c) 对象中:Son中有Mother的引用JoinColumn定义的motherid d) 数据库中:son表中有motherid,mother中没有引用 2. R --read (Fetch) R与fetch有关
a) 项目:多对一,一对多 关联 Son-Mother
b) Annotation:@ManyToOne和@OneToMany都有属性为fetch,fetch值为
fetchType的两个常量,EAGER和LAZY,其中EAGER指饥饿的,需要马上加载;LAZY指懒惰的,不需要马上加载,而是使用时才会加载。这两个注解在fetch上的区别为@ManyToOne注解默认的多端在load或get一端的情况下,会自动的获得一端的数据信息,要想不获取,则需要设置fetch的属性值为fetchType.LAZY;而OneToMany则不会马上加载,会在使用时才加载,所以要想获取信息,则需要设置fetch的属性值为fetchType.EAGER。 注意:关于Fetch,@ManyToOne和@OneToMany一般都用默认,前者为EAGER, 后者为LAZY,两端不要同时用EAGER,可以两端都设置为LAZY,不然会发出重复的SQL,影响效率。 Hibernate:
select son0_.id as id1_1_, son0_.mother_id as mother3_1_1_, son0_.name as name1_1_, mother1_.id as id0_0_, mother1_.name as name0_0_ from
Son son0_ left outer join
Mother mother1_
on son0_.mother_id=mother1_.id where
son0_.id=? Hibernate: select
sonset0_.mother_id as mother3_1_, sonset0_.id as id1_, sonset0_.id as id1_0_,
sonset0_.mother_id as mother3_1_0_, sonset0_.name as name1_0_ from
Son sonset0_ where
sonset0_.mother_id=?
后面的红色不分为多余部分,是在Mother(一端)设置了EAGER影响的结果。 c) 记忆方法:一对多fetchType为lazy,多对一为eager 3. Update
a) 项目:同上
b) Annotation:默认多端fetchType为eager,一端为lazy。
c) 进行update操作时一定要在一个session中操作,否则一旦session关闭后
(tx.commit)后就会保存。
4. Delete
a) 项目:同上
b) 删除时应注意删除时需要在所有操作都需要在一个session中进行 c) 一些情况下的例子 @Test /** * 级联状态为@OneToMany的cascade为CascadeType.ALL情况下删除一端,会级联删除所有对应的多端记录 */ public void testDeleteSon1(){ Session session = sf.getCurrentSession(); Transaction tx = session.beginTransaction(); com.myjava.model.many2one.bi.Mother mother =
(com.myjava.model.many2one.bi.Mother)session.get(com.myjava.model.many2one.bi.Mother.class, 1); session.delete(mother); tx.commit(); } @Test /** * 级联状态为CascadeType.ALL情况下删除一端,不想级联删除多端的时候需要循环取出多端内容,然后将外键关系置null,然后再删除一端内容 */ public void testDeleteSon2(){ Session session = sf.getCurrentSession(); Transaction tx = session.beginTransaction(); com.myjava.model.many2one.bi.Mother mother =
(com.myjava.model.many2one.bi.Mother)session.get(com.myjava.model.many2one.bi.Mother.class, 1); Session s = sf.getCurrentSession(); mother.setName(\); s.delete(mother); tx.commit(); } @Test /** * 级联状态为CascadeType.ALL情况下删除多端中一个 * 这样删除会将数据库中所有与删除对象的motherid相同的对象以及Mothe记录都删除,因为他们之间是All的关系 */ public void testDeleteSon3(){ Session session = sf.getCurrentSession(); Transaction tx = session.beginTransaction(); 5. com.myjava.model.many2one.bi.Son son =
(com.myjava.model.many2one.bi.Son)session.get(com.myjava.model.many2one.bi.Son.class, 1); Session s = sf.getCurrentSession(); s.delete(son); tx.commit(); } @Test /** * 对于testDeleteSon3方法改正方案1
共分享92篇相关文档