Hibernate面试问题与解答
Hibernate是Java应用程序中使用最广泛的ORM工具之一。它在企业应用程序中用于数据库操作。所以我决定写一篇关于的帖子 hibernate面试问题,在面试前刷新你的知识。
无论您是新手还是经验丰富,拥有良好的知识或Hibernate ORM工具都有助于破解面试。在这里,我提供重要的hibernate面试问题,并提供答案,帮助您提升知识面,并给面试官留下深刻印象。就像其他面试问题的帖子一样,我将来可能会在此列表中添加更多问题,因此您可能希望将其加入书签以供将来参考。
最近我写了很多关于hibernate的帖子,其中大部分都包含完整的可下载项目。我将在需要时提供它们的参考,您可以通过它们来更新您的知识。
Hibernate面试问题
- 什么是Hibernate框架?
- 什么是Java Persistence API(JPA)?
- 使用Hibernate Framework有哪些重要的好处?
- Hibernate相对于JDBC有什么优势?
- 列举一些Hibernate框架的重要接口?
- 什么是hibernate配置文件?
- 什么是hibernate映射文件?
- 列举一些用于Hibernate映射的重要注释?
- 什么是Hibernate SessionFactory以及如何配置它?
- Hibernate SessionFactory是线程安全的吗?
- 什么是Hibernate Session以及如何获得它?
- Hibernate Session是线程安全的吗?
- openSession和getCurrentSession有什么区别?
- Hibernate Session get()和load()方法有什么区别?
- 什么是hibernate缓存?解释Hibernate一级缓存?
- 如何使用EHCache配置Hibernate二级缓存?
- 实体bean的不同状态是什么?
- 什么是Hibernate Session merge()调用?
- Hibernate save(),saveOrUpdate()和persist()方法有什么区别?
- 如果我们在Entity bean中没有no-args构造函数会发生什么?
- 排序集合和有序集合之间有什么区别,哪一个更好?
- Hibernate中的集合类型是什么?
- 如何在Hibernate中实现连接?
- 为什么我们不应该让实体类最终?
- 什么是HQL,它有什么好处?
- 什么是Hibernate中的查询缓存?
- 我们可以在hibernate中执行本机sql查询吗?
- 在hibernate中本机sql查询支持有什么好处?
- 什么是命名SQL查询?
- 命名SQL查询有什么好处?
- Hibernate Criteria API有什么好处?
- 如何在日志文件中记录hibernate生成的sql查询?
- 什么是Hibernate代理以及它如何帮助延迟加载?
- 如何在hibernate中实现关系?
- 事务管理如何在Hibernate中运行?
- 什么是级联,什么是不同类型的级联?
- 如何在hibernate应用程序中集成log4j日志?
- 如何在Hibernate框架中使用应用服务器JNDI DataSource?
- 如何集成Hibernate和Spring框架?
- 什么是HibernateTemplate类?
- 如何将Hibernate与Servlet或Struts2 Web应用程序集成?
- Hibernate框架中使用了哪些设计模式?
- Hibernate框架遵循哪些最佳实践?
- 什么是Hibernate Validator Framework?
- Hibernate Tools Eclipse插件有什么好处?
Hibernate面试问题与解答
-
什么是Hibernate框架?
对象关系映射或ORM是将应用程序域模型对象映射到关系数据库表的编程技术。Hibernate是基于Java的ORM工具,它提供了将应用程序域对象映射到关系数据库表的框架,反之亦然。
Hibernate提供了Java Persistence API的参考实现,这使得它成为具有松散耦合优势的ORM工具的绝佳选择。我们可以使用Hibernate持久性API进行CRUD操作。Hibernate框架提供了使用JPA注释和基于XML的配置将普通旧Java对象映射到传统数据库表的选项。
类似地,hibernate配置是灵活的,可以从XML配置文件以及以编程方式完成。有关hibernate框架使用的快速概述,您可以浏览Hibernate Beginners Tutorial。
-
什么是Java Persistence API(JPA)?
Java Persistence API(JPA)提供了用于管理应用程序中的关系数据的规范。目前的JPA 2.1版本于2011年7月开始作为JSR 338. JPA 2.1于2013年5月22日被批准为最终版本。
JPA规范是使用javax.persistence包中的注释定义的。使用JPA注释有助于我们编写与实现无关的代码。
-
使用Hibernate Framework有哪些重要的好处?
使用hibernate框架的一些重要好处是:
整体hibernate是当前ORM工具市场的最佳选择,它包含ORM工具中您需要的所有功能。
- Hibernate消除了JDBC附带的所有样板代码并负责管理资源,因此我们可以专注于业务逻辑。
- Hibernate框架提供对XML和JPA注释的支持,这使我们的代码实现独立。
- Hibernate提供了一种类似于SQL的强大查询语言(HQL)。但是,HQL完全面向对象,并且理解继承,多态和关联等概念。
- Hibernate是Red Hat社区的一个开源项目,在全球范围内使用。这使得它成为比其他人更好的选择,因为学习曲线很小,并且有大量的在线文档,并且在论坛中可以轻松获得帮助。
- Hibernate很容易与其他Java EE框架集成,它非常流行,以至于Spring Framework为将hibernate与Spring应用程序集成提供了内置支持。
- Hibernate支持使用代理对象进行延迟初始化,并仅在需要时执行实际的数据库查询。
- Hibernate缓存有助于我们获得更好的性能。
- 对于数据库供应商特定功能,hibernate是合适的,因为我们也可以执行本机sql查询。
-
Hibernate相对于JDBC有什么优势?
Hibernate框架相对于JDBC的一些重要优点是:
- Hibernate删除了JDBC API附带的大量样板代码,代码看起来更清晰,更易读。
- Hibernate支持继承,关联和集合。JDBC API不提供这些功能。
- Hibernate隐式提供事务管理,实际上大多数查询都无法在事务外执行。在JDBC API中,我们需要使用commit和rollback为事务管理编写代码。阅读JDBC事务管理的更多内容。
- JDBC API抛出
SQLException
了一个已检查的异常,因此我们需要编写大量的try-catch块代码。大多数情况下,它在每个JDBC调用中都是冗余的,并用于事务管理。Hibernate包装JDBC异常并抛出JDBCException
或HibernateException
取消检查异常,因此我们不需要编写代码来处理它。Hibernate内置事务管理消除了try-catch块的使用。 - Hibernate查询语言(HQL)更面向对象并且接近于Java编程语言。对于JDBC,我们需要编写本机sql查询。
- Hibernate支持更高性能的缓存,不缓存JDBC查询,因此性能较低。
- Hibernate提供了我们也可以创建数据库表的选项,因为JDBC表必须存在于数据库中。
- Hibernate配置帮助我们使用JDBC连接以及JNDI DataSource用于连接池。这是企业应用程序中非常重要的功能,在JDBC API中完全缺失。
- Hibernate支持JPA注释,因此代码独立于实现,并且可以轻松替换为其他ORM工具。JDBC代码与应用程序紧密耦合。
-
列举一些Hibernate框架的重要接口?
Hibernate框架的一些重要接口是:
- SessionFactory(org.hibernate.SessionFactory):SessionFactory是单个数据库的已编译映射的不可变线程安全缓存。我们需要初始化SessionFactory一次,然后我们可以缓存并重用它。SessionFactory实例用于获取数据库操作的Session对象。
- Session(org.hibernate.Session):Session是一个单线程,短期对象,表示应用程序和持久性存储之间的对话。它包装JDBC
java.sql.Connection
并作为工厂工作org.hibernate.Transaction
。我们应该只在需要时打开会话,并在我们完成使用后立即关闭它。Session对象是java应用程序代码和hibernate框架之间的接口,为CRUD操作提供了方法。 - Transaction(org.hibernate.Transaction):Transaction是应用程序用来指定原子工作单元的单线程,短期对象。它从底层JDBC或JTA事务中抽象出应用程序。在某些情况下,org.hibernate.Session可能跨越多个org.hibernate.Transaction。
-
什么是hibernate配置文件?
Hibernate配置文件包含特定于数据库的配置,用于初始化SessionFactory。我们在hibernate配置xml文件中提供数据库凭据或JNDI资源信息。hibernate配置文件的其他一些重要部分是Dialect信息,因此hibernate知道数据库类型和映射文件或类的详细信息。
-
什么是hibernate映射文件?
Hibernate映射文件用于定义实体bean字段和数据库表列映射。我们知道JPA注释可以用于映射,但是当我们使用第三方类并且我们不能使用注释时,有时XML映射文件会派上用场。
-
列举一些用于Hibernate映射的重要注释?
Hibernate支持JPA注释,它在
org.hibernate.annotations
包中还有一些其他注释。使用的一些重要的JPA和hibernate注释是:以下是显示这些注释用法的两个类。
package com.journaldev.hibernate.model; import javax.persistence.Access; import javax.persistence.AccessType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Table; import org.hibernate.annotations.Cascade; @Entity @Table(name = "EMPLOYEE") @Access(value=AccessType.FIELD) public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "emp_id") private long id; @Column(name = "emp_name") private String name; @OneToOne(mappedBy = "employee") @Cascade(value = org.hibernate.annotations.CascadeType.ALL) private Address address; //getter setter methods }
package com.journaldev.hibernate.model; import javax.persistence.Access; import javax.persistence.AccessType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter; @Entity @Table(name = "ADDRESS") @Access(value=AccessType.FIELD) public class Address { @Id @Column(name = "emp_id", unique = true, nullable = false) @GeneratedValue(generator = "gen") @GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") }) private long id; @Column(name = "address_line1") private String addressLine1; @OneToOne @PrimaryKeyJoinColumn private Employee employee; //getter setter methods }
- javax.persistence.Entity:与模型类一起使用以指定它们是实体bean。
- javax.persistence.Table:与实体bean一起使用,以在数据库中定义相应的表名。
- javax.persistence.Access:用于定义访问类型,字段或属性。默认值为field,如果希望hibernate使用getter / setter方法,则需要将其设置为property。
- javax.persistence.Id:用于定义实体bean中的主键。
- javax.persistence.EmbeddedId:用于在实体bean中定义复合主键。
- javax.persistence.Column:用于在数据库表中定义列名。
- javax.persistence.GeneratedValue:用于定义用于生成主键的策略。与
javax.persistence.GenerationType
enum 一起使用。 - javax.persistence.OneToOne:用于定义两个实体bean之间的一对一映射。我们有其他类似的注释
OneToMany
,ManyToOne
和ManyToMany
- org.hibernate.annotations.Cascade:用于定义两个实体bean之间的级联,与映射一起使用。它与...一起使用
org.hibernate.annotations.CascadeType
- javax.persistence.PrimaryKeyJoinColumn:用于定义外键的属性。与
org.hibernate.annotations.GenericGenerator
和一起使用org.hibernate.annotations.Parameter
-
什么是Hibernate SessionFactory以及如何配置它?
SessionFactory是用于获取Session对象的工厂类。SessionFactory负责读取hibernate配置参数并连接到数据库并提供Session对象。通常,应用程序具有单个SessionFactory实例,并且服务客户端请求的线程从此工厂获取Session实例。
SessionFactory的内部状态是不可变的。创建后,将设置此内部状态。此内部状态包括有关对象/关系映射的所有元数据。
SessionFactory还提供了获取Class元数据和Statistics实例的方法,以获取查询执行的统计信息,二级缓存详细信息等。
-
Hibernate SessionFactory是线程安全的吗?
SessionFactory的内部状态是不可变的,因此它是线程安全的。多个线程可以同时访问它以获取Session实例。
-
什么是Hibernate Session以及如何获得它?
Hibernate Session是java应用层和hibernate之间的接口。这是用于执行数据库操作的核心接口。会话的生命周期受事务开始和结束的约束。
Session提供了对持久对象执行创建,读取,更新和删除操作的方法。我们可以使用Session对象执行HQL查询,SQL本机查询和创建条件。
-
Hibernate Session是线程安全的吗?
Hibernate Session对象不是线程安全的,每个线程都应该获得它自己的会话实例,并在它完成工作后关闭它。
-
openSession和getCurrentSession有什么区别?
Hibernate SessionFactory getCurrentSession()方法返回绑定到上下文的会话。但为了实现这一点,我们需要在hibernate配置文件中进行配置。由于此会话对象属于hibernate上下文,因此我们不需要关闭它。会话工厂关闭后,此会话对象将关闭。
<property name="hibernate.current_session_context_class">thread</property>
Hibernate SessionFactory openSession()方法总是打开一个新会话。完成所有数据库操作后,我们应该关闭此会话对象。我们应该在多线程环境中为每个请求打开一个新会话。
还有另一个方法openStatelessSession()返回无状态会话,有关更多详细信息,请阅读Hibernate openSession vs getCurrentSession。
-
Hibernate Session get()和load()方法有什么区别?
Hibernate会话带有不同的方法来从数据库加载数据。获取和加载是最常用的方法,起初看起来它们似乎相似,但它们之间存在一些差异。
有关差异的说明,请阅读Hibernate get vs load。
- get()在调用数据后立即加载数据,而load()返回代理对象并仅在实际需要时加载数据,因此load()更好,因为它支持延迟加载。
- 由于load()在未找到数据时抛出异常,因此我们应该仅在知道数据存在时才使用它。
- 当我们想确保数据库中存在数据时,我们应该使用get()。
-
什么是hibernate缓存?解释Hibernate一级缓存?
顾名思义,hibernate缓存查询数据以使我们的应用程序更快。如果正确使用,Hibernate Cache在获得快速应用程序性能方面非常有用。缓存背后的想法是减少数据库查询的数量,从而减少应用程序的吞吐时间。
Hibernate第一级缓存与Session对象相关联。默认情况下启用Hibernate第一级缓存,无法禁用它。但是,hibernate提供了一些方法,通过这些方法我们可以从缓存中删除所选对象或完全清除缓存。
会话中缓存的任何对象都不会对其他会话可见,并且会话关闭时,所有缓存的对象也将丢失。有关更好的解释,请阅读Hibernate First Level Cache。
-
如何使用EHCache配置Hibernate二级缓存?
EHCache是利用hibernate二级缓存的最佳选择。在hibernate应用程序中启用EHCache需要以下步骤。
就是这样,我们完成了。Hibernate将使用EHCache进行二级缓存,阅读Hibernate EHCache示例 以获得解释的完整示例。
- 在你的maven项目中添加hibernate-ehcache依赖项,如果它不是maven,那么添加相应的jar。
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>4.3.5.Final</version> </dependency>
- 在hibernate配置文件中添加以下属性。
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> <!-- For singleton factory --> <!-- <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</property> --> <!-- enable second level cache and query cache --> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.use_query_cache">true</property> <property name="net.sf.ehcache.configurationResourceName">/myehcache.xml</property>
- 创建EHCache配置文件,myehcache.xml示例文件如下所示。
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <diskStore path="java.io.tmpdir/ehcache" /> <defaultCache maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30" maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" statistics="true"> <persistence strategy="localTempSwap" /> </defaultCache> <cache name="employee" maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="5" timeToLiveSeconds="10"> <persistence strategy="localTempSwap" /> </cache> <cache name="org.hibernate.cache.internal.StandardQueryCache" maxEntriesLocalHeap="5" eternal="false" timeToLiveSeconds="120"> <persistence strategy="localTempSwap" /> </cache> <cache name="org.hibernate.cache.spi.UpdateTimestampsCache" maxEntriesLocalHeap="5000" eternal="true"> <persistence strategy="localTempSwap" /> </cache> </ehcache>
- 使用@Cache批注和缓存策略注释实体bean。例如,
import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Table(name = "ADDRESS") @Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="employee") public class Address { }
- 在你的maven项目中添加hibernate-ehcache依赖项,如果它不是maven,那么添加相应的jar。
-
实体bean的不同状态是什么?
实体bean实例可以存在三种状态之一。
- 瞬态:当一个对象永远不会持久存在或与任何会话相关联时,它处于瞬态状态。通过调用save(),persist()或saveOrUpdate()可以使瞬态实例持久化。通过调用delete()可以使持久化实例成为瞬态。
- 持久性:当对象与唯一会话关联时,它处于持久状态。get()或load()方法返回的任何实例都是持久的。
- 分离:当一个对象以前是持久的但没有与任何会话相关联时,它处于分离状态。可以通过调用update(),saveOrUpdate(),lock()或replicate()使分离的实例持久化。通过调用merge(),瞬态或分离实例的状态也可以作为新的持久实例持久化。
-
什么是Hibernate Session merge()调用?
Hibernate merge可用于更新现有值,但此方法从传递的实体对象创建副本并返回它。返回的对象是持久化上下文的一部分,并跟踪任何更改,不跟踪传递的对象。例如程序,读取Hibernate合并。
-
Hibernate save(),saveOrUpdate()和persist()方法有什么区别?
Hibernate save可用于将实体保存到数据库。save()的问题在于它可以在没有事务的情况下调用,如果我们有映射实体,则只保存主对象,从而导致数据不一致。save也会立即返回生成的id。
Hibernate持久化类似于使用事务保存。我觉得它比保存更好,因为我们不能在事务边界之外使用它,所以保留所有对象映射。另外,persist不会立即返回生成的id,因此在需要时会发生数据持久性。
Hibernate saveOrUpdate根据提供的数据生成插入或更新查询。如果数据存在于数据库中,则执行更新查询。我们也可以在没有事务的情况下使用saveOrUpdate(),但是如果没有刷新会话,你将再次遇到没有保存的映射对象的问题。例如,使用这些方法,请阅读Hibernate save vs persist。
-
如果我们在Entity bean中没有no-args构造函数会发生什么?
Hibernate使用Reflection API来创建实体bean的实例,通常在调用get()或load()方法时。该方法
Class.newInstance()
用于此,它需要no-args构造函数。因此,如果你在实体bean中没有no-args构造函数,那么hibernate将无法实例化它,你就会得到它HibernateException
。 -
排序集合和有序集合之间有什么区别,哪一个更好?
当我们使用Collection API排序算法对集合进行排序时,它被称为排序列表。对于小型集合,它不是很大的开销,但对于较大的集合,它可能导致性能下降和OutOfMemory错误。实体bean也应该实现
Comparable
或Comparator
接口才能工作,在java对象列表排序中阅读更多内容。如果我们使用Hibernate框架从数据库加载集合数据,我们可以使用它的Criteria API来使用“order by”子句来获取有序列表。下面的代码片段向您展示了如何获取它。
List<Employee> empList = session.createCriteria(Employee.class) .addOrder(Order.desc("id")).list();
有序列表优于排序列表,因为实际排序是在数据库级别完成的,这很快并且不会导致内存问题。
-
Hibernate中的集合类型是什么?
hibernate中有五种集合类型用于一对多关系映射。
- 袋
- 组
- 名单
- 排列
- 地图
-
如何在Hibernate中实现连接?
在hibernate中有多种方法可以实现连接。
- 使用一对一,一对多等关联。
- 在HQL查询中使用JOIN。还有另一种形式“连接提取”来同时加载相关数据,没有延迟加载。
- 我们可以触发本机sql查询并使用join关键字。
-
为什么我们不应该让实体类最终?
Hibernate仅在需要时才使用代理类来延迟加载数据。这是通过扩展实体bean来完成的,如果实体bean是最终的,那么延迟加载将是不可能的,因此性能低下。
-
什么是HQL,它有什么好处?
Hibernate Framework附带了一个强大的面向对象的查询语言--Hibernate Query Language(HQL)。它与SQL非常相似,只是我们使用Objects而不是表名,这使得它更接近面向对象的编程。
除了java类和变量名之外,Hibernate查询语言不区分大小写。因此SeLeCT与sELEct与SELECT相同,但com.journaldev.model.Employee与com.journaldev.model.EMPLOYEE不同。
HQL查询是缓存的,但我们应该尽可能地避免它,否则我们将不得不处理关联。然而,由于面向对象的方法,它比本机sql查询更好。阅读更多HQL示例。
-
什么是Hibernate中的查询缓存?
Hibernate为查询结果集实现了一个缓存区域,该结果集与hibernate二级缓存紧密集成。
这是一项可选功能,需要在代码中执行其他步骤。这仅适用于使用相同参数频繁运行的查询。首先我们需要在hibernate配置文件中配置下面的属性。
<property name="hibernate.cache.use_query_cache">true</property>
而在代码中,我们需要使用Query的setCacheable(true)方法,快速示例如下所示。
Query query = session.createQuery("from Employee"); query.setCacheable(true); query.setCacheRegion("ALL_EMP");
-
我们可以在hibernate中执行本机sql查询吗?
Hibernate提供了通过使用
SQLQuery
对象来执行本机SQL查询的选项。但是对于正常情况,它不是推荐的方法,因为我们放弃了与hibernate关联和hibernate一级缓存相关的好处。阅读更多Hibernate Native SQL Query Example。
-
在hibernate中本机sql查询支持有什么好处?
当我们想要执行Hibernate API不支持的数据库特定查询(如查询提示或Oracle数据库中的CONNECT关键字)时,本机SQL查询会派上用场。
-
什么是命名SQL查询?
Hibernate提供了我们可以在中心位置定义的命名查询,并在代码中的任何位置使用它们。我们可以为HQL和Native SQL创建命名查询。
Hibernate命名查询可以在Hibernate映射文件中定义,也可以通过使用JPA注释@NamedQuery和@NamedNativeQuery来定义。
-
命名SQL查询有什么好处?
Hibernate Named Query帮助我们在中心位置对查询进行分组,而不是让它们分散在整个代码中。
创建hibernate会话工厂时会检查Hibernate Named Query语法,从而在命名查询出现任何错误时使应用程序快速失败。
Hibernate Named Query是全局的,意味着一旦定义它就可以在整个应用程序中使用。然而,Named查询的一个主要缺点是它很难调试,因为我们需要找出它定义的位置。
-
Hibernate Criteria API有什么好处?
Hibernate提供了更加面向对象的Criteria API,用于查询数据库和获取结果。我们不能使用Criteria来运行更新或删除查询或任何DDL语句。它仅用于使用更多面向对象的方法从数据库中获取结果。
Criteria API的一些常见用法是:
在Hibernate Criteria示例中学习一些快速示例。
- Criteria API提供了我们可以用于聚合函数的Projection,例如sum(),min(),max()等。
- Criteria API可与ProjectionList一起使用,仅用于获取所选列。
- Criteria API可以通过连接多个表来用于连接查询,有用的方法是createAlias(),setFetchMode()和setProjection()
- Criteria API可用于获取条件的结果,有用的方法是add(),我们可以在其中添加Restrictions。
- Criteria API提供了addOrder()方法,我们可以使用它来排序结果。
-
如何在日志文件中记录hibernate生成的sql查询?
我们可以在hibernate配置下面设置属性来记录SQL查询。
<property name="hibernate.show_sql">true</property>
但是,我们应该仅在开发或测试环境中使用它,并在生产环境中将其关闭。
-
什么是Hibernate代理以及它如何帮助延迟加载?
Hibernate使用代理对象来支持延迟加载。基本上,当您从表中加载数据时,hibernate不会加载所有映射的对象。一旦通过getter方法引用子对象或查找对象,如果链接实体不在会话高速缓存中,则代理代码将转到数据库并加载链接对象。它使用javassist有效地动态生成实体对象的子类实现。
-
如何在hibernate中实现关系?
我们可以在hibernate中轻松实现一对一,一对多和多对多关系。可以使用JPA注释以及基于XML的配置来完成。为了更好地理解,您应该阅读以下教程。
-
事务管理如何在Hibernate中运行?
休眠中的事务管理非常简单,因为大多数操作都不允许在事务之外。因此,在从SessionFactory获取会话后,我们可以调用session
beginTransaction()
来启动事务。此方法返回我们稍后可以使用的事务引用,以提交或回滚事务。整体hibernate事务管理优于JDBC事务管理,因为我们不需要依赖异常进行回滚。会话方法抛出的任何异常都会自动回滚事务。
-
什么是级联,什么是不同类型的级联?
当我们在实体之间建立关系时,我们需要定义不同操作将如何影响另一个实体。这是通过级联来完成的,它有不同的类型。
以下是在主要实体和次要实体之间应用级联的简单示例。
import org.hibernate.annotations.Cascade; @Entity @Table(name = "EMPLOYEE") public class Employee { @OneToOne(mappedBy = "employee") @Cascade(value = org.hibernate.annotations.CascadeType.ALL) private Address address; }
请注意,Hibernate CascadeType枚举常量与JPA略有不同
javax.persistence.CascadeType
,因此我们需要使用Hibernate CascadeType和Cascade注释进行映射,如上例所示。
CascadeType枚举中定义的常用级联类型是:- 无:没有级联,它不是类型,但是当我们没有定义任何级联时,父级中的操作不会影响子级。
- ALL:Cascades保存,删除,更新,逐出,锁定,复制,合并,持久化。基本上一切
- SAVE_UPDATE:Cascades保存和更新,仅在休眠时可用。
- DELETE:对应于Hibernate本机DELETE操作,仅在hibernate中。
- DETATCH,MERGE,PERSIST,REFRESH和REMOVE - 用于类似的操作
- LOCK:对应于Hibernate本机LOCK操作。
- REPLICATE:对应于Hibernate本机REPLICATE操作。
-
如何在hibernate应用程序中集成log4j日志?
Hibernate 4使用JBoss日志记录而不是早期版本中使用的slf4j。对于log4j配置,我们需要按照以下步骤操作。
就是这样,我们的设置准备好了。
org.apache.log4j.Logger
在java类中创建实例并开始记录。对于完整的示例代码,您应该通过Hibernate log4j示例和Servlet log4j示例。- 为maven项目添加log4j依赖项,如果不是maven,则添加相应的jar文件。
- 创建log4j.xml配置文件或log4j.properties文件并将其保存在类路径中。你可以随意保存文件名,因为我们将在下一步中加载它。
- 对于独立项目,使用静态块使用
DOMConfigurator
或配置log4jPropertyConfigurator
。对于Web应用程序,您可以使用ServletContextListener对其进行配置。
-
如何在Hibernate框架中使用应用服务器JNDI DataSource?
对于Web应用程序,最好允许servlet容器管理连接池。这就是我们为DataSource定义JNDI资源的原因,我们可以在Web应用程序中使用它。它在Hibernate中使用非常简单,我们只需要删除所有特定于数据库的属性,并使用下面的属性来提供JNDI DataSource名称。
<property name="hibernate.connection.datasource">java:comp/env/jdbc/MyLocalDB</property>
有关完整示例,请参阅Hibernate JNDI DataSource示例。
-
如何集成Hibernate和Spring框架?
Spring是最常用的Java EE Framework之一,而Hibernate是最流行的ORM框架。这就是Spring Hibernate组合在企业应用程序中大量使用的原因。使用Spring的最佳部分是它为使用Spring ORM模块的Hibernate提供了开箱即用的集成支持。将Spring和Hibernate框架集成在一起需要以下步骤。
有关完整示例,请参阅Spring Hibernate Integration和Spring MVC Hibernate Integration。
- 添加hibernate-entitymanager,hibernate-core和spring-orm依赖项。
- 为数据库操作创建Model类和相应的DAO实现。请注意,DAO类将使用将由Spring Bean配置注入的SessionFactory。
- 如果您使用的是Hibernate 3,则需要配置
org.springframework.orm.hibernate3.LocalSessionFactoryBean
或org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
在Spring Bean配置文件中。对于Hibernate 4,org.springframework.orm.hibernate4.LocalSessionFactoryBean
应该配置单个类。 - 注意,我们不需要使用Hibernate Transaction Management,我们可以使用
@Transactional
注释将其留给Spring声明式事务管理。
-
什么是HibernateTemplate类?
当Spring和Hibernate集成开始时,Spring ORM提供了两个辅助类 -
HibernateDaoSupport
和HibernateTemplate
。使用它们的原因是从Hibernate获取Session并获得Spring事务管理的好处。但是从Hibernate 3.0.1开始,我们可以使用SessionFactory
getCurrentSession()方法获取当前会话并使用它来获得spring事务管理的好处。如果你通过上面的例子,你会看到它是多么容易,这就是为什么我们不应该再使用这些类了。另一个好处
HibernateTemplate
是异常转换,但可以通过使用@Repository
带有服务类的注释轻松实现,如上面的spring mvc示例所示。这是判断您的知识以及您是否了解最近发展的一个技巧问题。 -
如何将Hibernate与Servlet或Struts2 Web应用程序集成?
Hibernate与Servlet或Struts2的集成需要使用
ServletContextListener
,完整的例子可以在Hibernate Struts2 Integration Example中找到。 -
Hibernate框架中使用了哪些设计模式?
Hibernate Framework中使用的一些设计模式是:
-
Hibernate框架遵循哪些最佳实践?
Hibernate中要遵循的一些最佳实践是:
- 始终检查主键字段访问权限,如果它是在数据库层生成的,那么您不应该为此设置setter。
- 默认情况下,hibernate直接设置字段值,而不使用setter。因此,如果您希望hibernate使用setter,那么请确保将正确的访问定义为
@Access(value=AccessType.PROPERTY)
。 - 如果访问类型是属性,请确保注释与getter方法一起使用,而不是与setter方法一起使用。避免在字段和getter方法上混合使用注释。
- 仅当使用HQL无法完成时才使用本机sql查询,例如使用特定于数据库的功能。
- 如果必须对集合进行排序,请使用有序列表,而不是使用Collection API对其进行排序。
- 明智地使用命名查询,将其保存在一个位置以便于调试。仅将它们用于常用查询。对于特定于实体的查询,您可以将它们保存在实体bean本身中。
- 对于Web应用程序,始终尝试使用JNDI DataSource,而不是配置为在hibernate中创建连接。
- 避免多对多关系,可以使用双向一对多和多对一关系轻松实现。
- 对于集合,请尝试使用列表,地图和集合。避免使用数组,因为您没有获得延迟加载的好处。
- 不要将异常视为可恢复,回滚事务并关闭会话。如果不这样做,Hibernate无法保证内存状态准确表示持久状态。
- 首选DAO模式,用于公开可与实体bean一起使用的不同方法
- 喜欢懒惰提取关联
-
什么是Hibernate Validator Framework?
数据验证是任何应用程序的组成部分。您将在表示层使用Javascript进行数据验证,然后在处理服务器端代码之前进行数据验证。在持久化之前也会进行数据验证,以确保它遵循正确的格式。
验证是一项交叉任务,因此我们应该尝试将其与业务逻辑区分开来。这就是为什么JSR303和JSR349提供了使用注释验证bean的规范。Hibernate Validator提供了这两个bean验证规范的参考实现。阅读更多Hibernate验证示例。
-
Hibernate Tools Eclipse插件有什么好处?
Hibernate Tools插件可以帮助我们轻松编写hibernate配置和映射文件。主要好处是帮助我们使用属性或xml标签的内容辅助。它还根据Hibernate DTD文件验证它们,因此我们知道任何错误。了解如何在Hibernate Tools Eclipse插件中安装和使用。
这就是Hibernate面试问题和答案的全部内容,我希望它可以帮助你作为一个新手或有经验的人进行面试。如果我在这里遗漏了任何重要问题,请告诉我,我会将其添加到列表中。
转载来源:https://www.journaldev.com/3633/hibernate-interview-questions-and-answers