本帖最后由 小石姐姐 于 2017-12-11 17:24 编辑
Hibernate持久化类
Persistent Object(PO)= pojo+hbm.xml
规则
必须提供无参构造
字段私有,对外提供get/set方法
OID 必须提供一个标识属性,与主键对应
属性尽量使用基本数据类型的包装类
不能使用final修饰
查询中get/load区别
两者都是根据id去查询对象
get是直接得到一个持久化类型对象, 立即查询
load是持久化类的代理了下对象,延迟查询
get查询不到返回null,load查询不到会报异常ObjectNotFoundException
主键生成策略
* hibernate主键类型包括自然主键和代理主键 * 自然主键:具有业务含义 字段 作为主键,比如:学号、身份证号
代理主键:不具有业务含义 字段作为主键(例如 自增id),比如:mysql自增主键,oracle序列生成的主键、uuid()方法生成的唯一序列串
increment---identity---sequence---native---uuid
Hibernate 持久化对象
状态
瞬时态(临时态)
一般指的是new出的对象。不存在OID 与hibernate session无关
持久态
由hibernate session管理,具有持久化标识OID,事务未提交前一直是持久态
有OID 由session管理,在数据库中有可能有,也有可有没有。
托管态(游离态)
它是指持久态对象失去了与session的关联,托管态对象它存在OID,在数据库中有可能存在,也有可能不存在。
持久化状态切换
是否有OID
判断是否与session关联
瞬时态
--->持久态 save、saveOrUpdate
--->游离态 手动设置oid
* 持久态 * 持久----->瞬时 delete() 被删除后持久化对象不在建议使用 * 持久----->脱管 注意:session它的缓存就是所说的一级缓存 * evict(清除一级缓存 中指定的一个对象) * clear(清空一级缓存) * close(关闭,清空一级缓存) * 脱管态 (它是无法直接获取) * 脱管---->瞬时 直接将oid删除 * 脱管---->持久 update saveOrUpdate lock(过时)
Hibernate 一级缓存
* 一级缓存指的是session缓存 * 二级缓存值得是sessionFactory缓存 * 一级缓存的目的 * Hibernate的一级缓存存在的目的就是为了减少对数据库访问。
actionQueue它是一个行列队列,它主要记录crud操作的相关信息
persistenceContext它是持久化上下文,它其实是真正缓存。
** 持久化对象具有自动更新数据库的能力 **
一级缓存的特点
当我们通过session的save,update saveOrupdate进行操作时,如果一级缓存中没有对象,会将这些对象从数据库中查询到,存储到一级缓存。
当我们通过session的load,get,Query的list等方法进行操作时,会先判断一级缓存中是否存在,如果没有才会从数据库获取,并且将查询的数据存储到一级缓存中。
当调用session的close方法时,session缓存清空。
一级缓存中常用API
clear 清空一级缓存.
evict 清空一级缓存中指定的一个对象。
refresh重新查询数据库,用数据库中信息来更新一级缓存与快照
udpate操作它主要是针对于脱管对象,持久对象具有自动更新能力
saveOrUpdate
如果对象是一个瞬时对象 --------执行save操作
如果对象是一个脱管对象---------执行update
如果是一个持久对象-------直接返回
delete 删除一个脱管对象,与session关联,在删除
注意:如果执行delete操作,先删除一级缓存,在删除数据库中的数据。
Hibernate 关联关系 数据对象的三种关系
* 一对多配置文件
---一的一方
<class name="com.itheima.domian.Customer" table="t_customer" >
<id name="id" column="c_id">
<generator class="identity"/>
</id>
<property name="name" column="c_name" length="20"/>
<!--
set name 属性 类中对应的是多的一方的集合字段名
cascade="save-update" 设置保存一的一方时同时保存多的一方
key:它主要描述关联的多的一方产生的外键名称,注意要与多的一方定义的外键名称相同
one-to-many 描述集合中的类型
-->
<set name="orders" cascade="save-update">
<!-- key 是多的一方的外键列名 -->
<key column="o_customer_id"></key>
<!-- 指向多的那方的类 -->
<one-to-many class="com.itheima.domian.Order"/>
</set>
</class>
----多的一方配置
<class name="com.itheima.domian.Order" table="t_order" >
<id name="id" column="o_id">
<generator class="identity"/>
</id>
<property name="money" column="o_money"/>
<property name="receiverInfo" column="o_receiverInfo" length="50"/>
<many-to-one name="customer" class="com.itheima.domian.Customer" column="o_customer_id" cascade="save-update">
</many-to-one>
</class>
在配置一的一方的包含一个多的一方的set集合时可以在 set标签上添加 inverse属性
Inverse它的值如果为true代表,由对方来维护外键。
Inverse它的值如果为false代表,由本方来维护外键。
外键在哪一个表中,我们就让哪一方来维护外键。(一般只能在一的方上写 值 true)
级联操作
cascade总结
使用cascade可以完成级联操作
它可常用取值:
none这是一个默认值
save-update,当我们配置它时,底层使用save update或save-update完成操作,级联保存临时对象,如果是游离对象,会执行update.
delete 级联删除
delete-ophan 删除与当前对象解除关系的对象。
all 它包含了save-update delete操作
all-delete-orphan 它包信了delete-orphan与all操作
笔试题:cascade与inverse有什么区别?
cascade它是完成级联操作
Inverse它只有在双向关联情况下有作用,它来指定由哪一方维护外键。
课上
* 一对多 * 原则有两种 * 唯一外键对应 * 在任意的一方添加一个外键描述对应关系 * 主键对应
Class Employee{
Private Archives archives;
}
Class Archives{
Private Employee employee;
}
* 多对一 * 在多的一方建立一的一方的外键
Class Customer{
Private Set<Order> orders;
}
Class Order{
Private Customer c;
}
* 多对多 * 建表原则,通过一张中间表描述其对应关系 Class Student{ Set<Teacher> ts; } Class Teacher{ Set<Student> ss; }
* org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.itheima.domian.Customer
* 该异常是持久化对象调用了瞬时态对象 |
|