- 浏览: 107103 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
HEXLee:
感谢博主分享
Struts2的工作原理 -
funnywiser:
国内公司做的VisualRules更好。
不要一味迷信国外的产 ...
Drools 为你的业务逻辑提供框架[修订] -
tufei2006:
现在业务规则做的好的不止这些的,最好的应该是 ILOG JRU ...
Drools 为你的业务逻辑提供框架[修订] -
r_x_y:
呵,参考一下
Struts2的工作原理 -
shania0127:
收藏啦!
web开发的一些问题(java方向)
<!----><!----><!----> <!---->
Hibernate 提供以下几种检索对象的方式。
l 导航对象图检索方式。(根据已经加载的对象,导航到其他对象。)
l OID 检索方式。(按照对象的 OID 来检索对象。)
l HQL 检索方式。(使用面向对象的 HQL 查询语言。)
l QBC 检索方式。(使用 QBC(Qurey By Criteria) API 来检索对象。)
l 本地 SQL 检索方式。(使用本地数据库的 SQL 查询语句。)
一、 Hibernate 的检索方式简介
1 、 HQL 检索方式
HQL ( Hibernate Query Language )是面向对象的查询语言,它和 SQL 查询语言有些相识。在 Hibernate 提供的各种检索方式中, HQL 是使用最广的一种检索方式。它具有以下功能:
l 在查询语句中设定各种查询条件。
l 支持投影查询,即仅检索出对象的部分属性。
l 支持分页查询。
l 支持分组查询,允许使用 having 和 group by 关键字。
l 提供内置聚集函数,如 sum() 、 min() 和 max() 。
l 能够调用用户定义的 SQL 函数。
l 支持子查询,即嵌入式查询。
l 支持动态绑定参数。
Session 类的 find 方法及 Qurey 接口都支持 HQL 检索方式。区别在于,前者只是执行一些简单 HQL 查询语句的便捷方法,它不具有动态绑定参数的功能,而且在将来新的 Hibernate 版本中,有可能淘汰 find 方法;而 Qurey 接口才是真正的 HQL 查询接口,它提供了以上列出的各种查询功能。
注: Qurey 接口支持方法链编程风格,它的 set 方法都返回自身实例,而不是返回 void 类型。方法链编程风格能使程序代码更加简洁。
示例代码:
Query query = session.createQuery("from Customer as c where " +"c.name=:customerName and c.age=:customerAge");
// 动态绑定参数
query.setString("customerName", "Test"); query.setInteger("customerAge", 21);
// 执行检索 List result = query.list();
// 方法链编程风格 List result1 = session.createQuery( "from Customer as c where c.name=:customerName" + " and c.age=:customerAge").setString( "customerName", "Test").setInteger("customerAge", 21) .list();
2 、 QBC ( Qurey By Criteria )检索方式
采用 HQL 检索方式时,在应用程序中需要定义基于字符串形式的 HQL 查询语句。 QBC API 提供了检索对象的另一种方式,它主要由 Criteria 接口、 Criterion 接口和 Expression 类组成,它支持在运行时动态生成查询语句。
示例代码:
Criteria criteria = session.createCriteria(Customer.class);
Criterion criterion1 = Expression.like("namr", "T%");
Criterion criterion2 = Expression.eq("age", new Integer(21));
criteria = criteria.add(criterion1);
criteria = criteria.add(criterion2);
// 执行检索 List result = criteria.list();
// 方法链编程风格 List result1 = session.createCriteria(Customer.class).add(Expression.like("namr", "T%")).add(Expression.eq("age", new Integer(21))).list();
Hibernate 还提供了 QBE(Qurey By Example) 检索方式,它是 QBC 的子功能。 QBE 允许先创建一个随想模板,然后检索出和这个样板相同的对象。
示例代码:
Customer exampleCustomer=new Customer();
exampleCustomer.setAge(21);
List result1 = session.createCriteria(Customer.class).add( Example.create(exampleCustomer)).list();
QBE 的功能不是特别强大,仅在某些场合下有用。一个典型的使用场合就是在查询窗口中让用户输入一系列的查询条件,然后返回匹配的对象。 QBE 只支持“”和“”比较运算符,无法不大区间值,及其或的匹配。在这种情况下,还是采用 HQL 检索方式或 QBC 检索方式。
3 、 SQL 检索方式
采用 HQL 或 QBC 检索方式时, Hibernate 生成标准的 SQL 查询语句,使用于所有的数据库平台,因此这两种检索方式都是跨平台的
有的应用程序可能需要根据底层数据库的 SQL 方言,来生成一些特殊的查询语句。在这种情况下,可以利用 Hibernate 提供的 SQL 检索方式。
示例代码:
Query query = session.createSQLQuery("select {c.*} from CUSTOMER as c where c.NAME like :
customerName and c.AGE=:customerAge");
// 动态绑定参数 query.setString("customerName", "Test"); query.setInteger("customerAge", 21);
// 执行检索 List result = query.list();
4 、使用别名
通过 HQL 检索一个类时,如果查询语句的其他地方需要引用它,应该为这个类指定一个别名, as 关键字用于设定别名,也可以将 as 关键字省略。
QBC 检索不需要由应用程序显式指定类的别名, Hibernate 会自动把查询语句中的跟结点实体赋予别名“ this ”。
5 、多态查询
HQL 和 QBC 都支持多态查询,多态查询是指查询出当前类及所有子类的实例。多态查询对接口也使用。 Hibernate 不仅对 from 子句显式指定的类进行多态查询,而且对其他关联的类也会进行多态查询。
6 、对查询结果排序
HQL 和 QBC 都支持对查询结果进行排序。
query = session.createQuery("from Customer as c order by c.name");
// 排序 criteria.addOrder(Order.asc("name")); criteria.addOrder(Order.desc("age"));
7 、分页查询
Query 和 Criteria 接口都提供了用于分页显式查询结果的方法。
l setFirstResult(int firstResult) :设置从那个对象开始检索,参数表示这个对象在查询结果中的索引位置,索引位置的起始值为 0 。默认从 0 检索。
l setMaxResult(int maxResults) :设置一次最多检索出的对象数目。默认检索所有。
示例代码:
criteria = criteria.add(criterion1);
criteria = criteria.add(criterion2);
criteria.setFirstResult(0);
criteria.setMaxResults(10); // 执行检索
List result = criteria.list();
query.setString("customerName", "Test");
query.setInteger("customerAge", 21);
query.setFirstResult(0);
query.setMaxResults(10); // 执行检索
List result = query.list();
8 、检索单个对象
Query 和 Criteria 接口都提供了以下用于查询语句并返回查询结果的方法。
l list() 方法:返回一个 List 类型的查询结果。
l uniqueResult() 方法:返回单个对象。
注: Query 接口还提供了一个 iterate() 方法,它和 list() 方法一样,能返回所有满足条件的持久化对象,但是两者使用不同的 SQL 查询语句。
示例代码:
// 单个检索 Customer customer = (Customer) session.createQuery("from Customer as c order by c.name").setMaxResults(1) .uniqueResult();
// 单个检索 Customer customer = (Customer) session.createCriteria(
Customer.class).setMaxResults(1).uniqueResult();
如果明明知道一个对象,可以不调用 setMaxResults(1) 方法。
9 、在 HQL 查询语句中绑定参数
A 、按参数名字绑定。咋 HQL 中定义命名参数以“ : ”开头。
B 、按照参数位置绑定。在 HQL 查询语句中用“ ? ”来定义参数的位置。
示例代码:
Query query = session.createQuery("from Customer as c where " + "c.name=? and c.age=?"); // 动态绑定参数
query.setString(0, "Test");
query.setInteger(1, 21);
除了以上用于绑定映射类型的参数的方法, Hibernate 还提供了以下三个特殊的参数绑定方法。
( 1 ) setEntity() 方法:把参数与一个持久化类的实例绑定。(用 id 关联)
( 2 ) setParameter() 方法:绑定任意类型的参数。
( 3 ) setProperties() 方法:用于把命名参数与一个对象的属性值绑定。
10 、在映射文件中定义命名查询语句(略)
Hibernate 的检索方式(二)
二.设定查询条件
在 where 子句中给出的是对象的属性名,而不是字段名。
HQL 和 QBC 支持的各种运算
运算类型 HQL 运算符 QBC 运算符 含义
比较运算 = Expression.eq() 等于
<> Expression.not(Expression.eq()) 不等于
> Expression.gt() 大于
>= Expression.ge() 大于等于
< Expression.lt() 小于
<= Expression.le() 小于等于
is null Expression.isNull() 等于空值
is not null Expression.isNotNull() 非空值
范围运算 in ( 列表 ) Expression.in() 等于列表中的某一个值
not in ( 列表 ) Expression.not(Expression.in()) 不等于列表中的任意一个值
between 值 1 and 值 2 Expression.between() 大于等于值 1 并且小于等于值 2
not between 值 1 and 值 2 Expression.not(Expression.between()) 小于值 1 或者大于值 2
字符串模式匹配 like Expression.like() 字符串模式匹配
逻辑运算 and Expression.add() 或者 Expression.conjunction() 逻辑与
or Expression.or() 或者 Expression.disjunction() 逻辑或
not Expression.not() 逻辑非
1 、比较运算
( 1 )不区分大小写: HQL 使用 lower() 或者 upper() 来实现(如:”… lower(c.name)= ’ tom ’”);
QBC 使用 .ignoreCase() 来实现(如: Expression.eq( “” , ”” ) .ignoreCase() )。
注:在 HQL 中,可以调用 SQL 函数。 lower() 转小写, upper() 转大写。
QBC 不支持直接调用 SQL 函数。
( 2 ) HQL 查询支持数学运算表达式,而 QBC 不支持。
2 、范围运算
HQL 中的 in 示例: c.name in ( ‘ aa ’ , ’ bb ’ ) ;
QBC 中的 in 示例: String[] names={ ‘ aa ’ , ’ bb ’ }; Expression.in( ‘ name ’ ,names); 。
Hibernate 的检索方式(二)续
3 、字符串模式匹配
HQL 和 QBC 通用:字符串模式中的通配符
通配符名称 通配符 作用
百分号 % 匹配任意类型且任意长度(长度可以为 0 )的字符串,如果是中文,需要两个百分号,即“ %% ”
下划线 _ 匹配单个任意字符,常用来限制字符串表达式的长度
QBC : MatchMode 类包含的各个静态常量实例
匹配模式 举例
MatchMode.START Expression.like(“name”,”y”, MatchMode.START)
姓名以 y 开头
MatchMode.END Expression.like(“name”,”y”, MatchMode. END)
姓名以 y 结尾
MatchMode.ANYWHERE Expression.like(“name”,”y”, MatchMode. ANYWHERE)
姓名中包含 y
MatchMode.EXACT Expression.like(“name”,”y”, MatchMode. EXACT)
精确匹配,姓名必须为 y
4 、逻辑运算
Hibernate 的检索方式(三)
三、连接查询
HQL 和 QBC 支持的各种连接类型
在程序中指定的链接查询类型 HQL 语法 QBC 语法 使用范围
内连接 inner join 或者 join Criteria.createAlias() 适用于有关联的持久化类,并且在映射文件中对这种关联关系作了映射。
迫切内连接 inner join fetch 或者 join fetch 不支持
隐式内连接 不支持
左外连接 left outer join 或者 left join 不支持
迫切左外连接 left outer join fetch 或者 left join fetch FetchMode.EAGER
右外连接 right outer join 或者 right join 不支持
交叉连接 ClassA,ClassB 不支持 适用于不存在关联关系的持久化类
1 、默认情况下关联级别的运行时检索策略
采用配置文件中设置的检索策略,但有一个例外,那就是 HQL 会忽略映射文件设置的迫切左外连接策略,改用立即检索。
2 、迫切左外连接
显式指定对象的关联关系为迫切左外连接检索策略,可以覆盖映射文件中指定的检索策略。
例 HQL
"from Customer c left join fetch c.orders o where c.name like 't%'"
+" o.name like 't%'"
例 QBC
List reslut=session.createCriteria(Customer.class) .setFetchMode("orders",FetchMode.EAGER) .add(Expression.like("name","t",MatchMode.START))
.list();
当使用迫切左外连接检索策略时,查询结果中可能会包含重复元素,可以通过一个 HashSet 来过滤重复元素: List result= … .list(); HashSet set=new HashSet(result);
Hibernate 允许在一条查询语句中迫切左外连接多个多对一或一对一关联的类。
List reslut=session.createCriteria(A.class) .setFetchMode("this.b",FetchMode.EAGER) .setFetchMode("this.c",FetchMode.EAGER) .add(Expression.isNotNull("this.b")) .add(Expression.isNotNull("this.c"))
.list();
当存在传递关联时,可以通过 HQL 来同时迫切左外连接关联类和依赖关联类,但 QBC 无法表达这种形式的迫切左外连接。
3 、左外连接
使用左外连接查询时,将根据映射文件的配置来决定关联的检索策略。
4 、内连接
QBC 也支持内连接查询
List reslut=session.createCriteria(Customer.class) .add(Expression.like("name","t",MatchMode.SRART)) .createCriteria("orders") .add(Expression.like("orderNumber","t",MatchMode.SRART))
.list();
默认情况下, QBC 只检索出 Customer 对象,以上代码等同于以下 HQL 查询语句:
"select c from Customer c join c.orders o where c.name like 't%'"
+ " and o.orderNumber like 't%'";
createAlias() 方法为关联属性(集合)赋予别名。如果希望 QBC 返回的集合也包含成对的 Customer 和 Order 对象,可以调用 returnMaps() 方法:
List reslut=session.createCriteria(Customer.class) .createAlias("orders","o") .add(Expression.like("this.name","t",MatchMode.SRART)) .add(Expression.like("o.orderNumber","t",MatchMode.SRART)) .returnMaps()
.list();
采用内连接查询时, HQL 与 QBC 有不同的默认行为,前者检索成对的对象,后者仅检索出要检索的单个对象(不包含关联的对象)。
5 、迫切内连接
显式指定对象的关联关系为迫切内连接检索策略,可以覆盖映射文件中指定的检索策略。
6 、隐式内连接
一对一
"from Cunstomer c where c.homeAddress.provice like '%hai%'"
List reslut=session.createCriteria(Customer.class) .add(Expression.like("homeAddress.provice","t",MatchMode.SRART))
.list();
多对一
"from Order o where o.customer.name like '%hai%'"
QBC 不支持隐式内连接,下边是不正确的,:
List reslut=session.createCriteria(Order.class) .add(Expression.like("customer.name","t",MatchMode.SRART))
.list();
对于 QBC ,必须显式指定内连接查询:
List reslut=session.createCriteria(Order.class) .createAlias("customer","c") .add(Expression.like("c.name","t",MatchMode.SRART))
.list();
一对多或多对多
隐式内连接不适用。
7 、右外连接
8 、使用 SQL 风格的交叉连接和隐式内连接
HQL 支持 SQL 风格的交叉连接查询。如: from Customer c, Order o
在 SQL 语言中,显式内连接查询的语句使用 inner join 关键字,并且用 on 字句设定连接条件,形式为:
"select * from CUSTOMER c inner join ORDER o on c.ID=o.CUSTOMER_ID"
隐式内连接查询语句不包含关键字阿,并且用 where 字句设定连接条件:
"select * from CUSTOMER c ,ORDER o where c.ID=o.CUSTOMER_ID"
9 、关联级别运行是的检索策略
( 1 )没有显式指定,使用配置文件的,但有一个例外,那就是 HQL 会忽略映射文件设置的迫切左外连接策略,改用立即检索。
( 2 )如果显式指定,就会覆盖映射文件配置的检索策略。在 HQL 查询语句中显式指定检索策略包括以下内容。
l left join fetch
l inner join fetch
QBC 通过 FetchMode 类来显式指定检索策略,有以下 3 个静态实例。
l FetchMode.DEFAULT :默认,采用配置;
l FetchMode.EAGER :覆盖,指定迫切左外连接检索策略;
l FetchMode.LAZY :覆盖映射配置文件的检索策略,在程序中指定延迟检索策略。
Hibernate 的检索方式(四)
四、 报表查询
1 、投影查询
select c from Customer c ……
select c.name,c.age from Customer c ……
( 1 )动态实例化查询结果
select new com.CustomerRow(c.id,c.name,c.age) from Customer c ……
注: CustomerRow 类不需要是持久化类,因此不必创建它的对象-关系映射文件,它紧紧用于把 select 语句查询出来的关系数据包装为 Java 对象。
( 2 )过滤查询结果中的重复元素
select distinct c.name Customer c ……
2 、使用聚集函数
在 HQL 查询语句中可以调用以下聚集函数
l count() :统计记录数
l min()
l max()
l sum()
l avg() :求平均值
3 、分组查询( group by … (having … ) )
select c.name,count(c) from Customer c group by c.name
list() 结果: n 个对象数组类型的元素,每个对象数组对应查询结果中的一条记录。如
Iterator it = session.createQurey( "select c.name,count(c) from Customer c group by c.name") .list().iterator(); while (it.hasNext()) { Object[] pair = (Object[]) it.next(); String name = (String) pair[0]; Integer count = (Integer) pair[1];
}
4 、优化报表查询的性能
报表查询的特点:通常会处理大量数据;一般只涉及对数据的读操作,而不会修改数据。
当 select 语句仅仅选择查询持久化类的部分属性时, Hibernate 返回的查询结果为关系数据(不会占用 Session 的缓存),而不是持久化对象(位于 Session 缓存中)。
如果采用 select 语句查询,能提高报表查询的性能,只要应用程序不在引用这些数据,它们占用的内存就会被释放。当采用 from 类型的 HQL 语句查询出持久化对象,会导致大量的持久化对象一直位于 Session 的缓存中,而且 Session 还比讯负责这些对象与数据库的同步。
对于 select 语句查询,可以定义一个 JavaBean 来包装查询结果中的关系数据,使应用程序仍旧能够面向对象的方式来访问查询结果。
五、高级查询技巧
1 、动态查询
HQL 和 QBC 都能完成许多相同的任务,相比之下, HQL 能够直观地表达复杂的查询语句,而 QBC 表达复杂的查询语句很麻烦。
如果在程序运行前就明确了查询语句的内容(也称静态查询),应该优先考虑 HQL 查询方式。但是,如果只有在程序运行时才能明确查询语句的内容(也称动态查询), QBC 比 HQL 更加的方便。
QBE 的模糊匹配示例:
Customer customer=.... Example exampleCustomer=Example.create(customer); exampleCustomer.ignoreCase().enableLike(MatchMode.ANYWHERE); exampleCustomer.excludeZeroes(); Criteria criteria=session.crea
发表评论
-
DetachedCriteria构建动态查询
2009-03-24 13:46 877这段代码是项目中的一个方法使用DetachedCriter ... -
hibernate学习笔记
2009-03-24 13:42 926hibernate学习笔记,是我在网上看到很不错的学习资料,把 ... -
hibernate的性能优化
2009-03-23 13:16 875hibernate的性能优化 Hibernate是对JDB ... -
Hibernate的事务管理
2009-03-23 13:15 1625事务(Transaction)是工作中的基本逻辑单位,可以 ... -
Hibernate优化方案
2009-03-21 23:35 1241一、批量修改和删除 在Hibernate 2中,如果需要 ... -
优化Hibernate性能的几点建议
2009-03-21 22:50 793发布日期:2009-3 ... -
Hibernate 的 cache 管理
2009-03-04 23:53 844【转自】 http://www.cnblogs.com/efl ...
相关推荐
本教程将深入探讨"day36-hibernate检索和优化 02-Hibernate检索方式:简单查询及别名查询"的主题,通过源码分析和实际工具的应用,来提升数据库查询的效率。 首先,我们了解Hibernate的检索方式。在Hibernate中,...
标题中的“day36 04-Hibernate检索方式:多表连接查询”表明这是一个关于Hibernate框架的教程,重点讲解如何在Hibernate中进行多表连接查询。在这个主题中,我们将深入探讨Hibernate的ORM(对象关系映射)机制以及...
### Hibernate检索方式详解 #### 一、概述 Hibernate是一个强大的对象关系映射(ORM)框架,它可以将Java对象与数据库表进行映射,使得开发者能够更方便地进行数据的持久化操作。在Hibernate中,提供了多种检索...
一、Hibernate检索方式 1. **HQL(Hibernate Query Language)**: HQL是Hibernate提供的面向对象的查询语言,类似于SQL,但它是基于类和对象的。你可以通过HQL来查询、更新和删除对象,而无需关心底层的SQL语法。...
一、Hibernate检索方式概述 Hibernate提供了多种检索数据的方法,以适应不同的需求场景。这些方法包括:HQL(Hibernate Query Language)、QBC(Query By Criteria)、Criteria API以及直接使用Session的get()和load...
标题:“HIBERNATE检索策略” 描述:本文深入解析了HIBERNATE的检索策略,为读者提供了一条清晰的学习路径,重点分析了HIBERNATE中的抓取策略及其应用场景,帮助开发者更有效地管理和优化数据加载过程。 在...
HQL 是 Hibernate 最常用的检索方式,它支持所有 SQL 支持的检索方式。HQL 是一种面向对象的查询语言,可以使用 HQL 语句来检索对象。 步骤: 1. 获得 Session 2. 编写 HQL 3. 通过 session.createQuery(hql) 创建...
在讲解Hibernate检索方式之前,我们需要先了解Hibernate的基本概念。Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为Java应用程序提供数据持久化服务。通过Hibernate,开发者可以使用Java对象来实现...
11. Hibernate检索方式: - 有四种主要检索方式:HQL(Hibernate查询语言)、Criteria API、Query API(基于JPA的查询)、Native SQL。 12. 对象何时变为游离状态: - 在Hibernate中,当Session关闭时,所有与之...
### Hibernate数据检索(HQL)知识点详解 #### 一、简介 Hibernate 是一款开源的对象关系映射(ORM)框架,它允许开发人员将 Java 对象映射到数据库表中的记录,从而极大地简化了数据访问层的开发工作。本文档基于...
**Hibernate检索方式** 1. **导航对象图检索**:这是最直观的方式,通过已加载的对象导航到与之关联的其他对象,无需直接执行查询。 2. **OID检索**:根据对象的唯一标识(OID,Object Identifier)来获取对象,...
3. **Hibernate Search**:作为Hibernate的一个扩展,Hibernate Search提供了基于Lucene的全文检索功能,使得在数据库中的数据可以被快速、精确地搜索。 **二、集成Hibernate Search** 1. **配置依赖**:首先,你...
1. **Hibernate检索方式**: - 导航对象图检索:通过对象间的引用关系,直接获取关联对象。 - OID检索:通过对象的唯一标识符(OID)查找对象。 - HQL(Hibernate Query Language)检索:面向对象的查询语言,...
mybatie和hibernate相关面试题,包括常用xml标签,一二级缓存等信息hibernate优化以,hibernate在Java中的三种状态,hibernate检索方式
1. **Hibernate检索方式**: - 导航对象图检索:通过对象间的关联关系来获取数据,适合于对象关系映射紧密的情况。 - OID检索:通过对象标识符(Object Identifier)来获取对象,适用于已知对象ID的情况。 - HQL...
### Hibernate的检索策略详解 #### 一、概述 在Java持久化框架Hibernate中,检索策略是一种重要的机制,它主要用于控制对象何时以及如何加载到应用程序内存中。合理的检索策略不仅可以提高应用性能,还能简化代码...