Hibernate 面试问题和答案


我在这里分享一些重要的hibernate面试问题。

1.什么是ORM?

ORM代表对象关系映射。它是一种编程范式,用于将 java 对象持久保存到数据库表中。

2.什么是Hibernate?

Hibernate是纯 ORM 工具,用于将旧的 java 对象保存到数据库表中。hibernate的主要目标是避免陈旧JDBC code而更多地关注业务逻辑。您需要用它编写更少的代码。

3. Hibernate有什么优势?

Hibernate 的优点是:

  • 延迟加载
  • 缓存
  • 您不需要维护 JDBC 代码,Hibernate 会处理它。
  • 您需要编写更少的代码
  • 它提供了高级面向对象的 API

4.解释Hibernate的架构?

以下是带有核心类的 hibernate 的详细架构。

休眠架构

Hibernate 就像 java 代码和关系数据库之间的桥梁,提供面向对象的 API 来处理 JDBC 任务。

5、hibernate有哪些核心接口?

  • Session
  • SessionFactory
  • Configuration
  • Transaction
  • Query and Criteria interface.

6. 简单介绍一下hibernate中使用的Session接口?

Session接口主要由hibernate应用程序使用。Session 是重量轻、寿命短的对象,创建和销毁成本低。它允许您创建查询对象以检索持久对象。它为 Transaction 包装 JDBC 连接工厂。它拥有持久对象的强制(一级)缓存,用于导航对象图或通过标识符查找对象。

7. 会话对象是线程安全的吗?

Session对象不是线程安全的,需要在单线程中使用。每个线程都应该有自己的会话对象,并在完成工作后关闭它。

8. 简单介绍一下hibernate中使用的SessionFactory对象?

SessionFactory 是重量级对象,应该为每个数据库创建一个。SessionFactory 对象由多个会话共享。

9.什么是hibernate中的Configuration类?

配置类用于加载所需的休眠配置。它用于引导休眠并用于定位到休眠映射文件。

10. 简单解释一下Hibernate中的Criteria API?

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();

11. Hibernate中Query接口的简要说明?

查询接口是 Hibernate 查询的面向对象表示。您可以通过调用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);
}

12、hibernate中openSession和getCurrentSession有什么区别?

范围 开放会话 获取当前会话
Session object 它总是创建新的 Session 对象 如果不存在,它将创建一个新会话,否则使用当前休眠上下文中的相同会话
Flush and close 您需要显式刷新和关闭会话对象 您不需要刷新和关闭会话对象,它将由 Hibernate 内部自动处理
Performance 在单线程环境中,它比 getCurrentSession 慢 在单线程环境下,比 getOpenSession 快
Configuration 您无需配置任何属性即可调用此方法 你需要配置额外的属性“hibernate.current_session_context_class ”来调用getCurrentSession方法,否则会抛出异常。

13、hibernate中get和load方法有什么区别?

这是被问到最多的hibernate面试问题之一。

范围 得到 加载
Database retrieval 它总是命中数据库 它没有命中数据库
if null 如果没有得到有id的对象,则返回null 如果它确实获得了带有 id 的对象,它会抛出 ObjectNotFoundException
Proxy 它返回真实对象 它返回代理对象
Uae 如果不确定是否存在带有 id 的对象,可以使用 get 如果你确定对象的存在,你可以使用 load

14. 可以在hibernate中声明Entity类为final吗?

是的,您可以将实体类声明为 final,但这不被认为是一种好习惯,因为 hibernate 使用代理模式进行延迟初始化,如果您将其声明为 final,那么 hibernate 将无法创建子类并且将无法使用代理模式,因此它将限制性能和改进选项。

15、一级缓存和二级缓存的区别?

这是最重要的hibernate面试问题之一。

范围 一级缓存 二级缓存
协会 它在会话级别关联。 它在 SessionFactory 级别关联,并且通常每个应用程序都存在一个。
默认 默认启用 默认不启用,需要显式启用

16. hibernate中对象的状态是什么?

Transient :如果对象处于瞬态状态,则意味着它从未与会话相关联并且刚刚创建。

Persistent : 如果对象处于持久状态,则表示它与会话相关联,并且您刚刚从数据库中保存或检索了对象。

Detached :如果对象处于分离状态,则意味着会话已关闭并且对象不再是会话的一部分。如果您调用合并或更新,对象将返回到持久状态。

17. hibernate中的实体类不需要arg构造函数吗?

是的,hibernate 中的实体类不需要 arg 构造函数,因为 Hibernate 使用反射来创建实体类的实例,并且它要求 Entity 类中没有 arg 构造函数。

18.什么是HQL?

HQL 代表 Hibernate 查询语言。它是一种非常简单、高效且面向对象的查询语言,可简化复杂的 SQL 查询。您使用对象而不是表来编写查询。

19. session对象的save和saveOrUpdate方法有什么区别?

save(): 将对象存储在数据库中。它为 tQhe 对象生成标识符并返回它。如果对象已经存在于数据库中,则会抛出错误。

saveOrUpdate():如果标识不存在,SaveOrUpdate 方法保存对象。如果存在,则调用更新方法。

20.hibernate中有哪两种Collection?

  • 排序集合
  • 有序集合

21、hibernate中sorted和ordered collection有什么区别?

范围 排序集合 有序集合
排序 排序集合使用 java 的排序 API 对集合进行排序。 Ordered Collections 在检索对象时使用 order by 子句
默认 默认启用 默认不启用,需要显式启用

