Hibernate概述:
Hibernate是一个持久层的ORM的映射框架
ORM(Object Relational Mapping):
对象关系映射,将Java中一个对象与数据库中表建立映射关系,从而操作对象就可以操作表
Hibernate优点:
• 简化JDBC的开发
• 性能很好
Hibernate常用API:
Configuration
加载配置文件
SessionFactory
内部维护连接池,配置C3P0连接池,自定义工具类。
Session
维护一级缓存,与数据库交互桥梁
常用方法
save(Object obj)
get()/load() (区别)
update()
delete()
saveOrUpdate()
Transaction
commit()
rollback()
入门小案例:https://blog.csdn.net/Auuuuuuuu/article/details/86767294
持久化类的编写规则
持久化:将内存中的一个对象持久化到数据库中过程
持久化类:一个Java对象与数据库的表建立了映射关系,那么这个类在Hibernate中被称为持久化类
持久化类 = Java类 + 映射文件
规则:
• 对持久化类提供一个无参的构造方法(Hibernate底层需要使用反射生成实例)
• 属性私有,对私有属性提供Public的Get和Set方法(Hibernate中获取,设置对象的值)
• 对持久化类提供一个唯一表示的OID与数据库主键对应 (Java中通过对象的地址区分是否是同一个对象,数据库中通过主键确定是否是同一个记录,在Hibernate中通过持久化类的OID的属性区分是否是同一个对象)
• 持久类中属性尽量使用包装类类型(基本数据类型(int,double)默认是0,有歧义,包装类类型(Integer,Double)默认 值为null )
• 持久化类不要使用final进行修饰
(延迟加载本身是Hibernate的优化手段,返回一个代理对象
(javassist可以对没有实现接口的类产生代理----使用了非常底层字节码增强技术,继承这个类进行代理),
如果不能被继承,不能产生代理对象,延迟加载就会失效,load方法和get方法就一致了)
主键的分类
自然主键: 就是充当主键的字段本身具有一定的含义,是构成记录的组成部分,比如学生的学号,除了充当主键之外,同时 也是学生记录的重要组成部分。
eg:人员表中,身份证号(唯一,不可重复)作为主键,这种主键称为自然主键
代理主键: :就是充当主键的字段本身不具有业务意义,只具有主键作用,比如自动增长的ID
eg:人员表中,使用一个不相关的字段(id,pno . . . ),这种主键称为代理主键
实际开发中,尽量使用代理主键 ( 一旦自然主键参与到业务逻辑中,后期有可能需要修改源代码,好的程序满足OCP原则, 对程序的扩展是open的,对修改代码是close的)
主键的生成策略
在实际开发中一般不允许用户手动设置主键,一般将主键交给数据库,手动编写程序进行设置。在Hibernate中为了减少程序 的编写,提供了多种主键的生成策略。
• increment :Hibernate中提供的自动增长机制,适用于short、int、long类型的主键。在单线程程序中使用。
原理:首先发送一条语句:select max(id) from 表,然后让 id+1 作为下一条记录的主键。
• identity:适用short、int、long类型的主键,使用的是数据库底层的自动增长机制。适用于有自动增长机制的数据库
( mysql, mssql) 但是Oracle是没有自动增长的
• sequence :适用于short、int、long类型的主键,使用的是序列的方式。(Oralce、PSQL、DB2支持序列)mysql不支持
• uuid : 适用于字符串类型主键,使用Hibernate中的随机方式生成字符串主键
• native :本地策略,可以在identity和sequence之间进行自动切换
• assigned : Hibernate放弃外键的管理,需要通过手动编写程序或者用户自己设置
持久化类的三种状态
Hibernate为了更好的管理持久化类,将持久化类分为三种状态。
瞬时态:这种对象没有唯一的标识OID,没有被Session管理,称为是瞬时态对象。
持久态:这种对象有唯一的标识OID,被Session管理,称为是持久态对象
持久化类的持久态对象,可以自动更新数据库(一级缓存)
脱管态:这种对象有唯一的标识OID,没有被Session管理,称为脱管态对象
三种状态转换图:
Hibernate缓存:
Hibernate框架提供的优化手段:缓存,抓取策略。Hibernate中提供了两种缓存机制,一级缓存,二级缓存。
一级缓存:称为Session级别的缓存,一级缓存生命周期与Session一致(一级缓存是由Session中一系列的Java集合构成的),一级缓存是自带的不可卸载的(Hibernate二级缓存是SessionFactory级别的缓存,需要配置的缓存(redis缓存代替))
Hibernate的事务管理
事务:逻辑上的一组操作,组成这种操作的各个逻辑单元要么全都成功,要么全都失败
事务特性
• 原子性:代事务物不可分割
• 一致性:代表事务的执行前后,数据的完整性保存一致
• 隔离性:代表一个事务执行的过程中,不应当受到其他事务的干扰
• 持久性:代表事务执行完成后,数据就持久到数据库中
隔离引发的安全问题
脏读:一个事务读到另一个事务未提交的数据
不可重复读:一个事务读到另一个事务已经提交的update数据,导致在前一个事务多次查询结果的不一致
虚读:一个事务读到另一个事务已经提交的insert数据,导致在前一个事务多次查询结果的不一致
读问题的解决:设置事务的隔离级别
Read uncommitted :以上问题都会发生
Read committed :解决脏读,但是不可重复读和虚读可能发生(Oracle默认隔离级别)
Repeatable read :解决脏读和不可重复读,但是虚读可能发生(Mysql默认隔离级别)
Serializable :解决所有读问题(效率最低)
Hibernate中设置事物隔离级别(在hibernate.cfg.xml)
<!-- 设置事务隔离级别
1-Read uncommitted
2-Read committed
4-Repeatable read
8-Serializable
-->
<property name="hibernate.connection.isolation">4</property>
API
Query:接口用于接收HQL,查询多个对象
Criteria:QBC (Query by Criteria)条件查询,更加一种面向对象的查询方式