Hibernate的持久化和事务处理

什么是持久化

持久化:将内存中的一个对象持久化到数据库中的过程,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的主键生成策略
  1. increment:Hibernate中提供的自动增长机制,适用short、int、long类型的主键,在单线程程序中使用
  2. identity:适用short、int、long类型的主键,使用的是数据库底层的自动增强机制,适用于有自动增强机制的数据库(MYSQL,MSSQL),但是Oracle没有自增长
  3. sequence:适用short、int、long类型的主键,采用的是序列的方式,Oracle支持序列
  4. uuid:适用于字符串类型的主键
  5. native:本地策略,可以在identity和sequence之间进行自动切换
  6. assigned:Hibernate放弃外间的管理,需要手动编写程序或者用户自己设置
  7. foreign:外部的,一对一的一种关联映射的情况下使用

持久化类的三种状态

  • 瞬时态:
    这种对象没有唯一的标识OID,没有被session管理
  • 持久态:
    这种状态有唯一的OID,被session管理
    持久态对象能够自动更新数据库
  • 脱管态:
    这种对象有唯一标识OID,没有被session管理

Hibernate的一级缓存

  • 缓存:介于应用程序和永久性数据存储源之间,作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能

Hibernate框架中提供了优化手段:缓存、抓取策略。

  • Hibernate的一级缓存,称为Session级别的缓存,一级缓存生命周期和Session一致(一级缓存是由Session中的一系列的java集合构成)。一级缓存是自带的不可卸载的(Hibernate的二级缓存是SessionFactory级别的缓存,需要配置的缓存)
  1. 作用:减少对数据库的访问
  2. 特殊区域:快照区
  • Hibernate中的事务管理
    在hibernate.cfg.xml文件中配置,设置事务的隔离级别:
    1:读未提交
    2:读已提交
    4:不可重复读
    8:可串行化

      <propert name="hibernate.connection.isolation">4</property>
    
  • 保证Service中开启的事务使用的Session对象和DAO中多个操作使用的是同一个Session对象
    实现方法:

    1. 可以在业务层获取到Session,并将Session作为参数传递给DAO。
    2. 可以使用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();
}

猜你喜欢

转载自blog.csdn.net/weixin_43875648/article/details/88781738