1、多对一关联:
员工和部门(多个员工属于一个部门,多对一)
部门类:
public class Department{
private int id;
private String name;
.....
getter和setter 方法
.....
}
员工类:
public class Employee{
private int id;
private String name;
public Department dept;//可以得到部门的全部信息
//按下面的方式只能知道部门的id,要想知道全部信息还得进行查询
//private int departId;
.....
getter和setter 方法
.....
}
表结构:
department:id,name
employee:id,name,dept_id(外键)
前面学的都是一个实体类对应一个表,像现在的员工类就不能很好的映射了;
员工的映射文件:
...
<class name="Employee">
....
<many-to-one name="depart" column="dept_id"/>
....
</class>
...
hibernate 解析到<many-to-one>时 根据属性名(depart)和
类名(Employee)可以知道这个属性的类型,从而可以找到
Department类的映射文件,然后根据dept_id就可以得到一条
部门信息了;
ps:hibernate默认的认为这个外检对应另一张表中的主键,如果对应的不是主键则
需要指出:<many-to-one name="depart" column="dept_id" property-ref="name"/>
操作类:
(1)保存;
......
Department depart=new Department();
depart.setName("dept name");
Employee emp=new Employee();
emp.setDepart(depart);
emp.setName("emp name");
.....
session.save(depart);
session.save(emp);
tx.commit();
.....
session.close();
ps: 如果session.save(emp)在session.save(depart)前面,
执行session.save(emp)时会先给dept_id一个0的值;
当执行了session.save(depart)后dept_id有值了,
这是hibernate会在执行更新语句更新Employee表,
这就是hibernate的强大指出(因为此时对象都是
持久态,他们的变化都会反映到数据库中的);
(2)查询:
employee emp=(Employee)session.get(Employee.class,id);
System.out.println(emp.getDepart().getName());
ps:session.get(Employee.class,id)这语句其实是执行了两次查询,
首先查询"员工表"得到员工信息,然后根据员工信息中的部门id
在查询"部门表"得到部门表。
2、一对多关联:
还是上面的例子:从部门角度考虑就是"一对多"
部门类:
public class Department{
private int id;
private String name;
private Set<Employee> emps;
.....
getter和setter 方法
.....
}
员工类:
public class Employee{
private int id;
private String name;
public Department dept;//可以得到部门的全部信息
//按下面的方式只能知道部门的id,要想知道全部信息还得进行查询
//private int departId;
.....
getter和setter 方法
.....
}
表结构:
department:id,name
employee:id,name,dept_id(外键)
ps: 关系模型没有变化,只是对象模型变了,就是
在"部门类"中多了个Set<Employee> emps
映射文件:
员工的映射文件没有变化:
<class name="Department">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!--集合中每个元素都是一个Employee对象-->
<!--根据id=depart_id去Employee对象的表中去找-->
<set name="emps">
<key column="depart_id"/>
<one-to-many class="Employee"/>
<set>
操作类:
(1)查询:
.....
Department depart=(Department)session.get(Department.class,id);
System.out.println(depart.getEmps().size());
.....
ps:session.get(Department.class,id)是进行两次数据库访问的
先查询"部门表"查出部门信息;
在查询"员工表"根据部门id查询员工信息。
3、一对一关联:
人和身份证---一个人对应一个身份证
Person类:
public class Person{
private int id;
private String name;
private IdCard idCard;
......
getter和setter方法
......
}
IdCard类:
public class IdCard{
//此处id非自增正,而是与Person的id对应的
private int id;
private String name;
private Person person;
......
getter和setter方法
......
}
映射文件:
Person类的映射文件:
<class name="Person">
...
<one-to-one name="idCard"/>
...
</class>
IdCard类的映射文件:
<class name="IdCard" table="id_card">
<!--id是从person中拿到的不是自增长的-->
<id name="id">
<generator class="foreign">
<param name="propery">person</param>
</generator>
</id>
<one-to-one name="person" constrained="true"/>
...
</class>
操作类:
(1)添加:
.....
IdCard idCard=new IdCard();
idCard.setName("身份证");
Person p=new Person();
p.setName("lid");
p.setIdCard(idCard);
idCard.setPerson(p);
session.save(p);
session.save(idCard);
.....
(2)查询:
....
Person p=(Person)s.get(Person.class,id);
System.out.println(p.getIdCard().getName());
....
当然如果IdCard的id是自增长,而是通过外键与person关联:
IdCard类的映射文件:
<class name="IdCard" table="id_card">
<id name="id">
<generator class="native"/>
</id>
<many-to-one name="person" column="person_id" unique="true"/>
...
</class>
Person类的映射文件:
<class name="Person">
...
<one-to-one name="idCard" property-ref="person"/>
...
</class>
4、多对多关联:如老师和学生(一个老师对应多个学生,一个学生对应多个老师)
多对多是我们回创建一个中间表,这样就变成两个一对多了;
Teacher类:
public class Teacher{
private int id;
private String name;
private Set<Student> students;
......
getter 和setter方法
......
}
Student类:
public class Student{
private int id;
private String name;
private Set<Teacher> teachers;
......
getter 和setter方法
......
}
表结构:
teacher: id,name
teacher_student:teacher_id,student_id;
student:id,name;
映射文件:
Teacher的映射文件:
<class name="Teacher">
......
<!--中间表是teacher_student-->
<set name="students" table="teacher_student">
<key column="teacher_id"/>
<many-to-many class="Student" column="student_id"/>
</set>
......
</class>
Student的映射文件:
<class name="Student">
......
<!--中间表是teacher_student-->
<set name="teachers" table="teacher_student">
<key column="student_id"/>
<many-to-many class="Teacher" column="teacher_id"/>
</set>
......
</class>
5、组件关联:
Name类:
public class Name{
private String firstName;
private String lastName;
......
getter和setter方法
......
}
User类:
public class User{
private int id;
private Name name;
private Date birthday;
.....
getter 、setter方法
}
User的映射文件:
<class name=User">
......
<component name="name">
<property name="firstName" column="first_name"/>
<property name="lastName" column="last_name"/>
</component>
......
</class>
ps:当然我们也可以按一对一或者多对一来处理上面的情况,不过那样,用户和
Name就分别对应一张表了;
而向上面这种处理只会生成一张表(firstName和lastName分别对应列first_name和last_name)