hibernate持久化类的编写规则
hibernate是持久层的的ORM映射框架,专注数据的持久化工作。所谓的持久化就是将内存中的数据永久存储到关系数据库中。
持久化类就是指一个Java类与数据库表建立了映射关系,那么这个类称为是持久化类。
注意事项
- 持久化提供无参数构造
- 成员变量私有,提供公用的get/set方法访问,需要提供属性
- 持久化类中的属性,应该尽量使用包装类。
- 持久化类需提供oid与数据库中的主键列对应
- 不要使用final类修饰class
主键生成策略
主键的类型
自然主键:把具业务含义的字段作为主键,成为自然主键。例如在custom表中,如果name作为主键就是自然主键
代理主键:把不具备业务含义的字段作为主键,称为代理主键。该字段一般取名为“ID”,通常为整数类型。
hibernate主键生成策略
<id name="custId" column="cust_id">
<generator class="native"></generator>
</id>
generator:主键生成策略,就是每条记录录入时,主键的生成规则
- indentity:主键自增。采用底层数据库本身提供的主键生成标识符,由数据库来维护主键,录入时不需要指定主键
- increment:主键自增,由hibernate来维护,,每次插入前会先查询表中id最大值,+1作为主键,开发不常用
- sequence:oracle中主键生成策略
- hilo:高低算法,主键自增,由hibernate来维护,开发时不适用。
- native:hilo+sequence+identity自动三选一策略。推荐使用
- uuid:产生随机字符串作为主键,主键类型必须为string类型
- assined:自然主键生成策略,hibernate不会管理主键,开发人员自己录入
持久化对象的三种状态
- 瞬时状态:没有id,没有与session关联
- 持久化状态:有id,与session有关联
- 游离/托管状态:有id,没有与session关联
Customer c=new Customer();//Customer c=new Customer();
session.save(c);//有id,与session有关联
transaction.commit();
session.close();//有id,没有与session关联
三种状态特点
save方法其实并不是保存,而是将瞬时态转换为持久态的方法
持久化特点: 持久化状态的任何变化都会自动同步到数据库中
Hibernate的一级缓存
一级缓存指的就是session缓存。session缓存是一块内存空间,用来存放和管理Java对象,在hibernate查询对象时,首先会使用对象属性的id值在一级缓存中进行查找,如果没有则会去数据库中查找相应的数据。
作用:减少对数据的访问次数
特点
- 当应用程序调用session接口的save()、update()、saveOrUpdate()时,如果session缓存中没有相应的对象,hibernate就会自动的把从数据库中查询到的相应对象信息加入到一级缓存中去
- 当调用load、get方法,会判断缓存中是否存在该对象,有责返回;没有则去数据库查询并添加到一级缓存中
- 当调用session的close()时,session缓存会被清空
一级缓存的内部结构
一级缓存能够自动更新数据库是因为有一块特殊的快照区
hibernate向一级缓存放入数据时,同时复制一份数据放入到hibernate快照中,当使用commit提交事务时,同时会清理session的一级缓存,这时会使用oid判断一级缓存中的对象和快照中的对象是否一致,如果两个对象中的属性发生变化,则执行update语句,将缓存的内容同步到数据库并更新快照。快照的作用就是确保一级缓存中的数据和数据库中的数据一致
hibernate的事务
事务其实就是逻辑上的一组操作,组成这组操作的各个单元,要么一起成功,要么一起失败
事务的四个特性
- 原子性:要么全部执行,要么全部都不执行
- 一致性:事务完成时,必须使所有的数据都保持一致
- 隔离性:一个事务的执行不能被其他事务干扰
- 持久性:一个事务一旦提交,它对数据库的改变就应该是永久性的
事务的并发问题
- 脏读:一个事务读取到另一个事务未提交的数据
- 不可重复读:一个事务读取到了另一个事务已经提交的update数据,导致在同一个事务中的多次查询结果不一致
- 虚读/幻读:一个书屋读到了另一个事务已经提交的insert数据,导致在同一个事务中的多次查询结果不一致
事务的隔离级别
隔离级别 | 含义 |
---|---|
READ_UNCOMMITT | 允许你读取还未提交的改变了的数据。可能导致所有的事务并发问题 |
READ_COMMITTED(mysql默认) | 允许在并发事务一斤提交后读取。可防止脏读 |
REPEATABLE_READ(oracle默认) | 对相同字段的多次读取是一致的,可防止脏读、不可重复读 |
SERIALIZABLE | 可确保并发问题不发生,但是最慢 |
hibernate的事务处理
方法一
通过Transaction操作事务
Transaction transaction=session.beginTransaction();//开启一个事务
session.save(c);
transaction.commit();//提交一个事务
transaction.rollback();//事务回滚
方法二
配置文件
三种管理session对象的方法:
- session对象的生命周期与本地线程绑定
- session对象的生命周期与JTA事务绑定
- hibernate委托程序管理session对象的生命周期
在配置文件中hibernate.current_session_context_class属性用于指定session管理方式
<property name="current_session_context_class">thread</property>
<property name="current_session_context_class">jta</property>
<property name="current_session_context_class">managed</property>