hibernate的检索策略

来源:互联网 发布:网络图标图片免费下载 编辑:程序博客网 时间:2024/04/19 07:53

Hibernate检索策略:  

立即检索、延迟检索、迫切左外连接检索  

Hibernate检索策略应用对象级别:类级别、关联级别  

以下表格为类级别和关联级别可选的检索策略及默认的检索策略  
检索策略的作用域  
可选的检索策略  
默认的检索策略  
运行时行为受影响的Session的检索方法  
类级别  
立即加载  
延迟加载  
立即检索  
Load()方法  
关联级别  
立即加载  
延迟加载  
迫切左外连接检索  
多对一或者一对一为迫切左外连接检索  
一对多或者多对多为立即检索  
Get()Load()Find()方法  

对象-关系映射文件中设定检索策略的属性  

属性  
可选值  
默认值  
描述  
lazy  
truefalse  
false  
如果为true表示使用延迟加载,如果为false表示使用立即加载  
outer-join  
autotruefalse  
<many-to-one>元素和  
<one-to-one>元素中为auto,在<one-to-many>元素和<many-to-many>元素中为false  

如果为true表示使用迫切左外连接检索。在<many-to-one><one-to-one>、和<set>元素中包含此属性  
如果为false表示使用立即加载  
batch-size  
正整数  
1  
设定批量检索的数量。如果设定此项合理的取值在310之间  

hibernate还允许在应用程序中以编程方式显示设定检索策略。程序代码中的检索策略会覆盖映射文件中配置的检索策略,如果程序代码没有显示设定检索策略,则采用映射文件中配置的检索策略。

类级别的检索策略:  

类级别可选的检索策略包括立即检索和延迟检索,默认立即检索。如果<class>元素的lazy属性为true,则表示采用延迟检索;如果lazy属性为false,则表示立即检索。lazy属性默认值为false。
在类级别中应该优先考虑使用立即检索策略,因为在大多数情况下,当应用程序通过session的load()方法加载了一个持久化类的对象后,总是立即访问它。
延迟检索:
<class name="mypack.Customer" table="CUSTOMERS" lazy="true">
当执行session的load()方法时,hibernate不会立即执行查询CUSTOMERS表的select语句,仅仅返回Customer类的代理类实例,这个代理类具有以下的特征:
由hibernate在运行时动态产生,它扩展了Customer类,因此它集成了Customer类的所有属性和方法,但它的实现对于应用程序是透明的。
当hibernate创建Customer代理类实例时,仅仅初始化它的OID属性,其他属性都为null,因此这个代理类实例占用的内存很少
当应用程序第一次访问Customer代理类实例时(例如get、set方法,除了getId,因为id已经在代理类中了),hibernate会初始化代理类实例,初始化过程中执行select语句,真正从数据库中加载Customer对象的所有数据。
hibernate是采用CGLIB工具来生成持久化类的代理类。
lazy属性为true时,会影响Session的load()方法的各种运行时行为:
①如果加载Customer对象在数据库中不存在,Session的load()方法不会抛出异常,只有当运行get方法时才会抛出异常
②如果在整个session范围内,应用程序都没有访问过Customer对象,那么Customer代理类的实例一直不会被初始化,Hibernate不会执行任何select语句。
③net.sf.hibernate.Hibernate类的initialize()静态方法用于在session范围内显示初始化代理类实例,isInitialized()方法用于判断代理类实例是否已经被初始化。
值得注意的是,不管Customer.hbm.xml文件的<class>元素的lazy属性是true还是false,session的get()和find()方法在Customer类级别总是使用立即检索策略。
 

关联级别的检索策略  

一对多和多对多关联的检索策略,<set>属性如下

lazy属性  
outer-join属性  
检索策略  
false  
false  
采用立即检索,这是默认的检索策略,当使用Hibernate的第二级缓存时,可以考虑采用立即检索。  
true  
false  
采用延迟检索  
false  
true  
采用迫切左外连接检索,对于Hibernate2.0以下,再映射文件中如果有多个<set>元素,只允许有一个<set>元素的outer-join属性为true  
true  
true  
没有任何意义  


注意:对于Session.find()方法会忽略迫切左外连接检索,采用立即检索策略(如果hql语句中自己撰写了外连接,则会外连接检索)  
多对一和一对一关联的检索策略  
以订单和顾客为例,Order对象与Custom对象之间的多对一关系  
Order.hbml.xml  
<many-to-one>元素的  
outer-join属性  
Custom.hbm.xml<class>元素的lazy属性  
检索order对象时对关联的custom对象使用的检索策略  
auto  
true  
延迟检索  
auto  
false  
迫切左外连接检索  
true  
true  
迫切左外连接检索  
true  
false  
迫切左外连接检索  
false  
true  
延迟检索  
false  
false  
立即检索  

批量检索:  

设置<class>元素的batch-size,这样再进行查询时能够在Sql中采用or连接词减少查询次数。

三种检索模式比较:


检索策略
优点缺点适用性

立即检索

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

1.select语句太多;
2.可能会加载应用程序不需要访问的对象白白浪费许多内存空间

1.类级别

2.应用程序需要立即访问的对象

3.使用了二级缓存

延迟检索

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

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



1.一对多或者多对多关联

2.应用程序不需要立即访问或者根本不访问的对象


迫切左外连接

1.对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便地冲一个对象导航到与它关联的对象。
2.使用了外连接,select语句数目少;

1.可能会加载应用程序不需要访问的对象,白白浪费许多内存空间;
2.复杂的数据库表连接也会影响检索性能;

1.多对一或者一对一关联

2.应用程序需要立即访问的对象

3.数据库系统具有良好的表连接性能



提高查询性能

1、尽量使用迫切连接,以减少查询数据库的次数。

2、对使用延迟加载或者立即检索策略设置批量 查询数目,以检索查询数据库的次数。

3、使用查询缓存

4、有的时候数据量较大,只负责显示的数据可使用Sql查询,以减少缓存空间。

5、尽量减少返回记录集字段的数目,只返回所需要的字段。

6、使用集合过滤,也就是说通过第一次查询的结果来再次进行查询。

HQL方式与QBC方式的不同

1、HQL方式功能强大,可实现分组,外连、内连,而QBC则没有这些功能。

2、HQL语句写法接近Sql语句方式,容易上手。

3、HQL语句无法在编译期检查错误。而QBC能够做到。

4、QBC是面向对象的,而HQL语句还不是面向对象编程。

5、QBC能够动态创建查询,而HQL不能

6、QBC提供了接口,扩展性好,HQL方式不具有扩展性。


0 0
原创粉丝点击