Hibernate基础学习总结

来源:互联网 发布:易企秀邀请函报名数据 编辑:程序博客网 时间:2024/06/06 03:13

1.HQL(Hibernate Query Language),面向的是对象而不是数据库中的表,这是与SQL(Structured  Query  Language)之间的差别。

2.Session的get与load方法都可以获取相应的持久化对象,如果该对象存在,那么这两个方法的行为是一样的;如果该对象不存在,那么get方法会返回null而load方法则抛出异常。

3.OGNL(Object Graph Navigation Language),对象图导航语言。

4.OgnlContext(上下文对象),存在唯一的叫做根的对象(root),可以通过程序设计上下文当中的哪个对象作为根对象。

5.在OGNL中,如果表达式没有使用#号,那么OGNL会从根对象中寻找该属性对象的get方法,如果寻找的不是根对象中的属性,那么则需要以#号开头,告诉OGNL,去寻找你所指定的特定对象中的属性。

6.当使用OGNL调用静态方法的时候,需要按照如下语法编写表达式:@package.classname@methodname(parameter)。

7.对于OGNL来说,java.lang.Math是其的默认类,如果调用java.lang.Math的静态方法时,无需指定类的名字,比如:@@min(4,10).

8.对于OGNL来说,数组与集合是一样的,都是通过下标索引来去访问。构造集合的时候使用{...}形式。

9.使用OGNL来处理映射(Map)的语法格式如下所示:

  #{'key1':'value1','key2':'value2','key3':'value3','key4':'value4'}

10.过滤(filtering),collection.{? expression}

11.OGNL针对集合提供了一些伪属性(如size,isEmpty),让我们可以通过属性的方式来调用方法(本质原因在于集合当中的很多方法并不符合javabean的命名规则),但是我们依然还可以通过调用方法来实现与伪属性相同的目的。

12.过滤(filtering),获取到集合中的第一个元素:collection.{^ expression};获取到集合中的最后一个元素collection.{$ expression}。

13.在使用过滤操作时,我们通常都会使用#this,该表达式用于代表当前正在迭代的集合中的对象。

14.投影(projection):collection.{expression}。

15.过滤与投影之间的差别:类比于数据库中的表,过滤是取行操作,而投影是取列的操作。

16.在struts2中,根对象就是ValueStack。在struts2的任何流程当中,ValueStack中的最顶层对象一定是Action对象。

17.parameters,#parameters.username      request, #request.username    session,#session.username    application,#application.username    attr,#attr.username以上几个对象叫命名对象。

18.关于Struts2标签库属性值的%与#号的关系:

    1.如果标签的属性值是OGNL表达式,那么无需加上%{}

    2.如果标签的属性值是字符串类型,那么在字符串当中凡是出现的%{}都会被解析成OGNL表达式,解析完毕后再与其他的字符串进行拼接构造出最后的字符串值。

    3.我们在所有的属性值上加%{},这样如果该属性值是OGNL表达式,那么标签处理类就会将%{}忽略掉。


19.对于Query接口的list()方法与iterate()方法来说,都可以实现获取查询的对象,但是list()方法返回的每个对象都是完整的(对象中的每个属性都被表中的字段填充上了),而iterate()方法所返回的对象中仅包含了主键值(标识符),只有当你对iterate()方法返回的对象进行操作时,Hibernate才会向数据库再次发送SQL语句来获得该对象的属性值。

20.Hibernate中的延迟加载(lazy loading),当我们在程序中获取到一的一方,但是不需要多的一方,那么使用延迟加载就是非常适合的。


Session的缓存

  当Session的Save()方法持久化一个Customer对象时,Customer对象被加入到Session的缓存中,以后即使应用程序不再引用Customer对象,只要Session的缓存还没有被清空,Customer对象仍然处于生命周期中。

  当Session的load()方法试图从数据库中加载一个Customer对象时,Session先判断缓存中是否已经存在这个Customer对象,如果存在,就不需要再到数据库中检索。

