1、为什么要使用 hibernate?
- 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码
- 基于jdbc的主流持久化框架,是一个优秀的ORM实现,很大程度的简化了dao层的编码工作
- 使用java的反射机制
- 性能好,是一个轻量级框架,映射灵活,支持很多关系型数据库,从一对一到多对多的各种复杂关系
2、什么是 ORM 框架?
ORM(Object Relation Mapping)对象关系映射
通过类与数据库表的映射关系,将对象持久化到数据库中
常见的ORM框架有Hibernate、Mybatis、EclipseLink、JFinal
3、hibernate 中如何在控制台查看打印的 sql 语句?
在 Hibernate 中,可以通过以下几种方式在控制台查看打印的 SQL 语句:
-
配置日志级别:在 Hibernate 的配置文件(如
hibernate.cfg.xml
)中,将日志级别设置为DEBUG
或TRACE
。这样,Hibernate 会在控制台打印更多详细的信息,包括执行的 SQL 语句。 -
使用日志框架:将 Hibernate 与日志框架(如 Log4j 或 SLF4J)集成,并在日志配置文件中设置适当的日志级别。这样可以更灵活地控制日志输出,并将 SQL 语句打印到指定的日志文件中。
-
开启 Hibernate 的显示 SQL 功能:在 Hibernate 的配置文件中,设置
show_sql
属性为true
。这样,Hibernate 会在执行 SQL 语句时将其打印到控制台。 -
使用 Hibernate 的拦截器:编写自定义的拦截器类,实现
org.hibernate.EmptyInterceptor
接口,并在preFlush
方法中获取当前执行的 SQL 语句,并将其打印到控制台。
4、hibernate 有几种查询方式?
HQL,QBC(Query By Criteria),原生SQL查询
5、hibernate 实体类可以被定义为 final 吗?
可以,但是这种做法不好。因为Hibernate会使用代理模式在延迟关联的情况下提高性能,如果把实体类定义成final类之后,因为java不允许对final类进行扩展,所以hibernate就无法再使用代理了,从而影响性能。
6、在 hibernate 中使用 Integer 和 int 做映射有什么区别?
如果使用基本类型变量int,如果数据库中对应的存储数据是null,使用PO类进行获取数据会出现类型转换异常。
如果使用你的是对象类型Integer则不会报错。
7、get()和 load()的区别?
get:get方法被调用时会立即发出SQL语句
load:当调用load方法的时候会返回一个目标对象的代理对象,在这个代理对象中只存储了目标对象的ID值,只有当调用除ID值以外的属性值的时候才会发出SQL查询。
8、说一下 hibernate 的缓存机制?
Hibernate 的缓存机制是其性能优化的重要手段之一。Hibernate 的缓存分为一级缓存和二级缓存。
- 一级缓存:也称为会话级缓存,是 Hibernate 中默认启用的缓存。它与当前的会话相关联,存储了从数据库中查询到的对象。当再次访问同一个对象时,Hibernate 会从一级缓存中获取,而不是再次查询数据库,从而提高了性能。
- 二级缓存:也称为进程级或应用级缓存,是在一级缓存的基础上进一步扩展的缓存。它可以在多个会话之间共享缓存的数据,从而减少了对数据库的访问次数。Hibernate 提供了多种二级缓存实现,如 Ehcache、Redis 等。
Hibernate 的缓存机制通过以下方式提高性能:
- 减少数据库访问次数:通过缓存已经查询到的对象,避免了重复查询数据库,从而减少了数据库的负载和响应时间。
- 提高数据访问效率:缓存中的数据可以直接访问,无需进行数据库查询和结果映射,提高了数据访问的效率。
- 支持事务隔离级别:Hibernate 的缓存可以与数据库的事务隔离级别配合使用,确保在事务提交之前,缓存中的数据与数据库中的数据保持一致。
需要注意的是,缓存机制虽然可以提高性能,但也可能带来一些问题,如缓存一致性、缓存过期等。因此,在使用缓存时,需要根据具体的业务需求和数据访问模式进行合理的配置和管理。
9、hibernate 是如何工作的?
- 读取并解析配置
- 读取并解析映射信息
- 创建Session Factory
- 打开Session
- 创建事务Transaction
- 持久化操作
- 提交事务
- 关闭Session
- 关闭SessionFactory
10、hibernate 对象有哪些状态?
- Transient(瞬时):对象刚new出来,还没设ID,设了其他值
- Persistent(持久):调用了save()、saveOrUpdate(),就变成Persistent
- Detached(托管):当session close()完之后,变成Detached
11、hibernate 实体类必须要有无参构造函数吗?为什么?
必须,因为hibernate框架会调用这个默认构造方法来构造实例对象。
如果没有提供任何构造方法,虚拟机会自动提供默认构造方法,如果开发人员提供了其他有参数的构造方法的话,虚拟机就不再提供默认构造方法,这时必须手动把无参构造器写出来。
12、在 hibernate 中 getCurrentSession 和 openSession 的区别是什么?
openSession:每次使用都是打开一个新的对象,而且使用完需要调用close方法关闭session
getCurrenctSession:如果已经有session,就使用旧的,如果没有再打开新的。
一般情况下都是使用getCurrenctSession