八、 映射( 重点掌握和理解,注意配置的细节)
关联关系:A 有可能使用B ,则AB 之间有关联关系(Java 里指A 有B 的引用) 。
双边关系、传递性、方向性、名称、角色( 权限) 、数量(1:1 ;1:m ;n:m) 、关联强度
委托:整体跟部分之间是同一类型。
代理:整体跟部分之间不是同一类型。
A. 单一实体映射:最简单、基本映射( 最重要) ;任何其他映射种类的基础。
原则:
1. 类-> 表;一个类对应一个表。
2. 属性-> 字段:普通属性、Oid ;一个属性对应一个字段。
B. 实体关系映射:
a. 关联关系映射:( 最难、量最多)
1. 基数关系映射:
一对一(one to one) ( 共享主键、唯一外键)
一对多(one to many) (1:m) 作级联,删one 后连着删many
多对一(many to one) (m:1) 不作级联,删many 中一个,不删one
多对多(many to many)(n:m = 1:n + m:1)
2. 组件关系映射:( 一个类作为另一个类的零件,从属于另一个类,没有自己的XML)
单一组件关系映射
集合组件关系映射
b. 继承关系映射:( 最普遍。两个类有继承关系,在本质上他们就是一对一关系。共享主健。)
有三种映射方案:
1. 一个类一个表( 效率很低;最后考虑使用,一般是数据量较大和父子类重复字段不多的时候用)
只有当子类中的属性过多时才考虑每个类建一个表的策略。
2. 一个实体一个表( 多表查询效率低,不考虑多态时用)
不考虑多态时,最好是用只针对具体类建表,而考虑多态时尽量使用所有类建一个表
3. 所有类一个表( 查询效率最高,结构简单;字段数不超过100 个时使用,首选)
c. 集合映射( 值类型)
Set 不重复、无顺序
List 可重复、有顺序
Map
Bag 可重复、无顺序(bag 本身也是list 实现的)
双向关联(Bidirectional associations)( 相当于两个单向关联)
单向关联(Unidirectional associations)
" 一" 方的配置:
<!-- 表明以Set 集合来存放关联的对象,集合的属性名为orders ;一个"customer" 可以有多个"order" -->
<!-- inverse="true" 表示将主控权交给order ,由order 对象来维护关联关系,
也就是说order 对象中的关联属性customer 的值的改变会反映到数据库中 -->
<set cascade="save-update" inverse="true">
<!-- 表明数据库的orders 表通过外键customer_id 参照customer 表 -->
<key column="customer_id"/>
<!-- 指明Set 集合存放的关联对象的类型 -->
<one-to-many class="many_to_one.vo.Order"/>
</set>
" 多" 方的配置:
<many-to-one
name="customer"
class="many_to_one.vo.Customer"
column="customer_id"
not-null="true"
cascade="save-update"
/>
cascade 属性:设定级联操作( 插入、修改、删除) 。
cascad 属性值 |
描述 |
n one |
保存、更新或删除当前对象时,忽略其他关联对象,默认属性值 |
save-update |
通过 Session 的 save() 、 update() 以及 saveOrUpdate() 方法来保持、更新当前对象时级联,所有关联的新建对象,并且级联更新所有有关联的游离对象 |
delete |
当通过 Session 的 delete() 方法来删除当前对象时,级联删除所有关联对象 |
all |
包含所有的 save-update 以及 delete 行为 |
delete-orphan |
删除所有和当前对象解除关联关系的对象 |
all-delete-orphan |
包含 all 与 delete-orphan 的动作 |
inverse 属性:表示是否将当前属性的值的变化反映到数据库中去。
false --- 表示反映到数据库中
true --- 表示不反映到数据库中
Set 的lazy 属性:
A. 不设置lazy 值,默认true 现象:查询Customer 时,不会主动查询关联表Orders(SQL 语句)
B. 设置lazy=false 现象:出现查询Orders 表的SQL 语句
3 、多对多
默认情况下,由两方共同维护关联关系。也就是两个对象关联属性的值的改变都会反映到数据库中。
九、 Hibernate 控制的事务
事务保证原子操作的不可分,也就是操作的同时成功或同时失败。
hibernate 的事务隔离级别和JDBC 中大致相同。
设置时要在hibernate.cfg.xml 配置
<property>4</property>
1 : 读未提交的数据(Read uncommitted isolation) 脏读
2 : 读已提交的数据(Read committed isolation) 不可重复读
4 : 可重复读级别(Repeatable read isolation) 幻读
8 : 可串行化级别(Serializable isolation)
hibernate 的锁( 悲观锁,乐观锁)
1. 悲观锁是由数据库本身所实现的,会对数据库中的数据进行锁定,也就是锁行。( 更新期间不许其他人更改)
LockMode.UPGRADE, 修改锁,在get() 方法中加上这个设置作为第三个参数。
LockMode.NONE 无锁机制
LockMode.READ 读取锁
LockMode.WRITE 写入锁,不能在程序中直接使用
还可以使用Session.lock() Query.setLockMode() Criteria.setLockMode() 方法来设置锁,检测版本号,一旦版本号被改动则报异常。
2. 乐观锁,也就是通过对记录加上某些信息来解决并发访问的问题。( 认为更新期间不会有其他更改)
版本检查;要在其表中多加上一列表示版本信息,会在读取时读到这个版本号,并在修改之后更新这个版本号;
更新瞬间加锁,并且只有版本号相同才会予以更新,如果版本号不同,就会抛出例外。
<version column="version" />