Session的缓存的作用

(1)减少访问数据库的频率。应用程序中从内存读取持久化对象的速度显然比到数据库中查询数据的速度快多了,因此Session的缓存可以提高数据访问的性能。

(2)保证缓存中的对象与数据库中的相关记录保持同步。当缓存中持久化对象的状态发生变化时,Session并不会立即执行相关的SQL语句,这使得Session能够把几条相关的SQL语句合并为一条SQL语句,以便减少访问数据库的次数,从而提高应用程序的性能。


清理缓存是指按照缓存中对象的状态的变化来同步更新数据库。

当Session清理缓存时,只需要执行一条Update语句。

Session会在下面的时间点清理缓存:

当应用程序调用commit()方法的时候,commit()方法先清理缓存,然后再向数据库提交事务。

当应用程序显示调用Session的flush()方法的时候。


session级别的缓存又叫做一级缓存(无法修改);SessionFactory级别的缓存叫做二级缓存。

Hibernate提供了两级缓存,第一级缓存是Session的缓存。由于Session对象的生命周期通常对应一个数据库事务或者一个应用事务,因此它的缓存是事务范围的缓存。第一级缓存是必须的,不允许而且事实上也无法被卸除。在第一级缓存中,持久化类的每个实例都具有唯一的OID。

第二级缓存是一个可插拔的缓存插件,它由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个进程对应,因此第二级缓存是进程范围的缓存。这个缓存中存放的是对象的散装数据。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。



在Hibernate应用中Java对象的状态

1.临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。

2.持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。

3.游离状态(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象称为游离对象。

三种状态之间的关系:

Session的update()方法

它完成以下 操作:

(1)把Customer对象重新加入到Session缓存中,使它变为持久化对象。

(2)计划执行一个update语句。值得注意的是,Session只有在清理缓存的时候才会执行update语句,并且在执行时才会把Customer对象当做当前的属性值组装到update语句中。因此,即使在程序中多次修改了Customer对象的属性,在清理缓存时只会执行一次update语句。


延迟检索策略

优点

——由应用程序决定需要加载哪些对象,可以避免执行多余的select语句,以及避免加载应用程序不需要访问的对象。因此能提高检索性能,并且能节省内存空间。

缺点

——应用程序如果希望访问游离状态的代理类实例,必须保证它在持久化状态时已经被初始化。

使用范围

——一对多或者多对多关联

——应用程序不需要立即访问或者根本不会访问的对象。


默认情况下,多对一关联使用左外连接检索策略。

     <many-to-one>元素的outer-join属性设为true

左外连接检索策略

 优点

——1.对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便的从一个对象导航到与它关联的对象。

——2,使用外连接,select语句数目少。

缺点

——1.可能会加载应用程序不需要访问的对象,白白浪费许多内存空间。

——2.复杂的数据库表连接也会应用检索性能。

使用范围

——1.多对一或者一对一关联。2.应用程序需要立即访问的对象。3.数据库系统具有良好的表连接性能。

在映射文件中设定的检索策略是固定的,要么为延迟检索,要么为立即检索,要么为外连接检索。


一对一映射:

1)主键关联。一对一默认使用的是立即加载,如果需要使用延迟加载,那么需要在one-to-one元素中将constrained属性设为true,并且将待加载的一方的class元素中的lazy属性设置为true(或者不去设置,因为该属性默认值就是true)。一对一加载时默认使用左外连接,可以通过修改fetch属性为select修改成每次发送一条select语句的形式。

2)外键关联。本质上是一对多的蜕化形式。在many-to-one元素中增加unique=“true”属性就变成一对一了。



Map、Set、List映射

1.map与set标签中的element子标签映射的原子类型(String,date,int,long...),即能够直接映射到数据库表字段上的类型,而one-to-many映射的则是实体类型,指的是无法映射到表的某个字段,而是要映射到整张表的类型。

