三大框架面试笔记-Hibernate


Hibernate概念:

是一个面向JAVA环境得对象/关系数据库映射工具。主要体现:

1.      是开源的持久层框架

2.      ORM映射工具,建立面向对象的域模型和关系数据模型之间得映射

3.      是连接JAVA工程和数据库得中间件

4.      对JDBC得封装,负责对JAVA对象得持久化

5.      在分层结构中处于持久化层,封装了数据库的访问细节,使业务逻辑层更专注实现业务逻辑

作用:

1.      Hibernate对JDBC访问数据库代码进行了封装,大大减少了访问数据库层繁琐得重复代码

2.      Hibernate是一个基于JDBC得主流持久化框架,是一个优秀得ORM实现,很大程度的减少了DAO层得编码工作

3.      Hibernate使用JAVA得反射机制,而不是字节码增强程序类实现得透明性

4.      Hibernate的性能非常好,因为它是一个轻量级框架,映射得灵活性很出色。它支持很多关系型数据库,从一对一到多对多复杂的关系

持久化

封装了数据访问的细节,为业务逻辑层提供了面向对象的API。完善的持久化层应该达到的目标:

            1.  代码重用性高,可完成所有的数据访问操作

2.  如果需要的话,能够支持多种数据库平台。

3.  具有相对独立性,当持久化层变化时,不会影响上层实现。

 

持久化的概念:实体域对象在内存中创建后,不能永久存在。将实体域对象永久保存起来,就是持久化的过程

 

ORM

实现思想:将关系数据库中表中的记录映射成为对象,以对象的形式展现,程序员可以把对数据库的操作转化为对对象的操作

 

作用:ORM的目的是为了方便开发人员以面向对象的思想来实现对数据库的操作,充当业务逻辑层和数据库层之间的桥梁

 

运行原理:

1.       运用反射机制,获得Customer对象的Customer.class类

2.       参照映射文件得到Customer类对应的表的信息,以及和Customer类关联的类以及  相应的表信息

3.       根据以上信息生成SQL语句

4.       调用hibernate API,执行该语句

关联关系

1.       单向关联:仅仅建立了A类和B类得关联,但是B类却没有建立到A类得关联关系

2.       双向关联:即建立A类到B类得关联关系,又建立了B类到A类得关联关系

 

²  多对一
在Hibernate中使用<many-to-one>来映射多对一关联关系
  * name:设定待映射的持久化类的名字。

* column:设定和持久化类的属性对应的表的外键。

* class:设定持久化类的属性的类型。

* not-null:是否允许为空。

² 一对多
在Hibernate中使用<set>来映射一对多双向关联关系
  * name:设定待映射持久化类的属性名。

* cascade:设定级联操作的程度。

* key:子属性:设定与所关联的持久化类对应的表的外键。

* column: 指定关联表的外键名

* one-to-many:子属性:设定所关联的持久化类(集合中存放的对象)。

  *class:指定关联的持久化类的类名

 

注意:Hibernate会自动清理缓存中的所有持久化对象,按照持久化对象的改变来同步更新数据库,因此执行了上述的两条更新语句所以会产生两条update语句

在一对多双向关联时,有一个inverse属性,该属性表示由双方哪一方来维持数据库的关系,通常情况下,都是由多的一方维持。在映射一对多的双向关联关系时,应该在one方把inverse属性设为true,这可以提高性能。

级联删除:如果cascade属性取默认值none,不会自动删除和customer关联的其他持久化对象。如果希望删除customer时,自动删除和customer关联的order对象,可把cascade属性设为delete

²  多对多
多对多的实体关系模型也是很常见的,比如学生和课程的关系。一个学生可以选修多门课程,一个课程可以被多名学生选修。在关系型数据库中对于多对多关联关系的处理一般采用中间表的形式,将多对多的关系转化成两个一对多的关系
  * 双向 n-n 关联需要两端都使用集合属性

  * 双向n-n关联必须使用中间表

  * 集合属性应增加 key 子元素用以映射外键列, 集合元素里还应增加 many-to-many子元素关联实体类

  * 在双向 n-n 关联的两边都需指定连接表的表名及外键列的列名. 两个集合元素 set 的 table 元素的值必须指定,而且必须相同
注意:对于双向 n-n 关联, 须把其中一端的 inverse 设置为 true, 否则可能会造成主键冲突

