1.一对多自身相关
员工找经理 关系属性 Emp mgr; 映射文件: 多个员工对应一个经理
<many-to-one inverse="true"/>
经理找员工 关系 Set<Emp>;映射文件: 一个经理对应多个员工
<set name="xxx" cascade="xxx">
<key column="xxx"/>
<one-to-many class="xxx"/>
</set>
2.多对多
1.表之间的关系:三张表,两个外键(联合为主键)组成了一张表(关系表)
2.映射文件:关系属性的配置,要点:三张表,两个外键
<set name="关系属性的名称" table="第三张表" cascade="save-update">
<key column="当前对象为第三张表提供的外键"/>
<many-to-many class="关系属性对应的类(对应的表)" column="外键"></many-to-many>
</set>
如果当前对象能够获得外键列,可以直接删除,不用在内存中解除关系。
(注意:inverse="true")
主键生成器 generator class="xxx"
1.increment 先查询数据表的主键的最大值,然后加1
在实际开发过程中不会使用increment:不能解决并发问题
2.foreign 只能在共享主键1:1中使用
3.* sequence【序列】适用的数据库Oracle 、DB2、Postgre
默认调用hibernate_sequence
使用自定义的sequence控制主键的增长
1.创建序列
create sequence 序列名称 increment by 步进 start with 起始值;
2.在映射文件中使用
<generator class="sequence">
<param name="sequence">g_user_seq</param>
</generator>
4.identity 使用的数据库 Sqlserver Mysql
特点:在创建表时要为主键设定自动生长的关键词auto_increment
create table g_user(
id int auto_increment primary key
);
5.* native 特点:根据方言进行数据库的判断,根据数据库的类型
自动选择sequence和indentity
<generator class="native"></generator>
6.assigned 特点:可以让程序员手动指定主键的值(公司定义的算法),在实际开发中使用
较多
<generator class="assigned"></generator>
在保存对象时应该手动指定主键值
7.uuid 特点:uuid长度比较长,占空间,跨数据库,移植性比较好
8.* hilo 高低位算法:在hibernate 中最常用的一种主键生成方式,通过一张表来维护hi的
值(hi的值必须初始化)
1.创建维护hi值的表
create table hibernate_hilo(next_hi integer);next_hi维护高位值
insert into hibernate_hilo values (0);
2.在映射文件中配置
<generator class="hilo">
<!-- 指明维护高位值的表 -->
<param name="table">hibernate_hilo</param>
<!-- 指明维护高位的列名 -->
<param name="column">next_hi</param>
<!-- 设置低位的最大值 -->
<param name="max_lo">100</param>
执行的原理:
1.获得hi的值,并且将hi的值加1保存
2.获得lo的值,从0到max_lo中循环取值,每次值的差为1
3.根据公式:hi*(max_lo+1)计算生成主键的值
注意:到hi为0时,O*(max_lo+1);时lo会跳过0从1开始
特点:跨数据库,维护性比较高
9:seqhilo :将hilo中的数据表换成了sequence
复合主键
注意:1.对象必须实现序列化接口
1.对象当中的几个属性组合作为表的主键【实体类属性的复合主键】
O StudnetMsg
stuId//学号
courseId//课程
grade//分数
R create table g_stuMsg(
stuId integer,
courseId integer,
grade number(3,1),//数字总共3个,小数点后面一位
primary key (stuId,courseId)
);
M 映射文件
1.复合主键而言,主键的控制不能使用<id>标签
<composite-id>
<key-property name="属性名" column="对应的列名" type="类型" />
...
</composite-id>
2.由一个主键类,将对象当中的联合作为主键的属性描述成一个对象,称为主键类
【主键类的复合主键】
主键类: 1.实现序列化接口[必须]
2.要为主键类提供equas和hashcode的方法【早期版本的hibernate】
1.将组成主键的属性单独作为主键类
class StuMsgPk {
stuId//学号
courseId//课程
}
2.对象
class StuMsg{
StuMsgPk;//主键类
garde ;
}
映射文件:
<composite-id name="属性名" class="属性对应的对象">
<key-property name="xxx" column="xxxx"></key-property>
...
</composite-id>
2.继承关系
O Product //产品 Book extends Product Car extends Product
integer id; String author;//作者
String name;
Double price;
R create table g_product(
p_id integer primary key,
p_name varchar2(30),
p_price number(5,2),
b_author varchar2(40),//从子类扩展的字段
p_des varchar2(30)//一个辨别列
)
映射文件
1.subclass映射策略:
整个继承树的所有实例都会保存在同一张表当中,即Product和Book的数据保存在同一张表中。为了区分数据的类型,需要在表当中添加一个列,用来描述数据的类型。
该列也称为辨别列(discriminator)
<!-- 在父类中添加辨别列的配置:指明辨别类的列名,同时类型
辨别列不是对象的属性,只是为了在数据库表中去分类的作用 -->
<discriminator column="辨别列名" type="类型" ></discriminator>
<!-- 使用sub-class映射Product的子类 Book -->
<subclass name="Book" discriminator-value="图书">
<property name="author" column="b_author"></property>
</subclass>
subclass
优点:父表和子表保存在一张表当中,查询的时候不用子查询和多表连接,性能快
缺点:对于子类的字段不能加入非空约束
2.joined-subclass映射策略
特点:父表的数据由父表保存,子表的数据由父表和子表共同保存。子类和父类共有的
属性保存在父表当中,子类扩展的属性保存在子表当中。采取该策略不需要辨别列。要为子表提供一个列【主键】映射父表的主键
表:
create table g_product( --父表--
p_id integer primary key,
p_name varchar2(30),
p_price number(4,2)
)
create table g_book( --子表--
c_id integer primary key references g_product(p_id),--与父表关联--
c_author varchar2(40)
)
映射文件
<joined-subclass name="Book" table="g_book" >
<key column="c_id"></key><!-- 外键声明 -->
<property name="author" column="c_author"></property>
</joined-subclass>
3 union-subclass映射策略
特点:父表的数据保存在父表当中
子表的数据保存在子表当中=父表的数据+子表的数据
如果保存Product,数据保存在t_product表当中
如果保存Book,数据保存在t_book表中,不会保存在t_product表中
R. create table g_product(
p_id integer primary key,
p_name varchar2(30),
p_price number(4,2)
)
--子表--
create table g_book(
p_id integer ,
p_name varchar2(30),
p_price number(4,2),
c_author varchar2(40)
);
M:映射文件