Hibernate(二)

持久化类

javabean+映射文件

编写规范:
(1)提供一个无参数的构造器:
  此构造器可以不是被public所修饰,但是只要有无参构造器,Hibernate就可以使用Constructor.newInstance()来创建持久化类实例了,为了方便Hibernate在运行时生成代理,构造器的访问修饰符至少是包可见的。
(2)提供一个标识属性:标识属性通常映射数据库表的主键字段。
(3)为持久化类的每个成员变量提供setter、getter方法;
(4)使用非final类(若使用final修饰,load方法的懒加载失效,就和get一样了);
(5)重写equals()和hashCode()方法:

主键生成策略

主键类型分类
自然主键:使用实体中一个有具体业务意义的字段作为主键 例如:身份证号
★代理主键:使用实体中一个毫无任何具体业务意义的字段作为主键 例如 user_id product_id

hibernate中常用的主键生成策略:
native: 对于 oracle 采用 Sequence 方式,对于MySQL 和 SQL Server 采用identity(自增主键生成机制),native就是将主键的生成工作交由数据库完成,hibernate不管(很常用)。
uuid: 采用128位的uuid算法生成主键,uuid被编码为一个32位16进制数字的字符串。占用空间大(字符串类型)。
assigned: 在插入数据的时候主键由程序处理(很常用),这是 <generator>元素没有指定时的默认生成策略。等同于JPA中的AUTO。
identity: 使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence(MySQL 和 SQL Server 中很常用)。 等同于JPA中的INDENTITY。
sequence: 调用底层数据库的序列来生成主键,要设定序列名,不然hibernate无法找到。
foreign: 使用另外一个相关联的对象的主键。通常和<one-to-one>联合起来使用。
uuid.hex: 看uuid,建议用uuid替换。

持久化对象的三种状态

在hibernate中持久化类的对象可以划分为三种状态,分别是瞬态,持久态,脱管态。

  1. 瞬态(Transient),也叫临时态。处于这种状态的对象具备的特征如下:
    a) 不在Session的缓存中,不与任何的Session实例相关联。
    b) 在数据库中没有与之相对应的记录。
  2. 持久态(Persistent),处于这种状态的对象具备的特征如下:
    a) 在Session的缓存中,与Session实例相关联。
    b) 在数据库中存在与之相对应的记录。
  3. 脱管态(Detached),也叫游离态。处于这种状态的对象具备的特征如下:
    a) 不在Session的缓存中,不与任何的Session实例相关联。
    b) 在数据库中存在与之相对应的记录。(前提条件是没有其他Session实例删除该条记录)。

持久化对象的三种状态是可以相互转化的,具体转换过程如图所示:

这里写图片描述

一级缓存和快照机制

session的一级缓存
使用hibernate进行查询的时候,将查询结果放置到session的一级缓存中,在一级缓存中存在对象,对象使用属性的OID的值进行区分,此时再使用相同的OID进行查询的时候,首先会在session一级缓存中进行查找是否存在相同的OID

如果存在相同的OID,此时不再查询数据库,而是直接使用一级缓存中存在的对象
如果没有存在相同的OID,此时再查询数据库,将查询得到的结果数据再放置到session一级缓存中

目的:减少访问数据库的次数

session的快照
使用id进行查询数据库,将查询得到的结果放置到session一级缓存中,同时复制一份数据,放置到session的快照中
当使用tr.commit()的时候,同时清理session的一级缓存(flush)

如果2个对象(一级缓存对象和快照的对象)中的属性发生变化,则执行update语句,此时更新数据库,更新成一级缓存中的数据
如果2个对象中的属性不发生变化,此时不执行update语句

目的:确保和数据库中的数据一致

hibernate中的事务

同时运行多个事务访问相同数据时,可能会导致5类并发问题:

  1. 第一类丢失更新:撤销一个事务时,把其他事务已提交的更新覆盖
  2. 脏读:一个事务读到另一事务未提交的更新数据
  3. 虚读:一个事务读到另一事务已提交的新插入的数据
  4. 不可重复读:一个事务读到另一事务已提交的更新数据
  5. 第二类丢失更新:一个事务覆盖另一事务已提交的更新数据,不可重复读的特例

在hibernate中也有四种隔离级别,分别是

1—Read uncommitted isolation 读未提交数据
2—Read committed isolation 读已提交数据
4—Repeatable read isolation 可重复读
8—Serializable isolation 串行化

如何设置隔离级别? 在核心配置文件中配置:

<property name="hibernate.connenction.isolation">4</..>

如何保证service层和dao层使用的同一个事务?——–只需要保证service层和dao层使用同一个连接即可

如何何保证service层和dao层使用同一个连接?方式1:传递参数 方式2:使用线程绑定的方式(ThreadLocal)

hibernate如何使用事务,底层封装好了ThreadLocal

步骤:
1.在核心配置文件中配置 将session绑定到当前线程中

        <!-- 开启与线程绑定的session -->
        <property name="hibernate.current_session_context_class">thread</property>

2.factory.getCurrentSession();获取和当前线程绑定的session。(注意:此时的session不需要手动关闭)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值