² 一对一
一对一关联指两个表之间的记录是一一对应的关系。分为两种:外键关联和主键关联
  * 对于基于外键的1-1关联,其外键可以存放在任意一边,在需要存放外键一端,增加 many-to-one 元素。为 many-to-one元素增加 unique=“true” 属性来表示为1-1关联,并用name属性来指定关联属性的属性名
  * 另一端需要使用one-to-one元素,该元素使用 property-ref(可以不加) 属性指定使用被关联实体主键以外的字段作为关联字段
一对一的另一种解决方式就是主键关联,在这种关联关系中,要求两个对象的主键必须保持一致,通过两个表的主键建立关联关系,无须外键参与
  * 基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据”对方”的主键来生成自己的主键,自己并不能独立生成主键. <param> 子元素指定使用当前持久化类的哪个属性作为 “对方”
  * 采用foreign主键生成器策略的一端增加 one-to-one 元素映射关联属性,其 one-to-one 属性还应增加 constrained=“true” 属性;另一端(company)增加one-to-one元素映射关联属性
  * constrained(约束):指定为当前持久化类对应的数据库表的主键添加一个外键约束,引用被关联的对象(“对方”)所对应的数据库表主键

Session缓存

Session 接口是 Hibernate向应用程序提供的操纵对数据库的最主要的接口, 它提供了基本的保存, 更新, 删除和加载Java对象的方法

²  在 Session 接口的实现中包含一系列的 Java 集合,这些 Java 集合构成了 Session 缓存.只要 Session 实例没有结束生命周期, 存放在它缓存中的对象也不会结束生命周期

²  当session的save()方法持久化一个对象时,该对象被载入缓然存,以后即使程序中不再引用该对象,只要缓存不清空,该对象仍处于生命周期中。当试图load()对象时,会判断缓存中是否存在该对象,有则返回。没有在查询数据库

²  Session具有一个缓存, 位于缓存中的对象称为持久化对象, 它和数据库中的相关记录对应.Session 能够在某些时间点, 按照缓存中对象的变化来执行相关的 SQL 语句, 来同步更新数据库,这一过程被称为清理缓存(flush)

默认情况下 Session在以下时间点清理缓存:

²  当应用程序调用 Transaction 的 commit()方法的时, 该方法先清理缓存(session.flush()),然后在向数据库提交事务(tx.commit())

²  当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生了变化,会先清理缓存,以保证查询结果能够反映持久化对象的最新状态

²  显式调用 Session 的 flush() 方法

清理session的缓存的方法:

² flush: 进行清理缓存(此时缓存中的数据并不丢失)的操作,让缓存和数据库同步 执行一些列sql语句,但不提交事务,;

² commit:先调用flush() 方法,然后提交事务. 则意味着提交事务意味着对数据库操作永久保存下来。

² reresh:刷新,让session和数据库同步,执行查询,把数据库的最新信息显示出来,更新本地缓存的对象状态.

² clear:清空缓存,等价于list.removeAll()

Hibernate对象的四种状态

Session 的特定方法能使对象从一个状态转换到另一个状态

持久化状态(也叫”托管”)(Persist)

²  OID不为 null

²  位于 Session 缓存中

²  持久化对象和数据库中的相关记录对应

²  Session在清理缓存时, 会根据持久化对象的属性变化, 来同步更新数据库

²  在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象

临时状态(transient)

²  在使用代理主键的情况下, OID 通常为 null

²  不处于 Session 的缓存中

²  在数据库中没有对应的记录

游离状态(也叫”脱管”)(Detached)

²  OID不为 null

²  不再处于 Session 的缓存中

²  一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录

删除状态(Removed)

²  OID不为 null

²  从一个 Session实例的缓存中删除

²  Session已经计划将其从数据库删除, Session 在清理缓存时, 会执行 SQL delete 语句,删除数据库中的对应记录

²  一般情况下, 应用程序不该再使用被删除的对象

映射组成关系

Hibernate 把持久化类的属性分为两种:

²  值(value)类型: 没有OID, 不能被单独持久化, 生命周期依赖于所属的持久化类的对象的生命周期,组件类型就是一种值类型(Address)

²  实体(entity)类型: 有OID, 可以被单独持久化, 有独立的生命周期

Hibernate的映射类型:

²  内置映射类型:

² java时间和日期类性

