Java EE SSH框架之hibernate(2)—— hibernate详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zl_StepByStep/article/details/80399424

本篇讲到的内容很杂,主要总结了hibernate中的实体创建规则、hibernate主键常见的7种生成策略、hibernate中对象的三种状态:瞬时态,持久化状态和托管/游离态、hibernate的一级缓存的特点和原理以及快照、hibernate事务管理、query查询,criteria查询和原生SQL查询。




一、hibernate中的实体规则

1.1、实体类创建的注意事项

         (1)持久化类提供无参数构造方法;
         (2)成员变量私有,提供公有的get、set方法访问,需提供属性;
         (3)持久化类中的属性,应尽量使用包装类型,为空时是null,比如考试缺考和考试0分用基本类型无法辨别;
         (4)持久化类需要提供oid,与数据库中的主键列对应;
         (5)不要用final修饰class(hibernate使用cglib代理生成代理对象,代理对象是继承被代理对象,如果被final修饰,不能被继承,也将无法生成代理)。


1.2、主键类型

hibernate中主键分两种,如下

        (1)自然主键(即业务相关主键,在开发中不多见):表的业务列中,有某业务列符合,必须有,并且不重复的特征时,该列可以作为主键使用。

        (2)代理主键(即业务无关主键,常用这种):表的业务列中,没有某业务列符合,必须有,并且不重复的特征时,创建一个没有业务意义的列作为主键使用。


1.3、主键的生成策略

generator:主键生成策略,就是每条记录录入时,主键生成的策略。class属性有以下常见的7个取值。

(1)identify:主键自增,由数据库维护主键值,录入时不需要指定主键。


(2)sequence:Oracle的主键生成策略。

扫描二维码关注公众号,回复: 3042885 查看本文章

(3)increment(了解):主键自增,由hibernate来维护主键值,每次插入前会先查询id的最大值,+1作为新主键。

        有线程安全问题,多个线程访问时,找最大id会出问题,所以开发时不用!


(4)hilo(了解):主键自增,由hibernate来维护,开发时完全不使用。

(5)native:hilo+sequence+identify  自动三选一策略。


(6)uuid:产生一个永远不重复的随机字符串作为主键,主键类型必须为String类型。

(7)assigned:自然主键生成策略,开发人员手动指定id录入,hibernate不会管理主键值。

hibernate维护主键自增在开发时并没什么用处,每个开发团队会根据需要规定数据库表的主键的生成策略,不需要外界来维护!



二、hibernate中的对象状态

对象分为三种状态:

瞬时状态:没有id,与session没有关联

持久化状态:有id,与session有关联

游离/托管状态:有id,与session没有关联

(上述的id指的是:与数据库对应的id有对应关系,数据库中没有对应的那个id,相当于是没有id)


控制台打印:



学习对象三种状态的结论:将我们希望同步到数据库的数据对应的对象转化为持久化状态!

    saveOrUpdate()方法不用考虑对象是瞬时状态还是游离状态,只用直接调这个方法,因为她都会把对象转换为持久化状态,将数据同步到数据库中!


三、hibernate进阶:一级缓存

    缓存:预加载,提高效率。hibernate中的一级缓存通过缓存减少对数据库的访问次数,从而提高操作数据库的效率!

3.1、一级缓存特点

(1)只有在session范围内有效,即在session范围内减少对数据库的访问次数,session一旦关闭,一级缓存失效,所以一级缓存作用范围小,缓存的时间短,缓存效果不明显,另外,不同的session不共享缓存数据;

(2)当调用session的save、saveOrUpdate、get、load、list、iterator方法时,都会把对象放入session缓存中;

        list查询:一次性把所有的记录都查询出来,会放入缓存,但不会从缓存中取数据;

        iterate(N+1次查询):N表示所有的记录总数,即会发送一条语句查询所有的记录的主键,这是第一条查询语句,再根据每一个主键去数据库查询,这是根据第一次查询的条数进行N次查询操作;会放入缓存,也会从缓存中取出数据。

