Hibernate概述回顾
1.持久化概念
why、what、how(序列化/XML/JDBC/ORM)
2.对象关系映射(ORM)
什么是ORM?
ORM组成
ORM优点
ORM主流框架
3.Hibernate开发步骤
Hibernate项目构建
Hibernate应用组成
API应用步骤
4.Hibernate API
Session/SessionFactory/Configuration/Transaction/Query/Criteria
目标
掌握Hibernate实体映射配置技巧
掌握Hibernate内置ID生成器
掌握Hibernate数据类型
理解Hibernate对象生命周期
熟悉Hibernate对象三种状态
熟练应用Hibernate对象状态转换
知识点预览
Hibernate映射基础
Hibernate内置ID生成器
Hibernate数据类型
Hibernate对象生命周期
映射概述和生成器
1.映射概述
a)对象和关系数据库之间的映射通常是用一个XML文档定义
b)这个映射文档被设计为易读的, 并且可以手工修改
c)映射语言是以Java为中心,这意味着映射文档是按照持久化类的定义来创建的, 而不是表的定义
2.包含内容
a)实体映射技术作为类与表之间的联系纽带,在ORM实现中起着至关重要的作用。
b)对于Hibernate用户而言,映射关系更多地体现在配置文件的维护过程中。
c)Hibernate选用XML作为映射配置文件的基础形式。
d)实体映射的核心内容,即实体类与数据库表之间的映射定义。Hibernate中,类表映射主要包括:
e)类/表映射
f)主键id映射
g)属性/字段映射
h)复合主键映射
3.Hibernate映射
<hibernate-mappingschema="schemaName" (1)
catalog="catalogName"(2)
default-cascade="cascade_style"(3) default-access="field|property|ClassName"(4)
default-lazy="true|false"(5)
auto-import="true|false"(6)
package="package.name"(7) />
4.Hibernate映射节点参数说明
schema (可选): 数据库schema的名称。
catalog (可选): 数据库catalog的名称。
default-cascade(可选 - 默认为 none): 默认的级联风格。
default-access (可选 - 默认为 property): Hibernate用来访问所有属性的策略。可以通过实现PropertyAccessor接口 自定义。
default-lazy (可选 - 默认为 true): 指定了未明确注明lazy属性的Java属性和集合类, Hibernate会采取什么样的默认加载风格。
auto-import (可选 - 默认为 true): 指定我们是否可以在查询语言中使用非全限定的类名(仅限于本映射文件中的类)。
package (可选): 指定一个包前缀,如果在映射文档中没有指定全限定的类名,就使用这个作为包名。
5.Class映射
a)XML配置
<class name="ClassName"
table="tableName"
dynamic-update="true|false"
dynamic-insert="true|false"
batch-size="N"
optimistic-lock="none|version|dirty|all"
lazy="true|false"
/>
b)Class映射节点参数说明
6.主键(id)映射
a)被映射的类必须定义对应数据库表主键字段
b)<id>元素定义了该属性到数据库表主键字段的映射
c)XML配置
<idname="propertyName"
type="typename"
column="column_name"
unsaved- value="null|any|none|undefined|id_value"access="field|property|ClassName">
<generatorclass="generatorClass"/>
</id>
d)Id映射节点参数说明
e)生成器
i.<generator>子元素是一个Java类的名字, 用来为该持久化类的实例生成唯一的标识
ii.如果这个生成器实例需要某些配置值或者初始化参数, 用<param>元素来传递
iii.XML配置
<generatorclass=“org.hibernate.id.TableHiLoGenerator”>
<paramname=“table”>uid_table</param>
<paramname="column">next_hi_value_column</param>
</generator>
iv.所有的生成器都实现org.hibernate.id.IdentifierGenerator接口
v.Hibernate提供了一系列内置的实现
vi.下面是一些内置生成器的快捷名字:
incrementidentity sequence hiloseqhilo
uuid guidnative assigned selectforeign
f)assigned
i.主键由应用逻辑产生
ii.数据交由Hibernate保存时,主键值已经设置完成
iii.这是<generator>元素没有指定时的默认生成策略
g)hilo
i.通过hi/lo算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态
<id name="id" type="long"column="cat_id">
<generator class="hilo">
<param name="table">hi_value</param>
<param name="column">next_value</param>
<param name="max_lo">100</param>
</generator>
</id>
h)seqhilo
i.seqhilo适用于支持Sequence的数据库,如Oracle
<id name="id"type="long" column="cat_id">
<generator class="seqhilo">
<paramname="sequence">hi_value</param>
<paramname="max_lo">100</param>
</generator>
</id>
i)identity
i.Identity:采用数据库提供的主键生成机制,如DB2,MySQL, Sybase, MS SQL Server中的自增长主键生成机制
ii.自增长方式生成的主键实现机制:当前应用实例中维持一个变量,保存着当前最大值,之后每次需要生成主键时将此值加1多个应用实例不宜选择
j)sequence
i.Sequence:采用数据库提供的sequence机制生成主键,如在DB2, Oracle, PostgreSQL, Interbase, McKoi, SAP DB中使用序列
ii.此方式只能供提供sequence机制的数据库使用
iii.selectnext_value 增加开销
k)native
i.Native:由Hibernate根据数据库适配器(Dialect)中的定义,自动采用identity、hilo、sequence的其中一种作为主键生成方式比较灵活
ii.SQLServcer,MYSQL采用identity方式
iii.Oracle采用sequence方式,若不指定sequence名称,默认采用hibernate_sequence
l)uuid.hex
i.用一个128-bit的UUID算法生成(根据IP,时间,JVM启动时间,内部自增量等4个参数生成)字符串类型的标识符, 这在一个网络中是唯一的(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串
m)uuid.string
i.与uuid.hex类似,只是生成的主键未进行编码(长度为16),在某些数据库中可能会出现问题(如Postgre SQL)
n)foreign
i.使用外部表的字段作为主键
7.属性(property)
a)<property>元素为类定义了一个持久化的,JavaBean风格的属性
b)XML配置
<property name=“propertyName”
column=“column_name”
type=“typename”
update=“true|false”
insert=“true|false”
formula=“arbitrarySQLexpression”access=“field|property|ClassName”
lazy=“true|false”
unique=“true|false”not-null=“true|false”
optimistic-lock=“true|false” index="index_name"
unique_key="unique_key_id"
length="L"
precision="P" />
c)Property映射节点参数说明
Hibernate数据类型
1.Hibernate数据类型
a)实体映射关系定义,需提供属性的数据类型设定,通过这些类型定义,Hibernate即可完成java数据类型到数据库特定类型的映射关联
b)<property name=“userAge”type=“integer” column=“age”/>
c)Hibernate提供丰富的数据类型支持
基本数据类型(integer/String/Date)
JDBC类型(Blob/Clob)
自定义数据类型
2.基本类型
3.大数据类型
4.自定义值类型
a)开发者创建属于他们自己的值类型也是很容易的
b)比如说,你可能希望持久化java.lang.BigInteger类型的属性,持久化成为VARCHAR字段
c)定义类型能够映射一个属性(或集合元素)到不止一个数据库表字段,你可能有这样的Java属性:getName()/setName(),这是java.lang.String类型的,对应的持久化到三个字段:FIRST_NAME, INITIAL,SURNAME
d)要实现一个自定义类型,可以实现org.hibernate.UserType或org.hibernate.CompositeUserType中的任一个
Hibernate对象生命周期
1.对象生命周期
a)对象生命周期:一个对象从被创建开始,到不再使用,被垃圾回收期回收为止。
b)一个持久化类的实例可能处于三种不同状态中的某一种。这三种状态的定义则与所谓的持久化上下文(persistencecontext session对象)有关:
瞬时状态(Transient) new User();只存在于内存
持久状态(Persistent)DB/Session/内存
脱管状态(Detached)游离 DB/内存 Session无
c)Hibernate的Session对象就是这个所谓的持久化上下文
2.瞬时对象
a)由new操作符创建,且尚未与HibernateSession 关联的对象被认定为瞬时(Transient)的
b)瞬时(Transient)对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier)
c)如果瞬时(Transient)对象在程序中没有被引用,它会被垃圾回收器(garbage collector)销毁
d)使用Hibernate Session可以将其变为持久(Persistent)状态
3.持久对象
a)持久(Persistent)的实例在数据库中有对应的记录,并拥有一个持久化标识(identifier)
b)Hibernate会检测到处于持久(Persistent)状态的对象的任何改动,在当前操作单元(unit of work)执行完毕时将对象数据(state)与数据库同步(synchronize)
c)在默认情况下,Hibernate会在UPDATE中包含所有的列
d)如果只更新那些被修改的列,可以通过修改配置dynamic-update=”true”来实现
4.脱管对象
a)实例曾经与某个持久化上下文发生过关联,不过那个上下文被关闭了,或者这个实例是被序列化(serialize)到另外的进程。它拥有持久化标识,并且在数据库中存在一个对应的行
b)脱管(Detached)对象不在持久化管理(session)之内,但对脱管对象的引用依然有效,对象可继续被修改
c)Detached状态的对象可以再次与某个Session实例相关联而成为Persistent对象
5.Hibernate对象状态区别
6.Hibernate对象状态转换
7.对象状态管理—Transient->Persistent
a)新实例化的持久化类对象是瞬时(Transient)的。我们可通过将瞬时(Transient)对象与session关联而把它变为持久(Persistent)的
b)通过调用save(), persist() or saveOrUpdate()方法把transient实例持久化,这个对象就和当前的Session产生了关联,当commit()方法被调用的时候,持久化对象的修改会被同步到数据库
c)对象持久化代码片段
public class Test {
public static void main(String[] args) {
User user = new User();//Transient 对象
user.setUserName("zz");
user.setUserAddress("beijing");
user.setUserAge(21);
Configuration cfg = new Configuration().configure();
try {
sf = cfg.buildSessionFactory();
s = sf.openSession();
tran = s.beginTransaction();
s.save(user);//Transient对象user变成Persistent对象
tran.commit();// )Transient对象user变成Persistent对象
} catch (HibernateException e) {
e.printStackTrace();
tran.rollback();//step6:回滚事务
}finally{
if(s!=null){s.close();}if(sf!=null){sf.close();}//step7:释放资源
}
}
}
8.对象状态管理—Detached—>Persistent
a)update() 或saveOrUpdate()方法 强制更新对象在数据中的持久化状态
b)调用lock() 方法把对象和Session关联起来,不强制更新
c)在lock()方法之前做的改变不会被更新到数据库
d)当确定脱管实例还没有被 修改时才使用lock()方法
e)对象持久化代码片段
public void update(){
try{
//ses.lock(c, LockMode.READ);
user.setUserName(“william");
user.setUserAge(27);
s.update(user); //如果使用了lock()方法,没有必要调用update()
tx.commit();
}catch(HibernateException he){
tx.rollback();
throw he;
}finally{
s.close();
}
}
9.持久态对象自动更新
a)通过load()/get()方法或者其他查询来获取的持久化对象都和当前的Session和事务相关联。这个对象可以被修改并且会被同步到数据库。这种机制被称为自动脏数据检测
b)Session缓存机制:
i.对象的加载,首先查看缓存中是否有该对象,如无,先加载到Session缓存中,在copy一份到内存中,再次加载时,会直接从缓存中读取;
ii.操作单元执行完毕后,把内存中对象和缓存中对象比较,改动部分更新到数据库中
c)持久态对象更新代码样例
public void peristentDirtyCheck(){
try{
//查找获得persistend对象user
User user = (User)s.load(User.class, uid);
//将user变成脏对象
user.setUserName(“jeery");
//ses.update(c);
tx.commit(); //自动更新数据库中的记录
}catch(HibernateException he){
tx.rollback(); throw he;
}finally{s.close();}
}
10.读取对象
a)如果你知道某个实例的持久化标识(identifier),你就可以使用Session的load(),get()方法 来获取它
b)请注意如果没有匹配的数据库记录,load()方法可能抛出无法恢复的异常(unrecoverableexception)
c)如果你不确定是否有匹配的行存在,应该使用get()方法,它会立刻访问数据库,如果没有对应的记录,会返回null
d)读取对象代码样例
public void get(){
try{
user = (User)s.get(User.class, uid);
tx.commit();
}catch(HibernateException he){
tx.rollback();
throw he;
}finally{
s.close();
}
}
11.对象状态管理-Persistent->Transient
a)使用Session.delete()会把对象的状态从数据库中移除
b)如果瞬时(Transient)对象在程序中不再被引用,它会被垃圾回收器(garbage collector)销毁
c)代码样例
public void delete(){
try{
user = (User)s.get(User.class, uid);
s.delete(user);
tx.commit();
}catch(HibernateException he){
tx.rollback();
throw he;
}finally{
s.close();
}
}
12.对象状态管理-Persistent->Detached
a)使用Session.close()会把session关闭,对象也不在session的管理下
b)使用Session.clear()会把所有对象从session中移除
c)使用Session.evict(Object o)会把对象o从session中移除
d)代码样例
public void clear(){
try{
user = (User)s.get(User.class, uid);
s.evict(user);//1、User脱离Session管理
s.clear();// 2、 User脱离Session管理
tx.commit();
}catch(HibernateException he){
tx.rollback();
throw he;
}finally{
s.close(); //3、 User脱离Session管理
}
}
总结
Hibernate映射基础
Hibernate-mapping/class/id/generator/property
Hibernate内置ID生成器
Hibernate内置ID生成器、自定义ID生成器
Hibernate数据类型
基本数据类型、JDBC数据类型、自定义数据类型
Hibernate对象生命周期
三种状态特征、区分、转换,持久态对象特性
问题
课堂代码片段完善
Hibernate内置ID生成器练习
对象生命周期状态转换练习