Hibernate 面试题

Hibernate 面试题
1.为什么需要使用Hibernate?
1)Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,可以自动完成object和关系数据库之间的转换,提高开发效率。用Hibernate,通过面向对象的方式进行查询(对查询结果自动封装到实体,而不像jdbc那样手动封装)、轻量级封装jdbc操作是它最大的优势。
2)hibernate可以跨数据库。 作为一个通用orm框架,首先必须兼容主流的数据库,如果hibernate只能在某一个数据库上跑。那它肯定不会有目前的成就。
3)结果这一点就变成了很多产品开发的基础,这些产品只需要关注自己的业务,不需要考虑在不同的数据库之间进行迁移了,一切底层都交给hibernate,只做好自己擅长的事情,花最少的时间获得最大的价值。
4)hibernate上面附着了一大堆的扩展,hibernate-validator可以做数据校验,hibernate-search可以玩全文检索,hibernate-shard可以做水平分表。
5)Hibernate的性能非常好,因为它是个轻量级框架,映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
2.Hibernate使用步骤
1)导入hibernate的jar文件和数据库的jar文件
2)编写hibernate配置文件,hibernate.cfg.xml,默认放在src目录,此文件保存数据库的连接信息,hibernate全局属性信息,以及关联的实体映射文件。
3)编写实体及实体映射文件。如果是在3.2以上版本,则可用注解的方式,可不需要编写.hbm.xml文件。
编写完了配置文件之后,具体的使用步骤如下:
1)读取并解析配置文件
2)读取并解析映射信息,创建SessionFactory
3)打开Session
4)创建事务Transaction
5)持久化操作
6)提交事务
7)关闭Session
8)关闭SessionFactory
上面这些步骤是在单独使用Hibernate的步骤,如果通过spring集成Hibernate,则代码更加的简单。例如使用Spring的AOP声明式事务,则不需要手工开启和关闭Session及提交或回滚事务。
3.谈谈你对Hibernate的理解。
1). 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象、建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上都是要得到一个结果,程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化。
2).为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息。从Java程序的运行功能上来讲,保存对象状态的功能相比系统运行的其他功能来说,应该是一个很不起眼的附属功能,java采用jdbc来实现这个功能,这个不起眼的功能却要编写大量的代码,而做的事情仅仅是保存对象和恢复对象,并且那些大量的jdbc代码并没有什么技术含量,基本上是采用一套例行公事的标准代码模板来编写,是一种苦活和重复性的工作。
3).通过数据库保存java程序运行时产生的对象和恢复对象,其实就是实现了java对象与关系数据库记录的映射关系,称为ORM(即Object Relation Mapping),人们可以通过封装JDBC代码来实现了这种功能,封装出来的产品称之为ORM框架,Hibernate就是其中的一种流行ORM框架。使用Hibernate框架,不用写JDBC代码,仅仅是调用一个save方法,就可以将对象保存到关系数据库中,仅仅是调用一个get方法,就可以从数据库中加载出一个对象。
4).使用Hibernate的基本流程是:配置Configuration对象、产生SessionFactory、创建session对象,启动事务,完成CRUD操作,提交事务,关闭session。
5).使用Hibernate时,先要配置hibernate.cfg.xml文件,其中配置数据库连接信息和方言等,还要为每个实体配置相应的hbm.xml文件,hibernate.cfg.xml文件中需要登记每个hbm.xml文件。
6).在应用Hibernate时,重点要了解Session的缓存原理,级联,延迟加载和hql查询。
4.MBatis与Hibernate有什么不同?
相同点:屏蔽jdbc api的底层访问细节,使用我们不用与jdbc api打交道,就可以访问数据。
jdbc api编程流程固定,还将sql语句与java代码混杂在了一起,经常需要拼凑sql语句,细节很繁琐。
Mbatis的好处:屏蔽jdbc api的底层访问细节;将sql语句与java代码进行分离;提供了将结果集自动封装称为实体对象和对象的集合的功能,queryForList返回对象集合,用queryForObject返回单个对象;提供了自动将实体对象的属性传递给sql语句的参数。
Hibernate是一个全自动的orm映射工具,它可以自动生成sql语句,ibatis需要我们自己在xml配置文件中写sql语句,hibernate要比ibatis功能负责和强大很多。因为hibernate自动生成sql语句,我们无法控制该语句,我们就无法去写特定的高效率的sql。对于一些不太复杂的sql查询,hibernate可以很好帮我们完成,但是,对于特别复杂的查询,hibernate就很难适应了,这时候用ibatis就是不错的选择,因为ibatis还是由我们自己写sql语句。
5.Hibernate中实体对象的三种状态。
1)瞬时状态
2)持久状态
3)游离状态
6.介绍一下Hibernate的二级缓存
按照以下思路来回答:
(1)首先说清楚什么是缓存,(2)再说有了hibernate的Session就是一级缓存,即有了一级缓存,为什么还要有二级缓存,(3)最后再说如何配置Hibernate的二级缓存。

  1. 缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中(一个数据结构中),这个数据结构通常是或类似Hashmap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用。
  2. Hibernate的Session就是一种缓存,我们通常将之称为Hibernate的一级缓存,当想使用session从数据库中查询出一个对象时,Session也是先从自己内部查看是否存在这个对象,存在则直接返回,不存在才去访问数据库,并将查询的结果保存在自己内部。由于Session代表一次会话过程,一个Session与一个数据库连接相关连,所以Session最好不要长时间保持打开,通常仅用于一个事务当中,在事务结束时就应关闭。并且Session是线程不安全的,被多个线程共享时容易出现问题。通常只有那种全局意义上的缓存才是真正的缓存应用,才有较大的缓存价值,因此,Hibernate的Session这一级缓存的缓存作用并不明显,应用价值不大。Hibernate的二级缓存就是要为Hibernate配置一种全局缓存,让多个线程和多个事务都可以共享这个缓存。我们希望的是一个人使用过,其他人也可以使用,session没有这种效果。
  3. 二级缓存是独立于Hibernate的软件部件,属于第三方的产品,多个厂商和组织都提供有缓存产品,例如,EHCache和OSCache等等。在Hibernate中使用二级缓存,首先就要在hibernate.cfg.xml配置文件中配置使用哪个厂家的缓存产品,接着需要配置该缓存产品自己的配置文件,最后要配置Hibernate中的哪些实体对象要纳入到二级缓存的管理中。明白了二级缓存原理和有了这个思路后,很容易配置起Hibernate的二级缓存。扩展知识:一个SessionFactory可以关联一个二级缓存,也即一个二级缓存只能负责缓存一个数据库中的数据,当使用Hibernate 的二级缓存后,注意不要有其他的应用或SessionFactory来更改当前数据库中的数据,这样缓存的数据就会与数据库中的实际数据不一致。
    7.Hibernate的数据加载方式
    1)即时加载
    2)延迟加载
    ①  集合类型的延迟加载
    ②  实体对象的延迟加载
    ③  属性延迟加载
    区别:
    1)即时加载,当实体加载完后,立即加载其关联数据。
    2)延迟加载就是当真正需要数据的时候,才真正执行数据加载操作。
    8.Hibernate如何延迟加载?
    延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。下面我们就分别介绍这些种类的延迟加载的细节。
    1)实体对象的延迟加载:
    2)集合类型的延迟加载:
    3)属性延迟加载:(需要对该实体类做字节码增强操作,否则无法生效)
    4)实体属性延时加载
    9.Hibernate中怎样实现类之间的关系?(如:一对多、多对多关系)
    类与类之间的关系主要体现在表与表之间的关系进行操作,它们都是对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many。
    最常用的关系是双向一对多关系,也即主从表之间的关系:
    双向一对多关系中,在这表这边配置:
    Set集合,one-to-many
    在从表这边配置many-to-one
    10.如何优化Hibernate?
    1)灵活使用单向一对多关联
    2)不用一对一、用多对一取代
    3)配置对象缓存,不使用集合缓存
    4)一对多集合使用Bag,多对多集合使用Set
    5)继承类使用显示多态
    6)表字段要少,表关联不要怕多,有二级缓存撑腰
    7)使用双向一对多关联,不是单向一对多
    11.说下Hibernate缓存机制
    内部缓存在Hibernate中又叫一级缓存,属于应用事务级缓存
    二级缓存:
    1)应用级缓存
    2)分布式缓存
    条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非关键数据
    3)第三方缓存的实现

