什么是持久化
持久化:将内存中的一个对象持久化到数据库中的过程,Hibernate框架就是用来进行持久化的框架
持久化类:一个java对象与数据库的表建立了映射关系,那么这个类在Hibernate中称为持久化类
持久化类的编写规则
- 对持久化类提供一个无参的构造方法
Hibernate底层需要使用反射生成实例 - 属性需要私有,对私有属性提供public的get和set方法
Hibernate需要获取和设置对象的值 - 对持久化类提供一个唯一标识OID与数据库主键对应
java找那个通过的地址区分是否是同一个对象,数据库总通过主键确定是否是同一个记录,在Hibernate中通过持久化类的OID的属性区分是否是同一个对象 - 持久化类中属性尽量使用包装类类型 :
因为基本数据类型默认是0,那么0就会有很多的歧义,包装类类型默认值是null - 持久化类不要使用final修饰:
- 延迟加载本身是Hibernate一个优化的手段,返回的是一个代理对象(javassist可以对没有实现接口的类产生代理-----使用了非常底层字节码增强技术,继承这个类进行代理)。如果不能被继承,不能产生代理对象,延迟加载也就失效,load方法和get方法一致。
主键生成策略
- 主键分类
1.自然主键,主键的本身就是表中的一个字段(实体中一个具体的属性)
2.代理主键,主键的本身不是表中必须的一个字段(不是实体中的某个具体的属性)
在实际开发中,尽量使用代理主键
一旦自然主键参与到业务逻辑中,后期有可能需要修改源代码
好的程序设计满足OCP原则,对程序的扩展是open,对修改源码是close的 - Hibernate的主键生成策略
- increment:Hibernate中提供的自动增长机制,适用short、int、long类型的主键,在单线程程序中使用
- identity:适用short、int、long类型的主键,使用的是数据库底层的自动增强机制,适用于有自动增强机制的数据库(MYSQL,MSSQL),但是Oracle没有自增长
- sequence:适用short、int、long类型的主键,采用的是序列的方式,Oracle支持序列
- uuid:适用于字符串类型的主键
- native:本地策略,可以在identity和sequence之间进行自动切换
- assigned:Hibernate放弃外间的管理,需要手动编写程序或者用户自己设置
- foreign:外部的,一对一的一种关联映射的情况下使用
持久化类的三种状态
- 瞬时态:
这种对象没有唯一的标识OID,没有被session管理 - 持久态:
这种状态有唯一的OID,被session管理
持久态对象能够自动更新数据库 - 脱管态:
这种对象有唯一标识OID,没有被session管理
Hibernate的一级缓存
- 缓存:介于应用程序和永久性数据存储源之间,作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能
Hibernate框架中提供了优化手段:缓存、抓取策略。
- Hibernate的一级缓存,称为Session级别的缓存,一级缓存生命周期和Session一致(一级缓存是由Session中的一系列的java集合构成)。一级缓存是自带的不可卸载的(Hibernate的二级缓存是SessionFactory级别的缓存,需要配置的缓存)
- 作用:减少对数据库的访问
- 特殊区域:快照区
-
Hibernate中的事务管理
在hibernate.cfg.xml文件中配置,设置事务的隔离级别:
1:读未提交
2:读已提交
4:不可重复读
8:可串行化<propert name="hibernate.connection.isolation">4</property>
-
保证Service中开启的事务使用的Session对象和DAO中多个操作使用的是同一个Session对象
实现方法:- 可以在业务层获取到Session,并将Session作为参数传递给DAO。
- 可以使用ThreadLocal将业务层获取的Session绑定到当前线程中,然后再DAO中获取Session的时候,都从当前线程中获取。
最优方案是第二种,Hibernate已经帮我们做完了,只需要在在hibernate.cfg.xml文件中配置:
<!-- 配置session绑定本地线程 -->
<property name="hibernate.current_session_contest_class">thread</property>
在HibernateUtils工具类中更改getCurrentSession方法:
//获取当前线程绑定的会话
public static Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}