【03】框架学习—Hibernate持久化类/持久化对象的状态/事务与并发/查询方式

来源:互联网 发布:知轩藏书网 编辑:程序博客网 时间:2024/05/16 05:18

1.Hibernate的持久化类

1)什么是持久化类    持久化类,一个Java类,该类与表建立了映射关系。即:持久化类=JavaBean+xxx.hbm.xml2)持久化类编写规则提供一个无参的公有的构造器(可供底层进行反射)。提供一个标识属性,映射数据表主键字段(作为唯一标识OID,J持久化类通过唯一标识OID确定记录)。所有属性提供public访问控制符的set/get方法。标识属性可以是基本数据类型时尽量使用包装类型。3)区分自然主键和代理主键自然主键:对象本身的一个属性,如人的身份证号。代理主键:不是对象本身的一个属性,建表时额外增添用来作为唯一标识。结论:尽量使用代理主键。4)主键的生成策略increment:适用于shot、int、long等整型作为主键,不是使用的数据库自动增长机制。Hibernate中提供的一种增长机制:先查询max(id),然后使用max(id)+1作为新纪录的主键。Identity:适用于shot、int、long等整型作为主键,采用的是数据库底层的自动增长机制。自动增长机制(auto_increment),像Oracle数据库则不适用。Sequence:适用于shot、int、long等整型作为主键,底层采用的是序列的增长方式。Oracle底层没有自动增长,所以通过序列实现。Native:适用于shot、int、long等整型作为主键,本地策略,自动选择适用于数据库的生成策略。Native像是identity与sequence的结合体。uuid:适用于char,varchar等字符串型作为主键。使用随机的字符串作为主键。assigned:表示手动设置主键。

小结:主要记住native与uuid。

2.Hibernate持久化对象的状态

1)持久化对象的状态    Hibernate为了管理持久化类,将持久化类分成了三个状态。        瞬时态:Transient Object        没有持久化标识oid,没有被纳入到Session对象的管理(管理指进入Session对象的一级缓存中)。        持久态:Persistent Object        有持久化标识oid,已经被纳入到Session对象的管理。        注意:持久化持久态的对象有自动更新数据库的能力!!!        脱管态:Detached Object        有持久化标识oid,没有被纳入到Session对象的管理。因为此时Session对象的缓存已经被清除。    示例如下:

这里写图片描述

2)Hibernate的持久化类的状态的转换

这里写图片描述
注意:持久态对象有自动更新数据库的能力!!!
示例如下:
这里写图片描述

3)Session对象的一级缓存(★★★)    什么是缓存?    一块内存空间,将数据源(数据库或文件)中的数据存放到缓存中,再次获取时可直接从缓存中获取,提升性能。    Hibernate框架提供了两种缓存:    一级缓存:自带的、不可卸载的。一级缓存的生命周期与session一致,被称为session级别的缓存。    二级缓存:默认没有开启,需要手动配置才能使用。二级缓存可以在多个session中共享,是SessionFactory级别的缓存。    Session对象的缓存概述:    Session接口中,有一系列的Java的集合,这些集合构成了Session级别的缓存(一级缓存)。将对象存入到一级缓存中,session没有结束生命周期,那么对象在session中存放着。    内存中包含Session实例 -> 是Session的缓存(集合) -> 集合中包含的是缓存对象    证明一级缓存的存在:使用同一个Session对象两次查询相同数据。

这里写图片描述

Hibernate框架如何做到数据发生变化时同步操作呢?快照机制(Snapshot)。接下来拿上面“持久化对象具有自动更新数据库能力”的例子进行分析:

这里写图片描述

4)控制Session的一级缓存(了解)    Session.clear():清空缓存。    Session.evict(Object entiry):从一级缓存中清楚指定的实体对象。    Session.flush():刷新缓存,手动去比较缓存区域与快照区域的数据。

3.Hibernate中的事务与并发

1)事务相关的概念    什么是事务?    事务就是逻辑上的一组操作,组成事务的各个执行单元,操作要么全部成功,要么全部失败。    如转账:a转账给b。a扣钱,b加钱。这两个操作组成了一个事务。    事务的特性(★):    原子性:事务不可分割。    一致性:事务执行的前后数据的完整性保持一致。    隔离性:一个事务执行时不受到其它事务的干扰。    持久性:事务一旦提交,数据永久保存到数据库中。    如果不考虑隔离性,引发一些读的问题(★):    脏读:一个事物读到另一个事务未提交的数据(如:回滚引发的)。    不可重复读:一个事务读到另一个事务已经提交的update数据,导致多次查询结果不一致。    虚读:一个事务读到另一个事务已经提交的insert数据,导致多次查询结构不一致。    通过设置数据库的隔离级别来解决上述读的问题:    未提交读:无法避免任何读的问题。    已提交读:避免脏读。    可重复读:避免脏读、不可重复读。    串行化:以上读的情况都可以避免。    如果想在Hibernate的框架中来设置隔离级别,需要在hibernate.cfx.xml的配置文件中通过标签来设置:    通过如:hibernate.connection.isolation=4(表示隔离级别为已提交读)来配置    取值        1:Read uncommitted isolation        2:Read committed isolation        4:Repeatable read isolation        8:Serializable isolation2)丢失更新    如果不考虑隔离性,也会产生写入数据的问题,这一类问题称丢失更新。    示例:

这里写图片描述

    解决方案有两种:    悲观锁:采用的是数据库提供的一种锁的机制,在Sql语句的后面添加 for update 子句。    乐观锁(推荐):采用版本号的机制来解决。给表结构添加一个字段version,默认值是0。        更新数据时须获取的版本号与当前版本号相同才能更新成功。    使用Hibernate框架解决丢失更新的问题:    悲观锁:使用如:session.get(Customer.class, 1, LockMode.UPGREADE)方法    乐观锁:①在对应的JavaBean中添加一个属性,并提供get/set。②在映射文件中使用标签<version name=”” />

这里写图片描述

3) 绑定本地的Session(★)    Hibernate框架中使用Session对象开启事务,并提供了ThreadLocal的方式传递Session对象。    需要在hibernate.cfg.xml的配置文件中提供配置:

这里写图片描述

    从当前线程中获取Session对象:

这里写图片描述

注意:获取的Session对象不用手动关闭,线程结束时会自动关闭。

4.Hibernate框架的查询方式

1)Query查询接口

这里写图片描述

    或者:(起别名)

这里写图片描述

2)Criteria(适合条件查询)

这里写图片描述