(3)session的缓存是由hibernate维护的,用户不能直接操作缓存内容,只能通过hibernate提供的evict/clear方法操作;

         session.flush(); —— 让一级缓存与数据库同步

         session.evict(); —— 清空一级缓存中指定的对象

         session.clear(); —— 清空一级缓存中的所有对象


3.2、一级缓存提高效率的两个手段

一级缓存提高效率的两个手段分别是

《1》查询时,第一次查询时 ,将对象放入缓存,再次查询这个对象时,会返回缓存中的对象,而不再查询数据库。

《2》修改时,会使用快照对比修改前和修改后对象属性的区别,只执行一次修改。

《1》查询时

例:下面执行了三次get语句查询id为1的对象,但只执行了一次SQL语句。

一级缓存提高查询效率的原理:


《2》修改时(快照)

 



    上面将id为15的名字修改为了“改名”,执行了select和update语句。下面将id为15的名字修改成“改名*2”,再修改为原来的“改名”,控制台执行的SQL语句只有一个select语句,并没有发送update语句,减少了不必要的SQL修改语句的发送!



一级缓存减少不必要SQL语句发送的原理 —— 快照





四、hibernate中的事务

事务:a(原子性)c(一致性)i(隔离性)d(持久性)

事务并发产生的问题:①脏读、②不可重复读、③幻/虚读

事务的隔离级别:1——读未提交(会出现上述问题①②③)、2——读已提交(会出现上述问题②③)、4——可重复读(会出现上述问题③,mysql默认级别)、8——串行化(只允许串行,不允许并发没有问题,效率超低)

一个字节数据来存储隔离级别:0001——1、0010——2、0100——4、1000——8


在hibernate中指定事务隔离级别:

打开hibernate.properties文件(路径如下):


上述在主配置文件(hibernate.cfg.xml)中指定了事务的隔离级别为4。

在真正项目开发当中,事务的隔离级别不是随便就可以定的。


项目中管理事务(指定session与当前线程绑定):

    在三层架构中,一般是在Service(业务)层里管理事务的,在业务开始前打开事务,业务执行之后提交事务,执行过程中出现异常,要回滚事务。

    在DAO层操作数据库需要用到session对象,在Service层控制事务也是使用session对象完成,我们要确保DAO层和Service层使用的是同一个session对象。(有点类似连接数据库的Connection对象)

   在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了,开发人员只需要调用sessionFactory。getCurrentSession()方法即可获得与当前线程绑定的session对象,注意以下两点:

调用getCurrentSession方法必须配合主配置(hibernate.cfg.xml)中的一段配置:

 

通过getCurrentSession方法获得的session对象,当事务提交时,session会自动关闭,不需要我们手动调用close



五、hibernate中的批量处理

5.1、HQL查询

HQL(hibernate Query Language) hibernate独家查询语言,面向对象的查询语言

基本查询,查询全表:

 


条件查询,问号占位符:


条件查询,命名占位符:



分页查询


5.2、criteria查询

hibernate自创的无语句面向对象查询

查询所有:

条件查询:

上面的等于用的是Restrictions.eq(),下面是其他比较运算符的对照表

sql中 > >= < <= == != in like between and is not null is null or and
criteria中 gt ge lt le eq ne in like between is not null is null or and

分页查询:


查询中总记录数:


控制台打印的SQL语句:


5.3、原生SQL查询

基本查询,查询所有记录:返回数组List


基本查询,将查询结果封装到指定对象中:返回对象List


条件查询:


分页查询:



三种查询比较:

HQL查询:多表查询但不复杂时候使用

Criteria查询:单表查询,(多表时特别烧脑)

原生SQL查询(还是原生用的多):复杂的业务还是用原生SQL







猜你喜欢

转载自blog.csdn.net/zl_StepByStep/article/details/80399424