八、 映射( 重点掌握和理解,注意配置的细节)

     关联关系: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" />