简单来说Hibernate是ORM映射的持久层框架,全称是(Object Relational Mapping),即对象关系映射。
它将数据库中的表映射成对应的对象,以对象的形式展现,这样我们就可以通过映射的对象来对数据库中的数据进行间接的操作。
关联映射是将数据库中的表映射成与之相对应的对象,当你对这个对象进行操作的时候,Hibernate会对数据库中对应的表执行相应的操作,你对该实体的操作实际上就是在间接的操作数据库中与之相对应的表。
Hibernate正是实现了这种思想,达到了方便开发人员以面向对象的思想来实现对数据库的操作。
hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.Java)、映射文件(*.hbm.xml)和数据库配置文件(*.properties/*.cfg.xml),它们各自的作用如下。
映射类(*.java):它是描述数据库表的结构,表中的字段在类中被描述成属性,将来就可以实现把表中的记录映射成为该类的对象了。
映射文件(*.hbm.xml):它是指定数据库表和映射类之间的关系,包括映射类和数据库表的对应关系、表字段和类属性类型的对应关系以及表字段和类属性名称的对应关系等。
数据库配置文件(*.properties/*.cfg.xml):它是指定与数据库连接时需要的连接信息,比如连接哪种数据库、登录数据库的用户名、登录密码以及连接字符串等。当然还可以把映射类的地址映射信息放在这里。
1、单向关联与双向关联
单向关联:单向关联是指只有一方有另一方的关联信息而另一方没有关联信息
例:
A——>B
A对象中有B对象的关联信息
B对象中没有A对象的关联信息
我们可以通过A对象中B的关联信息查询或修改B对象的信息但无法通过B对象来查询修改A对象的信息
双向关联:双向关联是指两方都有另一方的关联信息
例:
A<——>B
A对象中有B对象的关联信息
B对象中也有A对象的关联信息
我们可以通过A对象中B的关联信息查询或修改B对象的信息也可以通过B对象来查询修改A对象的信息
单向关联一般在一方配置多方不进行配置
如:一对多 单向关联在“一”的一方配置文件里进行配置,"多"的一方不进行配置
双向关联两方都要配置
如:一对多 双向关联在“一”的一方配置文件里需要配置,“多”的一方也需要进行配置
2、一对一关联映射
一对一关联:一对一是指一个对象对应一个对象 如:一个人只有一个身份证。
在两个数据表之间的一对一关系可以有两种实现方法,其中一种就是通过两个表的主键相关联,另一种是通过外键相关联
如:一个人(Person)对应一个地址(Address)代码如下。
(1)一对一主键单向关联:
Person——>Address
public class Person {
private int personid;
private String name;
private int age;
//在Person对象中有Address对象的关联信息
private Address address;
public class Address{
//Address对象中没有Person对象的关联信息
private int addressid;
private String addressdetail;
这种单方面有另一个对象的关联信息的时候我们称为单向关联,再来看一下两个表中的映射hbm.xml文件:
Person.hbm.xml
address
单向关联和双向关联的区别主要在于单向只在一方配置而双向两方都要配置
Address.hbm.xml
因为是单方面关联所以只在Person.hbm.xml中配置了关联信息而Address.hbm.xml中不做任何配置
所以我们省略Address.hbm.xml
…………
(2)一对一主键双向关联:
Person<——>Address
public class Person implements java.io.Serializable {
private Long id;
private String name;
//双向关联中Person对象中有Adderss对象的关联信息
private Address address;
public class Address implements java.io.Serializable {
private Long id;
//Adderss对象中也有Person对象的关联信息
private Person person;
private String detail;
这种两方面都有另一个对象的关联信息的时候我们称为双向关联,再来看一下两个表中的映射hbm.xml文件:
Person.hbm.xml
姓名
单向关联和双向关联的区别主要在于单向只在一方配置而双向两方都要配置
Address.hbm.xml
person
详细地址
当我们操作Person对象时,可以对Address对象进行操作,也可以操作Address对象时对Person对象进行操作这样就形成了双向的关联
双向关联还需要在hibernate.cfg.xml中进行配置
root
jdbc:mysql://localhost:3306/testdb
org.hibernate.dialect.MySQLDialect
xiaohui
com.mysql.jdbc.Driver
true
true
(3)一对一外键单向关联:
Person——>Address
public class Person {
private int personid;
private String name;
private int age;
private Address address;
public class Address{
private int addressid;
private String addressdetail;
Address.hbm.xml
…………………………
Person.hbm.xml
关联和主键关联不同的地方是采用
(4)一对一外键双向关联:
Person<——>Address
public class Person implements java.io.Serializable {
private Long id;
private String name;
private Address address;
public class Address implements java.io.Serializable {
private Long id;
private Person person;
private String detail;
Person.hbm.xml
姓名
Address.hbm.xml
详细地址
人的ID
单向关联和双向关联的区别主要在于单向只在一方配置而双向两方都要配置所以一对一双向关联比单向关联多了一个在Person.hbm.xml文件中配置
双向关联还需要在hibernate.cfg.xml中进行配置
root
jdbc:mysql://localhost:3306/testdb
org.hibernate.dialect.MySQLDialect
xiaohui
com.mysql.jdbc.Driver
true
true
注意:因为一对一的主键关联映射扩展性不好,当我们的需要发生改变想要将其变为一对多的时候变无法操作了,所以我们遇到一对一关联的时候经常会采用唯一外键关联来解决问题,而很少使用一对一主键关联。
3、一对多关联映射
一对多关联:一对多是指一个对象对应多个对象 同样也分为单向关联和双向关联 如:一个教室可以有多个学生
(1) 一对多单向关联:
Classes——>Student
public class Classes {
private int id;
private String name;
//Set支持延迟加载因为多个学生所以我们用Set集合关联
private Set students;
}
public class Student {
private int id;
private String name;
}
单向关联只需在一方配置hbm.xml文件Student不需要配置所以就省略了
Classes对象中使用了set属性,但是只是说明了延迟加载的属性,并没有为属性配置对应的对象,属性的对象是要在映射文件中来配置的,需要添加set标签,并在set标签中添加
Classes.hbm.xml
因为Classes一方是一方对应的Student是多方 所以我们要用
Student.hbm.xml不做任何改变
省略………………
(2)一对多双向关联:
Classes<——>Student
public class Classes {
private int id;
private String name;
//Set支持延迟加载
private Set students;
}
public class Student {
private int id;
private String name;
//添加class对象关联信息因为是一方所以我们用一个对象关联
private Classes classes;
}
Classes.hbm.xml
因为与单向一对多配置一样所以就省略了 可以参考上面单向一对多的代码
Student.hbm.xml
双向我们需要两方都要配置代码如下:
因为Student一方是多方对应的Classes是一方 所以我们要用
4、多对多关联映射
多对多关联:多对多关联是指多个对象对应多个对象 如:老师可以有多个学生,学生也可以有多个老师
(1)多对多单向关联:
Teacher——>Student
public class Teacher {
private int id;
private String name;
private Set students = new HashSet();
}
public class Student {
private int id;
private String name;
private String title;
}
Teacher.hbm.xml
文件中要使用
Student.hbm.xml不做任何配置所以省略
…………
(2)多对多双向关联:
Teacher<——>Student
public class Teacher {
private int id;
private String name;
private Set students = new HashSet();
}
public class Student {
private int id;
private String name;
private String title;
private Set teachers = new HashSet();
}
Teacher.hbm.xml同单向多对多一样故省略
…………
Student.hbm.xml
5、多对一关联
对比一对一关联映射和多对一唯一外键关联映射,其实它们两个都是使用了
多对一关联:多对一关联是指多个对象对应一个对象 如:多个员工对应一个部门
(1)多对一单向关联:
public class Department {
private int id;
private String name;
}
public class Employee {
private int id;
private String name;
private Department depart;//注意这里是以部门的对象来作为员工的属性的,这个思想很关键,是建立起部门和员工关联的关键
}
Department.hbm.xml不做任何配置故省略
…………
Employee.hbm.xml
(2)多对一双向关联:
public class Department {
private int id;
private String name;
private Set emps;//用集合来存储员工
}
public class Employee {
private int id;
private String name;
private Department depart;//注意这里是以部门的对象来作为员工的属性的,这个思想很关键,是建立起部门和员工关联的关键
}
Departement .hbm.xml
Employee.hbm.xml同单向关联配置相同故省略
…………
1、简单的介绍
cascade和inverse (Employee – Department)
l Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的cascade:
none,all,save-update,delete, lock,refresh,evict,replicate,persist,
merge,delete-orphan(one-to-many)。
一般对many-to-one,many-to-many不设置级联,
在
l inverse表“是否放弃维护关联关系”(在Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=”true”表示该对象不维护关联关系;
该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false)。
one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。
注: 配置成one-to-one的对象不维护关联关系
2、属性的解析
class元素的lazy属性设定为true,表示延迟加载,如果lazy设为false,则表示立即加载。以下对这二点进行说明。
立即加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后, 会立即再从数据库取得数据组装此对象所关联的对象(如学生证1)。
延迟加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后,不会立即再从数据库中取得数据组装此对象所关联的对象(如学生1),而是等到需要时,才会从数据库取得数据组装此关联对象。
它的取得可以是以下几种:
none:在保存,删除或修改当前对象时,不对其附属对象(关联对象)进行级联操作。它是默认值。
save-update:在保存,更新当前对象时,级联保存,更新附属对象(临时对象,游离对象)。
delete:在删除当前对象时,级联删除附属对象。
all:所有情况下均进行级联操作,即包含save-update和delete操作。
delete-orphan:删除和当前对象解除关系的附属对象。
当fetch属性设定为select时,表示查询抓取(Select fetching):需要另外发送一条Select语句抓取当前对象的关联实体或集合。
3、代码练习
1、单向关联
(1)、一对一主键关联:单向关联时我们需要在有关联信息一方的配置文件里加入
(2)、一对一外键关联:单向关联时我们需要在有关联信息一方的配置文件里加入
(3)、一对多单向关联:单向关联时我们需要在有关联信息一方的配置文件里加入
(4)、多对多单向关联:单向关联时我们需要在有关联信息一方的配置文件里加入
(5)、多对一单向关联:单向关联时我们需要在有关联信息一方的配置文件里加入
2、双向关联
(2)、一对一主键关联:在从表的一方加入
(2)、一对一外键关联:除了在从表中加入
(3)、一对多双向关联:除了在一方中加入
(4)、多对多双向关联:需要在两方都加入
(5)、多对一双向关联:要在多方中加入