一.持久化类的概述
- 持久化: 将内存中的一个对象持久化到数据库中的过程. Hibernate框架就是用来进行持久化的框架
- 持久化类: 一个Java对象与数据库的表建立了映射关系,那么这个类在Hibernate中称为是持久化类
- 编写规则:
-1- 对持久化类提供一个无参数的构造方法 : Hibernate底层需要使用反射生成实例
-2-属性需要私有,对私有属性提供public的get和set方法 : Hibernate中获取,设置对象的值
-3- 对持久化类提供一个唯一标识OID与数据库主键对应 : Java中通过对象的地址区分是否是同一个对象,数据库通过主键
确定是否是同一个记录,在Hibernate中通过持久层的OID的属性区分是否是同一个对象
-4-持久化类中属性尽量使用包装类类型 :因为基本数据类型默认是0,0会有很多的歧义.包装类默认是null
-5-持久化类不要使用final进行修饰 :延迟加载时Hibernate一个优化的手段,返回的是一个代理对象(
javassist可以对没有实现接口的类产生代理---使用了非常底层字节码增强技术,继承这个类进行代理).如果不能被继承
,不能产生代理对象,延迟加载也就失效,load方法和get方法一致.
二.主键生成策略
- 主键的分类
- 自然主键 : 主键的本身就是表中的一个字段(实体中的一个具体的属性)
-1-创建一个人员表,人员都会有一个身份证号(唯一不可重复的),使用身份证号作为主键,这种主键被称为自然主键. - 代理主键 : 主键的本身不是表中必须的一个字段(不是实体中的某个具体的属性)
-1-创建一个人员表,没有使用人员中的身份证号,用了一个与这个表不相关的字段ID,(PNO),这种主键被称为代理主键 - 在实际开发中,尽量使用代理主键
-1-一旦自然主键参与到业务逻辑中,后期有可能需要修改原代码
-2-好的程序设计满足OCP原则,对程序的扩展是open的,对修改源码是close的
- 自然主键 : 主键的本身就是表中的一个字段(实体中的一个具体的属性)
- 主键的生成策略
在实际开发中一般不允许用户手动设置主键,一般将主键交给数据库,手动编写程序进行设置.在Hibernate中为了减
少程序编写,提供了很多种的主键的生成策略- increment : hibernate中提供的自动增长机制,适用short,int,long类型的主键,在单线程程序中使用
-1-首先发送一条语句 : select max(id) from 表; 然后让id+1作为下一条记录的主键 - identity : 适用short,int,long类型的主键,使用的是数据库底层的自动增长机制,适用有自动增长的数据库(MYSQL,
MSSQL)但是Oracle是没有自动增长 - sequence : 适用short,int,long类型的主键,采用的是序列的方式(Oracle支持序列)
- uuid : 适用于字符串类型主键,使用hibernate中的随机方式生成字符串主键
- native : 本地策略,可以在identity和sequence之间进行自动切换
- assigned : hibernate放弃外键的管理,需要通过手动编写程序或者用户自己设置
- foreign : 外部的,一对一的一种关联映射的情况下使用
- increment : hibernate中提供的自动增长机制,适用short,int,long类型的主键,在单线程程序中使用
三.持久化类的三种状态
Hibernate是持久化框架,通过持久化类完成ORM操作. Hibernate为了更好的管理持久化类,将持久化类分为三种状态
- 瞬时态
这种对象没有唯一的标识OID,没有被session管理,称为是瞬时态对象 - 持久态
这种对象有唯一标识OID,被session管理,称为是持久态对象
-1-持久化类的持久态的对象,可以自动更新数据库 - 脱管态
这种对象有唯一标识OID,没有被session管理,称为脱管态对象
四.一级缓存
- Hibernate框架中 提供了优化手段 : 缓存,抓取策略, 提供了两种缓存机制 : 一级缓存,二级缓存
- Hibernate的一级缓存 : 是Session级别的缓存,生命周期与Session一致(一级缓存是由Session中的一系列的Java集合构成)
一级缓存是自带的不可卸载的. (Hibernate的二级缓存是SessionFactory级别的缓存,需要配置的缓存) - 一级缓存中特殊区域: 快照区
五.事务管理
- 事务: 指逻辑上的一组操作,组成这组操作的各个逻辑单元要么全部成功,要么全都失败
- 事务特性: 原子性,一致性,隔离性,持久性
- 如果不考虑隔离性,引发安全性问题
读问题
脏读 : 一个事务读到另一个事务还未提交的数据
不可重复读 : 一个事务读到另一个事务已经提交的update数据,导致在前一个事务多次查询结果不一致
虚读 : 一个事务读到另一个事务已经提交的insert数据,导致在前一个事务多次查询结果不一致
写问题
引发两类丢失更新 - 读问题的解决
设置事务的隔离级别:
Read uncommitted 1
Read committed 2
Repeatable read 4
Serializable 8
六.Hibernate中设置事务隔离级别
- 在核心配置文件中,hibernate.cfg.xml 的 <session-factory>
<!-- 设置事务隔离级别 -->
<property name="hibernate.connection.isolation">4</property>
七.事务管理
Service中封装业务逻辑操作,必须要保证连接对象是同一个.
- -向下传递 , DAO中获取Service中的连接
- - 使用ThreadLocal对象 : 将该连接与当前线程绑定,在DAO的方法中,通过当前的线程获得连接对象
- Hibernate框架内部已经绑定好了ThreadLocal
* 在SessionFactory中提供了一个方法getCurrentSession();
* 通过一个配置完成 - 线程绑定的Session
<!-- 配置当前线程绑定的Session -->
<property name="hibernate.current_session_context_class">thread</property> - Session getCurrentSession(); //在工具类中提供一个方法
八.其他的API
- Query
- Query接口用于接收HQL,查询多个对象
- HQL: Hibernate Query Language :这种语言与SQL的语法极其类似,面向对象的查询语言
- Criteria : QBC (Query By Criteria)
- 更加面向对象的一种查询方式.
- SQLQuery
- 用于接收SQL,特别复杂情况下使用SQL