hibernate经典问题
发布日期:2021-09-16 04:36:22 浏览次数:17 分类:技术文章

本文共 4685 字,大约阅读时间需要 15 分钟。

 

 

一、hibernate 中对象的三种状态

瞬时态(临时态、自由态):不存在持久化标识OID,尚未与 Hibernate Session 关联对象, 被认为处于瞬时态,失去引用将被 JVM 回收持久态:存在持久化标识 OID,与当前 session 有关联,并且相关联的 session 没有关闭 , 并且事务未提交脱管态(离线态、游离态):存在持久化标识 OID,但没有与当前 session 关联,脱管状态 改变 hibernate 不能检测到

 

二、hibernate 的缓存机制

Hibernate 缓存分为两层:Hibernate 的一级缓存和 Hibernate 二级缓存。

1.Hibernate 一级缓存(Session 的缓存):

(1)Session 实现了第一级 Cache,属于事务级数据缓冲。一旦事务结束,缓存随之失效。一个 Session 的生命周期对应一个数据库事务或一个程序事务。

(2)Session-Cache 总是被打开并且不能被关闭的。

(3)Session-Cache 保证一个 Session 中两次请求同一个对象时,取得的对象是同一个 Java 实例,有时它可以避免不必要的数据冲突。

a.在对于同一个对象进行循环引用时,不至于产生堆栈溢出。

b.当数据库事务结束时,对于同一数据表行,不会产生数据冲突。因为对于数据库中的一行,最多有一个对象来表示它。

c.一个事务中可能会有很多个处理单元,在每一个处理单元中做的操作都会立即被其他的数据单元得知。

2.Hibernate 二级缓存(SessionFactory 的缓存):

1)二级缓存是 SessionFactory 范围内的缓存,所有的 Session 共享同一个二级缓存。在二级缓存中保存持久化实例的散装形式的数据。

(2)持久化不同的数据需要不同的 Cache 策略,比如一些因素将影响 Cache 策略的选择:数据的读/写比例、数据表是否能被其他的应用程序所访问等。

(3)设置 Hibernate 二级缓存需要分两步:首先,确认使用什么数据并发策略。然后,配置缓存过期时间并设置 Cache提供器。

 

三、Hibernate 的查询方式有哪些?

Hibernate 的查询方式常见的主要分为三种: HQL, QBC(命名查询), 以及使用原生 SQL 查询(SqlQuery)

四、 Hibernate 和 Mybatis 的区别?

两者相同点:

1)Hibernate 与 MyBatis 都可以是通过 SessionFactoryBuider 由 XML 配置文件生成 SessionFactory,然后由

SessionFactory 生成 Session,最后由 Session 来开启执行事务和 SQL 语句。其中 SessionFactoryBuider,

SessionFactory,Session 的生命周期都是差不多的。

2)Hibernate 和 MyBatis 都支持 JDBC 和 JTA 事务处理。

Mybatis 优势:

1)MyBatis 可以进行更为细致的 SQL 优化,可以减少查询字段。

2)MyBatis 容易掌握,而 Hibernate 门槛较高。

Hibernate 优势:

1)Hibernate 的 DAO 层开发比 MyBatis 简单,Mybatis 需要维护 SQL 和结果映射。

2)Hibernate 对对象的维护和缓存要比 MyBatis 好,对增删改查的对象的维护要方便。

3)Hibernate 数据库移植性很好,MyBatis 的数据库移植性不好,不同的数据库需要写不同 SQL。

4)Hibernate 有更好的二级缓存机制,可以使用第三方缓存。MyBatis 本身提供的缓存机制不佳。

 

五、Hibernate 和 JDBC 优缺点对比

相同点:

1)两者都是 java 数据库操作的中间件、

2)两者对数据库进行直接操作的对象都是线程不安全的,都需要及时关闭。

3)两者都可对数据库的更新操作进行显式的事务处理。

不同点:

JDBC 是 SUN 公司提供一套操作数据库的规范,使用 java 代码操作数据库。Hibernate 是一个基于 jdbc 的主流持久化框架,对 JDBC 访问数据库的代码做了封装。

使用的 SQL 语言不同:JDBC 使用的是基于关系型数据库的标准 SQL 语言,Hibernate 使用的是 HQL(Hibernatequery language)语言。

操作的对象不同:JDBC 操作的是数据,将数据通过 SQL 语句直接传送到数据库中执行,Hibernate 操作的是持久化对象,由底层持久化对象的数据更新到数据库中。

数据状态不同:JDBC 操作的数据是“瞬时”的,变量的值无法与数据库中的值保持一致,而 Hibernate 操作的数据是可持久的,即持久化对象的数据属性的值是可以跟数据库中的值保持一致的。

 

六、关于 Hibernate 的 orm 思想你了解多少?

ORM 指的是对象关系型映射(Object RelationShip Mapping ),指的就是我们通过创建实体类对象和数据库中的表关系进行一一对应,来实现通过操作实体类对象来更改数据库里边的数据信息。这里边起到关键作用的是通过Hibernate 的映射文件+Hibernate 的核心配置文件。

七、get 和 load 的区别?