22.什么是hibernate中的延迟加载?

它用于性能改进。延迟加载意味着当您加载父对象时,子对象在请求之前不会被加载。事实上,当您访问子对象时,休眠会自动加载它们。它提高了性能,因为您不是一次加载整个对象。

23、什么是Hibernate中的LazyInitializationException?你为什么得到它?

当您使用延迟加载并且在关闭会话后访问子对象时,通常会发生此异常。

这就是关于hibernate面试问题的全部内容。

24. hibernate 中有哪些不同的集合类型?

Hibernate 中有 5 种集合类型可用于一对多关系映射。

  • Bag

  • Set

  • List

  • Ma

    ## 25. 如何记录 Hibernate 执行的 sql 查询?

    您可以设置hibernate.show_sqltrue在 Hibernate 配置文件中记录 sql 查询。

    <property name="hibernate.show_sql">true</property>

    ## 26. hibernate可以执行native sql吗?

    是的,您可以借助SQLQueryHibernate 中的对象来执行本机 sql。

    这是从数据库中获取员工列表并创建相应的员工对象的示例。

    // 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,该类将变为不可变的。

    ## 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

  • Session management
  • SQL optimization

    ## 31. 在 Hibernate 中可以使用哪些类型的连接?

    在 Hibernate 中有多种使用 join 的方法。

  • 使用一对一、一对多或多对多等关系

  • 在本机 SQL 查询中使用连接

  • 在 HQL 中使用连接

    ## 32. Hibernate中的方言是什么?

    Dialect 指定了 Hibernate 使用的数据库类型,以便 Hibernate 可以生成 SQL 语句的类型。

    例如: mysql 数据库org.hibernate.dialect.MySQL5Dialect 的方言: sqlserver 数据库的方言:org.hibernate.dialect.SQLServer2005Dialect

    ## 33. 可以分享一些Hibernate支持的数据库吗?

    以下是 Hibernate 支持的一些数据库:

    • MySQL
    • SQLServer
    • PostgreSQL
    • FrontBaase
    • Oracle
    • Sybase SQL Server

    ## 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 默认禁用查询级别缓存的原因。

    要启用,您需要执行以下操作:

    1. 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 的优点。

      • Criteria API 是干净且面向对象的 API。
      • Criteria API 提供了 Projection,可用于 sum()、min() 等聚合函数。
      • 与 HQL 相比,您可以编写更灵活和动态的查询。
      • 它具有 addOrder() 方法,可用于对结果进行排序。

      ## 37. Hiberante 中的级联是什么,你能列出级联的类型吗?

      大多数情况下,如果实体关系依赖于其他实体的存在。 例如: 在 Employee-Address 关系的情况下,如果 Employee 从数据库中删除,那么 Address 本身就没有意义。因此,当您从数据库中删除 Employee 时,其关联的 Address 也应该被删除。

      您可以使用级联来实现此目的。当您对实体执行操作时,可以对关联实体执行相同的操作。

      以下是 Hibernate 支持的级联类型:

      | 级联操作 | 描述 | | ------------ | ------------------------------------------------------------ | | ALL | 所有操作都将应用于父实体的关联实体。所有操作包括 DETACH、MERGE、PERSIST、REFRESH、REMOVE 等。 | | DETACH | 如果父实体与上下文分离,则关联实体也将被分离。 | | MERGE | 如果父实体被合并到上下文中,那么关联的实体也将被合并。 | | PERSIST | 如果父实体被持久化到上下文中,那么关联实体也将被持久化。 | | REFRESH | 如果在当前持久化上下文中刷新父实体,则关联实体也将被持久化。 | | REMOVE | 如果从当前持久性上下文中删除父实体,则关联实体也将被删除。 |

      ## 38、如何将log4j与Hibernate集成?

      对于 log4j 配置,您可以按照以下步骤操作:

      1. 为 maven 项目添加 log4j 依赖项。如果它不是 maven 项目,则将所需的 log4j jar 添加到类路径。

      2. 创建 log4j.xmllog4j.properties放入类路径。

      3. 使用DOMConfiguratorPropertyConfigurator在静态块中为独立应用程序配置 log4j。如果您有 Web 应用程序,那么您可以使用ServletContextListener它来配置它。

        39.什么是hibernate配置文件?

        Hibernate 配置文件包含数据库配置,如数据库 url、用户名、密码和方言等,用于初始化SessionFactory. 它还包含映射文件和实体类详细信息。

        ## 40. 你能列出用于 Hibernate 映射的重要注解吗?

        以下是一些可用于 Hibernate 映射的重要注解。

        @Entity:用于将类定义为实体bean。 @Table:用于定义Entity对应的数据库中的表名。 @Id:用于定义实体bean中的主键。 @Column:用于定义数据库中与实体bean属性相对应的列属性。 @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 中使用的一些设计模式:

        • 延迟加载的代理模式
        • 工厂模式SessionFactory
        • CriteriaAPI的查询对象
        • 数据映射器:一种模式,其中事务层在对象和数据库之间流动数据,同时保持它们彼此独立
        • 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;
            }
        
        }

        以下是需要进行的更改:

        1. 注释 Customer 类以@Entity将其声明为 Hibernate 实体
        2. 使用@Table注释将类映射到数据库中的表名
        3. 使用@id@GeneratedValue注解使id作为主键
        4. 用于@Column将属性映射到相应的数据库列

        这是代码:

        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/