我在这里分享一些重要的hibernate面试问题。
ORM代表对象关系映射。它是一种编程范式,用于将 java 对象持久保存到数据库表中。
ORM
Hibernate是纯 ORM 工具,用于将旧的 java 对象保存到数据库表中。hibernate的主要目标是避免陈旧JDBC code而更多地关注业务逻辑。您需要用它编写更少的代码。
Hibernate
JDBC code
Hibernate 的优点是:
以下是带有核心类的 hibernate 的详细架构。
Hibernate 就像 java 代码和关系数据库之间的桥梁,提供面向对象的 API 来处理 JDBC 任务。
Session接口主要由hibernate应用程序使用。Session 是重量轻、寿命短的对象,创建和销毁成本低。它允许您创建查询对象以检索持久对象。它为 Transaction 包装 JDBC 连接工厂。它拥有持久对象的强制(一级)缓存,用于导航对象图或通过标识符查找对象。
Session
Session对象不是线程安全的,需要在单线程中使用。每个线程都应该有自己的会话对象,并在完成工作后关闭它。
SessionFactory 是重量级对象,应该为每个数据库创建一个。SessionFactory 对象由多个会话共享。
配置类用于加载所需的休眠配置。它用于引导休眠并用于定位到休眠映射文件。
Criteria API 是一种通过组合 Criterion 对象(也称为 Criterion 查询)来检索实体的 API。
Criteria API 是在持久性数据库上构建动态查询的优雅方式。
让我们在示例的帮助下理解。 您有 Employee 类,它有两个属性,即姓名和年龄。
package org.arpit.java2blog; /* * This is our model class and it corresponds to Employee table in database */ @Entity @Table(name="EMPLOYEE") public class Employee { @Id @Column(name="id") @GeneratedValue(strategy=GenerationType.IDENTITY) int id; @Column(name="name") String name; @Column(name="age") int age; public Employee(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
您想获取姓名以 A 开头且年龄大于 30 的员工列表。
您可以编写如下查询。
Criteria criteria = session.createCriteria(Employee.class); criteria.add(Restrictions.like("name","A%"); criteria.add(Restrictions.gt("age",30); List<Employee> employeeList = criteria.list();
查询接口是 Hibernate 查询的面向对象表示。您可以通过调用Session.createQuery()方法获取查询对象。
Session.createQuery()
这是使用查询 API 执行本机查询的简单示例。
SQLQuery query = session.createSQLQuery("select name, age from Employee"); List<Object[]> rows = query.list(); for(Object[] row : rows){ Employee e = new Employee(); e.setName(row[0].toString()); e.setAge(Integer.parseInt(row[1].toString())); System.out.println(e); }
这是被问到最多的hibernate面试问题之一。
是的,您可以将实体类声明为 final,但这不被认为是一种好习惯,因为 hibernate 使用代理模式进行延迟初始化,如果您将其声明为 final,那么 hibernate 将无法创建子类并且将无法使用代理模式,因此它将限制性能和改进选项。
这是最重要的hibernate面试问题之一。
Transient :如果对象处于瞬态状态,则意味着它从未与会话相关联并且刚刚创建。
Persistent : 如果对象处于持久状态,则表示它与会话相关联,并且您刚刚从数据库中保存或检索了对象。
Detached :如果对象处于分离状态,则意味着会话已关闭并且对象不再是会话的一部分。如果您调用合并或更新,对象将返回到持久状态。
是的,hibernate 中的实体类不需要 arg 构造函数,因为 Hibernate 使用反射来创建实体类的实例,并且它要求 Entity 类中没有 arg 构造函数。
HQL 代表 Hibernate 查询语言。它是一种非常简单、高效且面向对象的查询语言,可简化复杂的 SQL 查询。您使用对象而不是表来编写查询。
save(): 将对象存储在数据库中。它为 tQhe 对象生成标识符并返回它。如果对象已经存在于数据库中,则会抛出错误。
save():
saveOrUpdate():如果标识不存在,SaveOrUpdate 方法保存对象。如果存在,则调用更新方法。
saveOrUpdate():
它用于性能改进。延迟加载意味着当您加载父对象时,子对象在请求之前不会被加载。事实上,当您访问子对象时,休眠会自动加载它们。它提高了性能,因为您不是一次加载整个对象。
当您使用延迟加载并且在关闭会话后访问子对象时,通常会发生此异常。
这就是关于hibernate面试问题的全部内容。
Hibernate 中有 5 种集合类型可用于一对多关系映射。
Bag
Set
List
Ma
## 25. 如何记录 Hibernate 执行的 sql 查询?
您可以设置hibernate.show_sql为true在 Hibernate 配置文件中记录 sql 查询。
hibernate.show_sql
true
<property name="hibernate.show_sql">true</property>
## 26. hibernate可以执行native sql吗?
是的,您可以借助SQLQueryHibernate 中的对象来执行本机 sql。
SQLQuery
这是从数据库中获取员工列表并创建相应的员工对象的示例。
// Crate session object SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.getCurrentSession(); // Get list of employees with help of SQLQuery. Transaction tx = session.beginTransaction(); SQLQuery sqlQuery = session.createSQLQuery("select id, name, age from Employee"); List<Object[]> rows = sqlQuery.list(); for(Object[] row : rows){ Employee employee = new Employee(); employee.setId(Long.parseLong(row[0].toString())); employee.setName(row[1].toString()); employee.setAge(Integer.parseInt(row[2].toString())); System.out.println(employee); }
## 27. Hibernate 中有哪些继承映射策略?
Hibernate 支持三种策略。您可以使用 xml 文件或 JPA 注释来实现它们。
每个子类的表
## 28. 如何在 Hibernate 中使类不可变?
您可以将类标记为mutable=false,该类将变为不可变的。
mutable=false
## 29. Hibernate 中的 dirty checking是什么?
如果对象在事务中被修改,那么它的状态将在您提交事务时自动更新。
这是一个例子:
SessionFactory factory = cfg.buildSessionFactory(); Session session = factory.openSession(); Transaction tx=session.beginTransaction(); Employee e1 = (Employee) session.get(Employee.class, Integer.valueOf(10001)); e1.setAge(32); tx.commit(); session.close();
在这里,我们在获取员工实例后更新员工年龄,并且在我们提交事务时自动更新。
## 30、你对Hibernate调优的理解是什么?
Hibernate 调优是优化 Hibernate 应用程序性能的过程。
一些性能调整策略是:
Data Caching
SQL optimization
## 31. 在 Hibernate 中可以使用哪些类型的连接?
在 Hibernate 中有多种使用 join 的方法。
使用一对一、一对多或多对多等关系
在本机 SQL 查询中使用连接
在 HQL 中使用连接
## 32. Hibernate中的方言是什么?
Dialect 指定了 Hibernate 使用的数据库类型,以便 Hibernate 可以生成 SQL 语句的类型。
例如: mysql 数据库org.hibernate.dialect.MySQL5Dialect 的方言: sqlserver 数据库的方言:org.hibernate.dialect.SQLServer2005Dialect
org.hibernate.dialect.MySQL5Dialect
org.hibernate.dialect.SQLServer2005Dialect
## 33. 可以分享一些Hibernate支持的数据库吗?
以下是 Hibernate 支持的一些数据库:
## 34.什么是Hibernate中的命名查询?
命名查询可帮助您在单个位置对 HQL/SQL 语句进行分组。当您想使用它们时,您可以在代码中按名称引用它。它可以帮助您避免由于项目中分散的查询而可能发生的代码混乱。
package org.arpit.java2blog; @NamedQueries( { @NamedQuery( name = "getEmployeeByName", query = "from Employee e where e.name = :name" ) } ) /* * This is our model class and it corresponds to Employee table in database */ @Entity @Table(name="EMPLOYEE") public class Employee { @Id @Column(name="id") @GeneratedValue(strategy=GenerationType.IDENTITY) int id; @Column(name="name") String name; @Column(name="age") int age; public Employee(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
您可以在主类中执行查询,如下所示:
TypedQuery query = session.getNamedQuery("getEmployeeByName"); query.setParameter("name","John"); List<Employee> employees=query.getResultList(); System.out.println(employees);
## 35、什么是Hibernate中的查询缓存?
如果您有使用相同参数一遍又一遍运行的查询,那么查询缓存可以提高应用程序的性能。
缓存查询结果的好处非常有限,并且取决于应用程序的使用情况。这就是 Hibernate 默认禁用查询级别缓存的原因。
要启用,您需要执行以下操作:
hibernate.cache.use_query_cache在休眠配置文件中设置。
hibernate.cache.use_query_cache
<property name="hibernate.cache.use_query_cache">true</property>
2.您需要为特定查询启用查询缓存。这是一个例子:
List<Employees> employee = session.createQuery("from Employee e where e.name = :name") .setEntity("employee", employee) .setMaxResults(15) .setCacheable(true) .setCacheRegion("employeeReg") .list();
## 36. Hibernate 中的 Criteria API 有什么好处?
Criteria API 可用于使用面向对象的方法从数据库中获取实体。 以下是标准 API 的优点。
## 37. Hiberante 中的级联是什么,你能列出级联的类型吗?
大多数情况下,如果实体关系依赖于其他实体的存在。 例如: 在 Employee-Address 关系的情况下,如果 Employee 从数据库中删除,那么 Address 本身就没有意义。因此,当您从数据库中删除 Employee 时,其关联的 Address 也应该被删除。
您可以使用级联来实现此目的。当您对实体执行操作时,可以对关联实体执行相同的操作。
以下是 Hibernate 支持的级联类型:
| 级联操作 | 描述 | | ------------ | ------------------------------------------------------------ | | ALL | 所有操作都将应用于父实体的关联实体。所有操作包括 DETACH、MERGE、PERSIST、REFRESH、REMOVE 等。 | | DETACH | 如果父实体与上下文分离,则关联实体也将被分离。 | | MERGE | 如果父实体被合并到上下文中,那么关联的实体也将被合并。 | | PERSIST | 如果父实体被持久化到上下文中,那么关联实体也将被持久化。 | | REFRESH | 如果在当前持久化上下文中刷新父实体,则关联实体也将被持久化。 | | REMOVE | 如果从当前持久性上下文中删除父实体,则关联实体也将被删除。 |
## 38、如何将log4j与Hibernate集成?
对于 log4j 配置,您可以按照以下步骤操作:
为 maven 项目添加 log4j 依赖项。如果它不是 maven 项目,则将所需的 log4j jar 添加到类路径。
创建 log4j.xml 或log4j.properties放入类路径。
log4j.properties
使用DOMConfigurator或PropertyConfigurator在静态块中为独立应用程序配置 log4j。如果您有 Web 应用程序,那么您可以使用ServletContextListener它来配置它。
DOMConfigurator
PropertyConfigurator
ServletContextListener
39.什么是hibernate配置文件?
Hibernate 配置文件包含数据库配置,如数据库 url、用户名、密码和方言等,用于初始化SessionFactory. 它还包含映射文件和实体类详细信息。
SessionFactory
## 40. 你能列出用于 Hibernate 映射的重要注解吗?
以下是一些可用于 Hibernate 映射的重要注解。
@Entity:用于将类定义为实体bean。 @Table:用于定义Entity对应的数据库中的表名。 @Id:用于定义实体bean中的主键。 @Column:用于定义数据库中与实体bean属性相对应的列属性。 @OneToOne, @ManyToOne, @ManyToMany: 这些注释用于定义各种实体之间的关系。 @JoinColumn:用于指定加入实体关联的映射列。
@Entity
@Table
@Id
@Column
@OneToOne
@ManyToOne
@ManyToMany
@JoinColumn
这是一个示例: 我们使用具有一对一关系的两个实体 Country 和 Capital。
package org.arpit.java2blog; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name="COUNTRY") public class Country { @Id @Column(name="Country_Name") String countryName ; @OneToOne @JoinColumn(name="Capital_Name") Capital capital; @Column(name="Country_Population") long countryPopulation; public Country() { } public Country(String countryName, long countryPopulation) { this.countryName = countryName; this.countryPopulation = countryPopulation; } public long getCountryPopulation() { return countryPopulation; } public void setCountryPopulation(long countryPopulation) { this.countryPopulation = countryPopulation; } public String getCountryName() { return countryName; } public void setCountryName(String countryName) { this.countryName = countryName; } public Capital getCapital() { return capital; } public void setCapital(Capital capital) { this.capital = capital; } }
Capital.java
package org.arpit.javapostsforlearning;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="CAPITAL") public class Capital { @Id @Column(name="Capital_Name") String capitalName; @Column(name="Capital_Population") long capitalPopulation; public Capital() { } public Capital(String capitalName, long capitalPopulation) { super(); this.capitalName = capitalName; this.capitalPopulation = capitalPopulation; } public String getCapitalName() { return capitalName; } public void setCapitalName(String capitalName) { this.capitalName = capitalName; } public long getCapitalPopulation() { return capitalPopulation; } public void setCapitalPopulation(long capitalPopulation) { this.capitalPopulation = capitalPopulation; } }
## 41. Hibernate中使用了哪些设计模式?
以下是 Hibernate 中使用的一些设计模式:
Criteria
Domain Model pattern
## 42. 给定一个 Customer 类,您需要将客户数据以客户 ID 作为主键保存在数据库中。请列出您需要进行的更改?
这是表 CUSTOMER 的定义。
CREATE TABLE CUSTOMER ( id int(11) NOT NULL AUTO_INCREMENT, Customer_Name varchar(255) DEFAULT NULL, email varchar(255) DEFAULT NULL, PRIMARY KEY (id) )
这是客户类的定义
package org.arpit.java2blog.model; /* * This is our model class and it corresponds to Customer table in database */ = public class Customer{ int id; String customerName; String email; public Customer() { super(); } public Customer(String customerName,String email) { super(); this.customerName=customerName; this.email=email; } public String getCustomerName() { return customerName; } public void setCustomerName(String customerName) { this.customerName = customerName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
以下是需要进行的更改:
@id
@GeneratedValue
这是代码:
package org.arpit.java2blog.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; /* * This is our model class and it corresponds to Customer table in database */ @Entity @Table(name="CUSTOMER") public class Customer{ @Id @Column(name="id") @GeneratedValue(strategy=GenerationType.IDENTITY) int id; @Column(name="Customer_Name") String customerName; @Column(name="email") String email; public Customer() { super(); } public Customer(String customerName,String email) { super(); this.customerName=customerName; this.email=email; } public String getCustomerName() { return customerName; } public void setCustomerName(String customerName) { this.customerName = customerName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
原文链接:https://codingdict.com/