Hibernate的检索策略

立即检索: 立即加载检索方法指定的对象

延迟检索: 延迟加载检索方法指定的对象

²  类级别检索策略:

  * 类级别可选的检索策略包括立即检索和延迟检索,默认为延迟检索

  * 类级别的检索策略可以通过<class> 元素的 lazy 属性进行设置

  * 如果程序加载一个对象的目的是为了访问它的属性,可以采取立即检索。如果程序加载一个持久化对象的目的是仅仅为了获得它的引用,可以采用延迟检索

  * 无论<class> 元素的 lazy 属性是 true 还是 false, Session 的get() 方法及 Query 的 list() 方法在类级别总是使用立即检索策略

²  关联级别的检索策略:

  * 在映射文件中,用 <set> 元素来配置一对多关联及多对多关联关系. <set> 元素有 lazy 和fetch 属性

²  hibernate检索方式:

  * 导航对象图检索方式:  根据已经加载的对象导航到其他对象

  * OID 检索方式:  按照对象的OID 来检索对象

  * HQL 检索方式:使用面向对象的 HQL 查询语言

  * QBC 检索方式:使用 QBC(Query By Criteria) API 来检索对象. 这种 API 封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口.

  * 本地SQL 检索方式: 使用本地数据库的 SQL 查询语句

Hibernate的二级缓存

²  多个事务并发运行时的并发问题

对于同时运行的多个事务,当这些事务都在访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题,这些并发问题可归纳为以下几类:

* 第一类丢失更新:撤消一个事务时,把其他事务已经提交的数据覆盖

* 脏读:一个事务读到了另一事务未提交的的更新数据

* 虚读:一个事务读到了另一事务已经提交的新插入的数据

* 不可重复读:一个事务读到了另一事务已经提交的更新数据

²  ANSI事务隔离级别:

* READ_UNCOMMITED:允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读

*READ_COMMITTED:允许在并发事务已经提交后读取。可防止脏读,但幻读和 不可重复读仍可发生

*REPEATABLE_READ:对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏、不可重复读,但幻读仍可能发生

* SERIALIZABLE:完全服从ACID的隔离级别,确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的

注意:

* Hibernate不可能改变在受管环境下由应用服务器提供的数据库连接的隔离级别,只能通过改变应用服务器配置的方式来改变

            * 设置隔离级别是全局选项,会影响所有的连接和事务.有时需要为某个特定事务指        定更多的限制

                        * Hibernate依赖于乐观的并发控制,使用版本检查和悲观锁实现附加的锁支持

 

²  理解缓存(Cache)定义

计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存

²  Hibernate中提供了两个级别的缓存

* 第一级别的缓存是 Session 级别的缓存,它是属于事务范围的缓存。这一级别的缓存由hibernate 管理的,一般情况下无需进行干预

* 第二级别的缓存是 SessionFactory 级别的缓存,它是属于进程范围的缓存

²  SessionFactory的缓存可以分为两类

* 内置缓存:Hibernate 自带的,不可卸载,该内置缓存是只读的

* 外置缓存(二级缓存):一个可配置的缓存插件

²  理解二级缓存的并发访问策略

* 非严格读写(Nonstrict-read-write)

* 读写型(Read-write)

* 事务型(Transactional)

* 只读型(Read-Only)

²  适合放入二级缓存中的数据

* 很少被修改

* 不是很重要的数据, 允许出现偶尔的并发问题

二级缓存的配置

Hibernate的二级缓存是进程或集群范围内的缓存,缓存中存放的是对象的散装数据,二级缓存是可配置的的插件,Hibernate允许选用以下类型的缓存插件:

²  EHCache:可作为进程范围内的缓存,存放数据的物理介质可以使内存或硬盘,对Hibernate 的查询缓存提供了支持

²  OpenSymphonyOSCache:可作为进程范围内的缓存,存放数据的物理介质可以使内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate 的查询缓存提供了支持

²  SwarmCache:可作为集群范围内的缓存,但不支持 Hibernate 的查询缓存

²  JBossCache:可作为集群范围内的缓存,支持 Hibernate 的查询缓存

4 种缓存插件支持的并发访问策略(x代表支持, 空白代表不支持):

 

 

 

 

 

 

 

posted @ 2015-01-16 23:14  lihui1625  阅读(97)  评论(0编辑  收藏  举报