12.hibernate进行多表查询每个表中各取几个字段,也就是说查询出来的结果集没有一个实体类与之对应如何解决
1)解决方案一,按照Object[]数据取出数据,然后自己组bean
解决方案二,对每个表的bean写构造函数,比如表一要查出field1,field2两个字段,那么有一个构造函数就是Bean(type1 filed1,type2 field2) ,然后在hql里面就可以直接生成这个bean了。
13.hibernate的工作原理
从以下四个方面来说明工作原理:
1)hibernate如何连接数据库?
配置文件Hibernate.cfg.xml文件中定义了和数据库进行连接的信息,包括数据库方言.jdbc驱动.用户名.密码和URL等。Configuration 类借助dom4j的xml解析器进行xml的解析设置环境,然后使用这些环境属性来生成sessionfactory。这样sessionfactory生成的session 就能够成功获得数据库的连接。
2)hibernate如何进行数据库写操作?
当保存一个pojo持久化对象时,触发Hibernate保存事件监听器进行处理。Hibernate通过映射文件获得对象对应的数据库。表名以及属性对应的数据库列名,然后通过反射机制获得持久化对象的各个属性,最终组织向数据库插入新对象的SQL的insert语句。调用session.save()保存数据后这个对象会被标识为持久化状态放在session,当事务进行提交时才真正执行insert语句。
3)hibernate如何从数据中载入对象?
当需要读取读取文件时,Hibernate先尝试从session缓存中读取,如果session缓存数据不存在或是脏数据并且配置了二级缓存,Hibernate尝试从二级缓存中检索数据;否则Hibernate会根据对象类型·主键等信息组织select语句到数据库中读取,再把select结果组织成对象返回。
4)hibernate如何进行数据库查询操作?
Hibernate提供SQL、HQL、Criteria查询方式。HQL是其中运用最广泛的查询方式。用户使用session.createQuery()函数以一条HQL语句为参数创建Query查询对象后,Hibernate会使用Anltr库把HQL语句解析成jdbc可以识别的sql语句。如果设置了查询缓存,那么执行Query.list()时,Hibernate会先对查询缓存进行查询,如果查询缓存不存在,再使用select语句查询数据库。
14.hibernate的inverse属性的作用?
在hibernate的集合属性配置(即一对多或多对多关联)的时候,在set节点上可以配置inverse属性,该属性的主要作用是设置关联属性的控制权,主要是用来指定one方是否拥有对关联属性的控制权,inverse=true表明one方对关联属性字段进行控制。举例来说,班级和学生两个实体是一对多关系,当在班级实体的映射文件中设置集合属性的inverse节点为true,则意味着对班级实体做操作时,不会对关系造成影响。
15.cascade属性和inverse属性的作用和区别?
1)Cascade指的是关联对象之间的级联操作
2)Inverse指的是关联关系的控制方向
16.为什么要用 ORM? 和 JDBC 有何不一样?
orm是一种思想,就是把object转变成数据库中的记录,或者把数据库中的记录转变成objecdt,我们可以用jdbc来实现这种思想,其实,如果我们的项目是严格按照oop方式编写的话,我们的jdbc程序不管是有意还是无意,就已经在实现orm的工作了。
现在有许多orm工具,它们底层调用jdbc来实现了orm工作,我们直接使用这些工具,就省去了直接使用jdbc的繁琐细节,提高了开发效率,现在用的较多的orm工具是hibernate。也听说一些其他orm工具,如toplink,ojb等。
17.hibernate中get()与load()区别
请注意如果没有匹配的数据库记录,load()方法可能抛出无法恢复的异常(unrecoverable exception)。 如果类的映射使用了代理(proxy),load()方法会返回一个未初始化的代理,直到你调用该代理的某方法时才会去访问数据库。 若你希望在某对象中创建一个指向另一个对象的关联,又不想在从数据库中装载该对象时同时装载相关联的那个对象,那么这种操作方式就用得上的了。 如果为相应类映射关系设置了batch-size, 那么使用这种操作方式允许多个对象被一批装载(因为返回的是代理,无需从数据库中抓取所有对象的数据)。 如果你不确定是否有匹配的行存在,应该使用get()方法,它会立刻访问数据库,如果没有对应的行,会返回null。
18.Hiberane中Query对象的list()方法和iterate()方法的区别:
list()方法不在缓存中读取数据,它总是一次性的从数据库中直接查询所有符合条件的数据,同时将获取的数据写入缓存。
iterate()方法则是获取了符合条件的数据的id后,首先根据id在缓存中寻找符合条件的数据,若缓存中无符合条件的数据,再到数据库中查询。
19.Hibernate支持两种查询方式:
1)HQL(Hibernate Query Languge)查询:是一种面向对象的查询语言。(应用较为广泛)
2)Criteria查询又称为“对象查询“:用面向对象的方式将构造查询的过程做了封装。
20.为什么使用HQL查询?
HQL是一种面向对象的查询语言,支持属性查询、参数查询、关联查询、分页查询等特性,还支持统计函数。还有如下优点:
1)使用HQL可以避免使用JDBC查询的一些弊端。
2)不需要在编写繁复的SQL语句,我们将针对实体类及其属性进行查询。
3)查询结果是直接存放到List中的对象,不需要再次封装。
4)HQL还独立于数据库,对不同的数据库根据Hibernate dialect属性的配置自动生成不同的SQL语句执行
21.使用HQL步骤
1)得到session
2)编写HQL语句
3)创建Query对象
4)执行查询,得到结果
22.HQL优化
1)避免or操作
2)避免使用not
3)避免like的特殊形式
4)避免having子句
5)避免使用distinct
23.HQL联接查询有几种方式?
1)内联接
2)迫切内联接
3)左外联接
4)迫切左外联接
5)右外联接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值