(1)get 是立即加载,load 是延时加载。

(2)get 会先查一级缓存,再查二级缓存,然后查数据库;load 会先查一级缓存,如果没有找到,就创建代理对象,等需要的时候去查询二级缓存和数据库。(这里就体现 load 的延迟加载的特性。)

(3)get 如果没有找到会返回 null,load 如果没有找到会抛出异常。

(4)当我们使用 session.load()方法来加载一个对象时,此时并不会发出 sql 语句,当前得到的这个对象其实是一个代理对象,这个代理对象只保存了实体对象的 id 值,只有当我们要使用这个对象,得到其它属性时,这个时候才会发出 sql 语句,从数据库中去查询我们的对象;相对于 load 的延迟加载方式,get 就直接的多,当我们使用session.get()方法来得到一个对象时,不管我们使不使用这个对象,此时都会发出 sql 语句去从数据库中查询出来。

 

八、如何进行 Hibernate 的优化?

(1)数据库设计调整。

(2)HQL 优化。

(3)API 的正确使用(如根据不同的业务类型选用不同的集合及查询 API)。

(4)主配置参数(日志,查询缓存,fetch_size, batch_size 等)。

(5)映射文件优化(ID 生成策略,二级缓存,延迟加载,关联优化)。

(6)一级缓存的管理。

(7)针对二级缓存,还有许多特有的策略。

(8)事务控制策略。

 

九、什么是 Hibernate 延迟加载?

延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在 Hibernate 中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在 Hibernate3 中还提供了对属性的延迟加载。

延迟加载的过程:通过代理(Proxy)机制来实现延迟加载。Hibernate 从数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据(除标识符外),

Hibernate 并不从数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都为默认值;只有在真正需要使用该对象的数据时才创建这个真正的对象,真正从数据库中加载它的数据。

 

十、No Session 问题原理及解决方法?

Nosession 问题报错如下:

 

根据字面上的意思,是指代理不能被初始化,session 已经关闭。

Nosession 问题产生的原因:

当执行 Session 的 load()方法时,Hibernate 不会立即执行查询所查询对象关联的对象(在此我们统称被关联的对象类为 A 类),仅仅返回 A 类的代理类的实例,这个代理类具由以下特征:

(1)由 Hibernate 在运行时动态生成,它扩展了 A 类,因此它继承了 A 类的所有属性和方法,但它的实现对于应用程序是透明的。

(2)当 Hibernate 创建 A 类代理类实例时,仅仅初始化了它的 OID 属性,其他属性都为 null,因此这个代理类实例占用的内存很少。

(3)当应用程序第一次访问 A 代理类实例时(例如调用 a..getXXX()或 a.setXXX()方法),Hibernate 会初始化代理类实例,在初始化过程中执行 select 语句,真正从数据库中加载 A 对象的所有数据。但有个例外,那就是当应用程序访问 A 代理类实例的 getId()方法时,Hibernate 不会初始化代理类实例,因为在创建代理类实例时 OID 就存在了,不必到数据库中去查询。

提示:Hibernate 采用 CGLIB 工具来生成持久化类的代理类。CGLIB 是一个功能强大的 Java 字节码生成工具,

它能够在程序运行时动态生成扩展 Java 类或者实现 Java 接口的代理类。

因为 Hibernate 中如果采用 load 加载的话(默认的是延迟加载),也就是 lazy=true 操作,因此,当调用完 load后,session 即可关闭。因为我们的 session 只是放置到了 Dao 层,表现层根本获取不到,所以在表现层调用的时候,session 已经关闭,报错。

 

十一、比较 Hibernate 三种检索策略的优缺点

1、立即检索

优点:对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便的从一个对象导航到与它关联的对象;

缺点:1.select 语句太多;2.可能会加载应用程序不需要访问的对象白白浪费许多内存空间;

2、延迟检索

优点:由应用程序决定需要加载哪些对象,可以避免可执行多余的 select 语句,以及避免加载应用程序不需要访问的对象。因此能提高检索性能,并且能节省内存空间;

缺点:应用程序如果希望访问游离状态代理类实例,必须保证他在持久化状态时已经被初始化;

3、 迫切左外连接检索

优点:1、对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便地冲一个对象导航到与它关联的对象。2、使用了外连接,select 语句数目少;

缺点:1、可能会加载应用程序不需要访问的对象,白白浪费许多内存空间;2、复杂的数据库表连接也会影响检索性能;

 

十二、简述一下 hibernate 的开发流程

第一步:加载 hibernate 的配置文件,读取配置文件的参数(jdbc 连接参数,数据 库方言,hbm 表与对象关系映射文件)

第二步:创建 SessionFactory 会话工厂(内部有连接池)

第三步:打开 session 获取连接,构造 session 对象(一次会话维持一个数据连接, 也是一级缓存)

第四步:开启事务

第五步:进行操作

第六步:提交事务

第七步:关闭 session(会话)将连接释放

第八步:关闭连接池

 

转载地址:https://blog.csdn.net/wlg9527/article/details/107461169 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:oracle 数据库优化
下一篇:dubbo入门

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月22日 20时53分19秒