2.Bag(结合了List与Set),可以重复且没有顺序的一种集合,是Hibernate提供的。

3.查询排序(内存排序及数据库排序)。

4.数据库排序使用order-by属性。

5.内存排序使用sort属性,它有两个个属性值(unsorted,natural)可以直接使用,其中的natural指的是按照自然的升序排序,unsorted指的是不排序。

   此外我们还可以自定义排序规则,方式是定义一个类,让其实现Comparator接口,并且实现该接口中的compare方法,在该方法中实现排序规则即可。然后将自定义排序规则的类名作为sort的属性值即可


联合主键的映射规则

1)类中的每个主键属性都对应到数据表中的每个主键列.Hibernate要求具有联合主键的实体类实现Serializable接口,并且重写hashCode与equals方法,重写这两个方法的原因在于Hibernate要根据数据库的联合主键来判断某两行记录是否是一样的,如果一样那么就认为是同一对象,如果不一样,那么就认为是不同的对象。这反映到程序领域中就是根据hashCode与equals方法来判断某两个对象是否能够放到诸如Set这样的集合当中。联合主键的实体类实现Serializable接口的原因在于使用get或load方法的时候需要先构建出来该实体的对象,并且将查询依据(联合主键)设置进去,然后作为get或load方法的第二个参数传进去即可。

2)将主键所对应属性提取出一个类(称之为主键类),并且主键类需要实现Serializable接口,重写equals方法与hashCode方法,原因与上面一样。


继承映射

1)每个子类一张表

2)一张表存储继承体系中所有类的信息(数据库表实际上是继承体系中所有类的属性的并集所构成的字段)

      需要在hbm文件添加如下配置:<discriminator column="personType" type="string"/>

3)公共信息放在父类表中,独有信息放在子类表中,每一个子类对应一张表。



Hibernate提供的检索对象的方式

一、导航对象图检索方式

         根据已经加载的对象,导航到其他对象。例如,对于已经加载的Customer对象,调用它的getOrders().iterator()方法就可以导航到所有关联的Order对象,加入在关联级别使用了延迟加载检索策略,那么首次执行此方式时,Hibernate会从数据库中加载关联的Order对象,否则就从缓存中取得Order对象。

二、OID检索方式

        按照对象的OID来检索对象。Session的get()和load()方法提供了这种功能。如果在应用程序中事先知道了OID,就可以使用这种检索对象的方式。

三、HQL检索方式

        Hibernate提供了Query查询接口,它是Hibernate提供的专门的HQL查询接口,能够执行各种复杂的HQL查询语句。

四、QBC检索方式

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


HQL检索方式

HQL(Hibernate Query Language)是面向对象的查询语言,它和SQL查询语言有些相似。在Hibernate提供的各种检索方式中,HQL是使用最广的一种检索方式。它具有以下功能:

  ——在查询语句中设定各种查询条件

  ——支持投影查询,即仅检索出对象的部分属性

  ——支持分页查询

  ——支持连接查询

  ——支持分组查询,允许使用having和group by关键字

 —— 提供内置聚集函数,如sum(),min(),max()

  ——支持子查询,即嵌入式查询

  ——支持动态绑定参数


HQL检索步骤



QBC检索方式

  采用HQL检索方式时,在应用程序中需要定义基于字符串形式的HQL查询语句。

  QBC API提供了检索对象的另一种方式,它主要由Criteria接口,Criteria接口和Expression类组成,它支持在运行时动态生成查询语句。



QBC检索步骤


分页查询


两种方式的代码实现


数据库事务

事务:体现出整体的概念:要么事务中的操作全部成功,要么全部失败。


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



举例说明这几种情况




数据库的事务隔离级别



隔离级别与并发性能的关系


多数应用程序会将隔离级别设置为Read  Committed


在mysql.exe程序中设置隔离级别




悲观锁和乐观锁



乐观锁




0 0
原创粉丝点击