Hibernate 关联关系映射(Association Relationship Mapping)
一对一主键关联
数据表为:夫妻表

?POJO 为:
??映射文件为:
Husband.hmb.xml
<class?
???????????name="com.demo.hibernate.beans.Husband"?
?????????? table="t_husband"
????????? ?lazy="false"
>
??? <id name="id"?
?????????? type="java.lang.Integer"?
?????????? column="id"
??? >
??????????<generator />
??? </id>
??? <property name="name"
???????????????type="java.lang.String"
???????????????column="name"
???????????????length="50"
??? />
?????<one-to-one name="myWife" >??? <!--主键作为与Husband 对象关联的外键-->
??????? ?????????????<param name="property">myHusband</param>?<!--主键的值是由Husband的主键赋给-->
???????? </generator>
??? </id>
??? <property
?????????????? ?name="name"
??????????????? type="java.lang.String"
??????????????? column="name"
????????????????length="50"
??? />
????<one-to-one name="myHusband" style="margin: 0px 10px 0px 0px;" alt="Hibernate 关联关系照射(Association Relationship Mapping)">
POJO 为:

映射文件:
Father.hbm.xml
<class?
??? name="com.demo.hibernate.beans.Father"?
??? table="t_father"
??? lazy="false"
>
??? <id
??????? name="id"
??????? type="java.lang.Integer"
??????? column="id"
??? >
??????? <generator />
??? </id>
??? <property
????????????? name="name"
????????????? type="java.lang.String"
????????????? column="name"
????????????? length="50"
??? />
?????<one-to-one name="mySon" />
??? </id>
??? <property
???????????? name="name"
???????????? type="java.lang.String"
?????????????column="name"
???????????? length="50"
??? />
?????<many-to-one?name="myFather" cascade="all"/>?? <!--father_id 为外键-->
</class>
插入一条记录
? Father father =?new?Father();
??father.setName("杨康");
??Son son =?new?Son();
??son.setName("杨过");
??
??father.setMySon(son);
??son.setMyFather(father);
? session.save(father);
?一对多关联
数据表为:母子表

POJO:

映射文件为:
Mother.hbm.xml
<class name="com.demo.hibernate.beans.Mother" table="t_mother" lazy="false">
?????? <id name="id" type="java.lang.Integer" column="id">
???????????? <generator />
?????? </id>
?????? <property name="name" type="java.lang.String" column="name" length="50" />
???????<set?name="myChildren" table="t_children" inverse="false" cascade="all" lazy="false">??<!--配置关联映射-->
?????????????????<key column="mother_id"/>??<!--mother_id 为外键-->
??????????????? <one-to-many />
??????</set>
?</class>
Children.hbm.xml
<class?
??? name="com.demo.hibernate.beans.Children"?
??? table="t_children"
??? lazy="false"
>
??? <id
??????? name="id"
??????? type="java.lang.Integer"
??????? column="id"
??? >
??????? <generator />
??? </id>
??? <property
???????????? name="name"
???????????? type="java.lang.String"
?????????????column="name"
???????????? length="50"
??? />
??? <!--如果是单向关联,下面的可以不用配置-->
????<many-to-one name="myMother"???<!--配置关联映射-->
???????????? cascade="all"
??? ???????? column="mother_id"?insert="true"/>???<!--mother_id 为外键-->
</class>
插入一条记录
? Mother mother =?new?TMother();
??mother.setName("阮母");
??Children child1 =?new?Children();
??child1.setName("阮小二");
??Children child2 =?new?Children();
??child2.setName("阮小五");
??Children child3 =?new?Children();
??child3.setName("阮小七");
??Set<Children> children =?new?HashSet<Children>();
??children.add(child1);
??children.add(child2);
??children.add(child3);
? session.save(mother);
?注:如果要查询“阮小二“的母亲是谁。则需要在Children.hbm.xml 文件中的<many-to-one>添加“insert = false” 和 “update = false”。t_children 中的外键mother_id不能有not null约束,否则,必须是双向关联,且必须有child1.setMother(mother),...child3.setMother(mother).。
多对多关联
数据表:
POJO:
?映射文件:
Student.hbm.xml
?<class?
??????? name="org.school.hibernate.beans.Student"?
??????? table="t_student"
??????? lazy="false"
>
??????? <id
??????????????? name="id"
??????????????? type="java.lang.Integer"
??????????????? column="id"
???????? >
?????????????????? <generator />
???????? </id>
???????? <property
????????????????? ?name="name"
?????????????????? type="java.lang.String"
?????????????????? column="name"
?????????????????? length="50"
???????? />
???? ????<set? name="courses"? table=" t_student_course" lazy="false" inverse="false" cascade="save-update" >?<!--配置关联映射-->
????????????? <key column="student_id"/>
??????????????<many-to-many column="course_id" />
???????? </set>?
</class>
Course.hbm.xml
<class?
????????? name="org.school.hibernate.beans.Course"?
????????? table="t_course"
????????? lazy="false"
>
??? <id
???????? name="id"
???????? type="java.lang.Integer"
???????? column="id"
??? >
??????? <generator />
??? </id>
??? <property
????????????? name="name"
????????????? type="java.lang.String"
????????????? column="name"
????????????? length="50"
??? />
????<set? name="students"? table=" t_student_course" lazy="false" inverse="true" cascade="save-update" >?<!--配置关联映射-->
????????????? <key column="course_id"/>
????????????? <many-to-many column="student_id" />
??? </set>
</class>
查询一条记录:查询“张三”学的课程
?? Query query = session.createQuery("from Student where name=?");
???query.setString(0,"张三");
???Student student = (Student)query.uniqueResult();
???String stuName = student.getName();
???System.out.println(stuName);
???
???Set courses = student.getCourses();
???Iterator it = courses.iterator();
???while(it.hasNext()){
????????????? String courseName = ((Course)it.next()).getName();
????????????? System.out.println(courseName);
???}
?
在关联配置中的一些属性
invser:inverse = true 表示在给主表做save() 、update() 和 delete() 操作时,不会对象关联的表做同样的操作;inverse = false 表示当给主表中插入、修改 和 删除操作时,也会对相关联的表中做插入、修改和删除的操作。
cascade:【级联关系】? cascade = all 表示所有情况下均进行级联操;cascade = save-update 表示只有进行save() 和 update() 操作时,才进行级联操作;cascade = delete 表示只有进行 delete() 操作时,才进行级联操作。cascade = none 任何时候都不进行级联操作。cascade? = delete-orphan 表示删除和当前对象已解除关系的附属对象。
sort:【排序关系】 sort = unsorted(不排序);sort = natural(自然排序);sort = comparatorClass(由某个实现了java.util.comparator接口的类型指定排序算法)。
<key>子元素的column属性指定关联表的外键.。
lazy:【是否延迟加载】? lazy = false表示立即加载;lazy = true 掩饰加载。
fetch:【抓取数据方式】 fetch = select(默认) 表示【查询抓取(Select fetching)】:需要另外发送一条 SELECT 语句抓取当前对象的关联实体或集合;fetch = join 表示【连接抓取(Join fetching)】 : Hibernate通过 在SELECT语句使用OUTER JOIN(外连接)来获得对象的关联实例或者关联集合。
<many-to-one>元素的name属性声明外键关联对象的代号;class属性声明该外键关联对象的类;column属性声明该外键在数据表中对应的字段名,unique属性表示外键值必须唯一,不能重复,unique = true,多对一的关系实际上变成了一对一的关系。