一.双向一对多和多对一
这个很简单,先附上点源代码吧。
user的映射文件:
<class name="User" table="user" catalog="tie">
<id name="id" type="long">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="string">
<column name="name" not-null="true" />
</property>
<set name="emails" table="email" cascade="all" lazy="true" inverse="true">
<key column="uid"></key>
<one-to-many class="Email"/>
</set>
</class>
email的映射文件:
<hibernate-mapping>
<class name="Email" table="email" catalog="tie">
<id name="id" type="long">
<column name="id" />
<generator class="native" />
</id>
<many-to-one name="user" column="uid" class="User" cascade="all" outer-join="true"></many-to-one>
<property name="address" type="string">
<column name="address" not-null="true" />
</property>
</class>
</hibernate-mapping>
介绍一下标出来的属性的作用吧.一,outer-join,在多对一关系中通过email导航到user时,(一对多应该也一样,试试)如果outer-jonin为false(默认)则生成的是两条查询语句,将他的值设为true时生成的是一条外连接的语句。二,cascade,设置了他则有连接关系的两个对象只要设置了他们的连接关系则系统会在处理一个的时候自动处理另一个。三inverse,在一对多关系的时候把inverse设置为true是指把主控权交给多方自己,关键要注意,这个时候要设置双方各自的联系
二 一对一
有两种实现:外键关联 主键关联
1.外键关联:这种实现的形式是一种特殊的一对多方式。idcard表中有一个和user表关联的外键uid,card类当然应该user类,此时user类中也有一个card类(不再是set了)
user的映射文件:
<class name="tie.User" table="user" catalog="tie">
<id name="id" type="long">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="string">
<column name="name" not-null="true" />
</property>
<one-to-one name="card" class="tie.Card" cascade="all" property-ref="user"></one-to-one>
</class>
注: property-ref:指定关联的属性与外键对应,如果不设置系统默认的是用主键关联。
card的映射文件:
<class name="tie.Card" table="card" catalog="tie">
<id name="id" type="long">
<column name="id" />
<generator class="native" />
</id>
<many-to-one name="user" class="tie.User" column="uid" unique="true"></many-to-one>
<property name="cardno" type="string">
<column name="cardno" not-null="true" />
</property>
</class>
unique;把多对一限制成一对一
2主键关联
此时card表中不需要uid字段了,
user的映射文件:
<class name="tie.User" table="user" catalog="tie">
<id name="id" type="long">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="string">
<column name="name" not-null="true" />
</property>
<one-to-one name="card" class="tie.Card" cascade="all" property-ref="cardno"自己测试一下是不是必须></one-to-one>
</class>
card的映射文件:
<class name="tie.Card" table="card" catalog="tie">
<id name="id" type="long">
<column name="id" />
<generator class="foreign" >
<param name="property">user</param>
</generator>
</id>
<property name="cardno" type="string">
<column name="cardno" not-null="true" />
</property>
<one-to-one name="user" class="tie.User" constrained="true"></one-to-one>
</class>
注:constrained告诉hibernate存在外键约束,一定要注意修改generator->foreign
一.单向多对多和双向多对多
create table course
(id varchar ( 32 ) not null primary key ,
name varchar ( 16 ),
)
create table student
(id varchar ( 32 ) not null primary key ,
name varchar ( 16 )
)
create table student_course_link
(sid varchar ( 32 ) not null ,
cid varchar ( 32 ) not null ,
primary key (sid,cid)
)
加入外键约束。映射文件如下:
<class name="org.tie.Student" table="student" catalog="tie">
<id name="id" type="long">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="string">
<column name="name" not-null="true" />
</property>
<set name="courses" table="student_course" cascade="save-update" inverse="false">
<key column="studentid"></key>
<many-to-many class="org.tie.Course" column="courseid"></many-to-many>
</set>
</class>
<class name="org.tie.Course" table="course" catalog="tie">
<id name="id" type="long">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="string">
<column name="name" not-null="true" />
</property>
<set name="students" table="student_course"
cascade="save-update" inverse="true">
<key column="courseid"></key>
<many-to-many class="org.tie.Student" column="studentid"></many-to-many>
</set>
</class>
这里特别要注意inverse这个选项,在多对多关联的时候必须有一方的inverse设置有true,也就是说要由一方来维护关联关系即中间的关系表。这里由student表来维护表的关系,即inverse设为false,
Session session = factory.openSession();
// Transaction tx = session.beginTransaction();
// Student stu = (Student)session.load(Student.class, new Long(7));
// System.out.println(stu.getName());
// Set<Course> courses = stu.getCourses();
// for(Course course : courses){
// System.out.println(course.getName());
// }
// session.delete(stu);
// tx.commit();
// session.close();
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
Course course = (Course)session.load(Course.class, new Long(7));
System.out.println(course.getName());
Set<Student> students = course.getStudents();
for(Student student : students){
student.getCourses().remove(course);
System.out.println(student.getName());
}
session.delete(course);
tx.commit();
session.close();
因为student是主控方,所以要删除course先要在student中解除他们之间的关系