Hibernate学习笔记(持久化类、主键、缓存、事务、常用API)

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)条件查询,更加一种面向对象的查询方式

发布了67 篇原创文章 · 获赞 50 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Auuuuuuuu/article/details/86802795