Hibernate基础面试题

  • 格式:docx
  • 大小:34.17 KB
  • 文档页数:3

Hibernate是一个Java环境的关系型数据库映射工具。

用来把对象模型表示的对象映射到基于SQL的关系模型中去。

对象关系映射对象关系映射(Object Relational Mapping,简称ORM)将Java程序中的对象自动持久化到关系型数据库中,反过来将数据库中的记录自动的读取到内存对象中。

以往开发程序,一般都是通过拼写sql语句访问数据库,这样代码繁琐易出错,且工作量大。

ORM所采取的办法就是将对象“翻译“成s ql 语句交给数据库服务器,数据库服务器根据sql语句进行存取。

Hibernate是一个优秀的ORM框架,它在JDBC基础上进行封装,只需少量代码就可以完成对数据库的操作。

在持久化层,对象分为哪些状态?分别列出来。

◆瞬时态(T ransient)是对象是创建时,瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系,在Hibernate中,可通过session的save()或saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象。

◆持久态(Persistent)是该对象在数据库中已有对应的记录,并拥有一个持久化标识,如果是用hibernate的delete()方法,对应的持久对象就变成瞬时对象,因数据库中的对应数据已被删除,该对象不再与数据库的记录关联。

当一个session执行close()或clear()、ev ict()之后,持久对象变成脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具有数据库识别值,但它已不在hibernate持久层的管理之下。

持久对象具有如下特点:1、和session实例关联;2、在数据库中有与之关联的记录。

◆脱管态(Detached)当与某持久对象关联的session被关闭后,该持久对象转变为脱管对象。

当脱管对象被重新关联到session上时,并再次转变成持久对象。

脱管对象拥有数据库的识别值,可通过update()、saveOrUpdate()等方法,转变成持久对象。

脱管对象具有如下特点:1、本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收;2、比瞬时对象多了一个数据库记录标识值。

lock和update区别update是把一个已经更改过的脱管状态的对象变成持久状态lock是把一个没有更改过的脱管状态的对象变成持久状态(针对的是因Session的关闭而处于脱管状态的po对象(2),不能针对因delete而处于脱管状态的po对象)对应更改一个记录的内容,两个的操作不同:update的操作步骤是:(1)属性改动后的脱管的对象的修改->调用updatelock的操作步骤是:(2)调用lock把未修改的对象从脱管状态变成持久状态-->更改持久状态的对象的内容-->等待f lush或者手动f lushsave 和update区别save是把一个对象做为一个新的数据保存update则是把一个脱管状态的对象或自由态对象(一定要和一个记录对应)更新到数据库,其实一个是保存一个是更新,一看都知道是有什么区别了update 和saveOrUpdate区别不管对象是什么状态,update()都只会做简单的更新操作,如果该对象在数据库中不存在,则update()操作没有意义,否则数据库中的数据会同步更新。

在执行saveOr Update()方法时,该方法会自动判断该对象的状态,如果为自由态则执行save操作,如果为游离态或者持久态则执行update操作。

flush和update区别update操作的是在自由态或脱管状态(因session的关闭而处于脱管状态)的对象flush是操作的在持久状态的对象。

默认情况下,一个持久状态的对象的改动(包含set容器)是不需要update的,只要你更改了对象的值,等待hibernate flush就自动更新或保存到数据库了。

hibernate flush发生在以下几种情况中:1、调用某些查询的和手动flush(),session的关闭、SessionFactory关闭结合、get()一个对象,把对象的属性进行改变,把资源关闭。

2、transaction commit的时候(包含了flush)update()方法和merge()方法如果持久化对象在数据库中存在,使用merge()方法操作时进行同步更新操作。

如果对象在数据库中不存在,merge()方法对对象则进行保存操作。

如果对象是游离状态,经过update操作后,对象转换为持久态。

但经过merge操作后,对象状态依然是游离态。

saveOrUpdate()方法和merge()方法主要区别在于如果session中存在两个主键值相同的对象,进行saveOr Update操作时会抛出异常。

这时必须使用merge来进行操作hibrnate session接口的get和load方法有何异同?这两个方法都是利用主键直接获取对象,并且可以使对象处于持久状态。

get()方法获取对象的时候,立即执行查询操作。

load()方法获取对象时不会立即执行查询操作,而是在第一次使用对象的时候才执行查询操作(延迟加载)。

能够延迟加载的对象都是被改写过的代理对象,当关联的session没有关闭时,访问这些延迟加载对象(代理对象)的属性,Hibernate会初始化这些代理,或者用Hibernate.initialize(proxy)来初始化代理对象,当相关联的session关闭后,再访问延迟加载的对象将不再出现异常。

