持久化
将内存中的数据存入数据库中,Hibernate是进行持久化的框架。
持久化类
使得java对象与数据库的表建立映射关系。这个类在Hibernate里面可被称作持久化类
持久化类编写规则
- 包含无参的构造函数: Hibernate底层需要使用反射生成实例
- 属性私有,但是相应的get/set方法共有:Hibernate需要获取值
- 提供与数据库内表的主键相对应的唯一标识OID: Java中通过对象的地址区分是否是同一个对象,数据库中通过主键确定是否是同一个记录,在Hibernate中通过持久化类的OID的属性区分是否是同一个对象。
- 属性尽量使用包装类型(integer):基本类型(int)的默认值为0,而包装类型的默认值为long, 包装类型可以对应数据库中的NULL,而基本类型不能表达出null的含义。
- 不要使用final进行修饰: Hibernate中的延迟加载是其优化手段,返回的是一个代理对象,使用final后这个对象不能被继承,将使得延迟加载失效。
主键
主键的分类
- 自然主键:主键的本身是表中必须的一个字段(实体中的一个具体的属性)
- 代理主键:主键的本身不是表中必须的字段(不是实体中某个具体的属性)
在开发中一般选择代理主键:
1. 使用自然主键,会导致后期维护困难,反复修改源代码
2. 程序设计应该满足OCP原则(开闭原则):一个软件实体应该通过扩展来实现变化,而不是通过修改已有代码来实现变化
主键的生成策略
- increment : Hibernate的自动增长机制,没有采用数据库底层增长,适用于short、int、long类型主键,只用于单线程中 。
- identity : 数据库底层的增长机制,适用于short、int、long类型主键,用于有自动增强机制数据库中,Oralce等没有自动增强机制的数据库不适用
- sequence : 采用序列的方式,适用于short、int、long类型主键,用于支持序列的数据库如Oracle。
- uuid : 适用于字符串类型的主键,使用hibernate中的随机方式生成字符串主键。
- native:本地策略,可根据数据库自动在identity、sequence间切换。
- assigned : Hibernate放弃对主键的管理
- foreign : 一对一映射的情况下使用
持久化的三种状态与转化
关系图:
- 瞬时态:没有OID标识,不被session管理。
获得:new一个实体对象时处于该状态
→持久态: save(Object o)、saveOrUpdate(Object o)(执行save)
→托管态: 类名.setCstr_id(Long long); - 持久态:有OID标识,被session管理。
获得:
session.get();
session.load();
session.find(…);
session.Iterate(…);
→瞬时态: session.delete(…)
→托管态:session.close(); clear(); evict(Object o); - 托管态:有OID标识,不被session管理
获得: session.close();
→瞬时态: 类名.setCstr_id(null);
→持久态: update(Object o)、saveOrUpdate(Object o)(执行update)
需要特别注意:持久态可自动更新数据库,即不执行session.save()数据也会更新,因为它依赖于底层的一级缓存。
Hibernate缓存
分类
- 一级缓存:处于session级别,生命周期与session一致,有Hibernate自带且不可卸载的
- 二级缓存: SessionFactory级别,默认不可开启,开启需要配置,一般不使用,可由redies替代
一级缓存区的管理
1、clear() :清空一级缓存中所有的对象.
2、evict(Object obj) : 清空一级缓存中某个对象.
3、flush() :刷出缓存.
4、refresh(Object obj):将快照区的数据重新覆盖了一级缓存的数据.
5、save(): 可以向一级缓存中存放数据
一级缓存中的特殊区——快照区
当事务提交时,缓存数据与快照区的数据进行比较,数据不同时自动更新数据库,保证了数据库的一致性
Hibernate其他API
- Query : 用于接收HQL(Hibernate Query language),HQL是Hibernate查询语言,与SQL语言类似,是一种面向对象的查询语言
- Criteria : QBC( Query By Criteria ),更加面向对象的一种查询方式
- SQLQuery: 接收SQL语句,SQL查询情况复杂的情况下使用