hibrnate有哪几种查询数据的方式1) 使用主键id加载对象load() 、get()2) 通过对象导航,比如通过stu.getTeam()得到Team的实例3) HQL4) QBC(query by criteria)5) 直接使用SQL语句取得记录集hibrnate原理及意义Hibernate的工作是通过一个文件(x ml或Properties)在对象和数据库表之间建立一个映射关系,这样使得程序员可以使用对象编程的思想来操作数据库。

在它的底层依然使用JDBC操作数据库,而程序员就可以从JDBC中解放出来,专心实现程序的业务功能。

当要操作一个对象的时候,Hibernate会根据这种映射关系自动将对象保存到数据库或者从数据库取出数据库后保存到对象中。

1)读取并解析配置文件2)读取并解析映射信息,创建SessionFactory3)打开Session4)创建事物Transaction5)持久化操作6)提交事务7)关闭Session8)关闭SessionFactory意义:1) 对JDBC访问数据库的代码作了封装,大大简化了数据访问层繁琐的重复性代码。

2) Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。

他很大程度的简化DAO层的编码工作3) hiber nate使用Java反射机制,而不是字节码增强程序来实现透明性。

4) hiber nate的性能非常好,因为它是个轻量级框架。

映射的灵活性很出色。

它支持各种关系数据库,从一对一到多对多的各种复杂关系。

Hibernate主键生成方式⏹increment:当向数据库插入数据时,主键自动加1,与底层无关。

缺点是线程不安全,当多个线程并发的时候,可能会出现相同的主键。

⏹identity:用数据库提供的主键生成机制,与数据库底层无关,线程安全⏹native:由Hibernate根据方言选择主键生成方式,与底层无关⏹uuid.hex:由Hibernate基于128位唯一值产生算法生成16进制数值作为主键。

⏹assigned:主键由外部程序负责产生,无需Hibernate参与Hibernate对象之间的关系1) 关联(Association)分为一对一、一对多、多对多关联,如果类A与类B关联,那么被引用的类B将被定义为类A的属性2) 聚集(Aggregation)整体与部分之间的关系。

在聚集关系中,部分不能单独存在,它的声明周期依赖于整体类的对象的声明周期,当整体消失,部分也随着消失。

而关联可以允许每个类的对象单独存在。

3) 依赖(dependency):类与类之间的访问、调用关系。

如在类A中实例化类B或者调用类B的方法Hibernate延迟加载延迟加载原因:为了更好的提升Hibernate的性能,避免在某些情况下关联关系带来的不必要的性能开销。

(用的时候再调用或询)。

当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。

避免延迟加载:使用lazy属性关闭延迟加载;修改抓去(查询)策略;使用initialized静态方法对数据进行预加载。

Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、Hibernate的缓存机制缓存是位于应用程序与物理数据源之间、用于临时存放复制数据的内存区域。

目的是为了减少应用程序对屋里数据源的访问次数,从而提高应用程序的运行性能。

Hibernate在查询数据时,首先到缓存中去查找,如果找到就直接使用,找不到就会从物理数据源中查找,所以,把频繁使用的数据加载到缓存区后,就可以大大提高系统运行性能。

1)一级缓存(内置缓存)在Session中实现,当Session关闭一级缓存就失效了,如果在同一个Session中获取同一个对象两次,我们只看到输出一条查询。

管理:Session提供了clear方法,用于将一级缓存中的所有对象删除,使用evict方法可以将指定的对象从一级缓存中清除;Session的contains方法判断指定的对象是否在一级缓存中;flush方法表示刷新一次缓存区的内容,使之与数据库保持同步。

2)二级缓存(外置缓存)在SessionFactory中实现,同一个SessionFactory中的所有Session实例所共享。

session在查找一个对象时,首先会在自己的一级缓存中查找,再进入二级缓存中查找,最后从数据库中获得。

Hiber nate并未提供对二级缓存的产品化实现,而是为第三方缓存组件的使用提供了接口,当前的Hibernate支持的第三方二级缓存的实现如下:HCache OSCache warmCache Jboss TreeCache如何优化Hibernate1. 使用双向一对多关联,不使用单向一对多2. 灵活使用单向一对多关联3. 不用一对一,用多对一取代4. 配置对象缓存,不使用集合缓存5. 一对多集合使用Bag,多对多集合使用Set6. 继承类使用显式多态7. 表字段要少,表关联不要怕多,有二级缓存撑腰。