2009年2月27日 Hibernate-Version: 3.2.5.ga
=================================================================================================
==================================================================================================
类级别(class的lazy属性,3.x默认为true,2.x默认为false)
受影响方法:get(),load()
延迟检索 立即检索
lazy true false
get():总是使用立即检索,没有数据则返回空
load():lazy=true延迟检索,调用getXX()(非getOID())时进行查询,没有数据则抛出异常
lazy=false立即检索,没有数据则抛出异常
==================================================================================================
==================================================================================================
关联级别1(<one-to-one>/<many-to-one>)
outer-join:true | false | auto [Hibernate3已经不赞成使用,使用fetch代替]
fetch:join | select(默认:select)
lazy:false | proxy | no-proxy(默认:proxy)
主键表class lazy:true | false(默认:true)
受影响的方法:HQL,QBC,SQLQuery,get()/load()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fetch lazy 主键表class lazy 检索策略 检索方式
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
select false true/false 立即检索(n+1次查询) 所有
no-proxy/proxy true 延迟检索(n+1次查询) 所有
false 立即检索(n+1次查询) 所有
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
join false true/false inner join QBC,get()/load()
立即检索(n+1次查询) HQL,SQLQuery
no-proxy/proxy false inner join QBC,get()/load()
立即检索(n+1次查询) HQL,SQLQuery
true inner join QBC,get()/load()
延迟检索(n+1次查询) HQL,SQLQuery
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注:1,n+1次查询问题解决办法:
A:可以改用连接查询fetch=join
B:设置批量抓取(batch-size),设置主键表class的batch-size属性,建议3-10之间,这时会使用in(?,?,?)来减少查询语句
2,lazy="proxy"单点关联是经过代理的。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取
(fetche lazily)(需要运行时字节码的增强)。lazy="false"指定此关联总是被预先抓取。
==================================================================================================
==================================================================================================
关联级别2(<set>)
outer-join:true | false | auto [Hibernate3已经不赞成使用,使用fetch代替]
fetch:join | select | subselect(默认:select)
lazy:true | false | extra(默认:true)
受影响的方法:HQL,QBC,SQLQuery,get()/load()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fetch lazy 检索策略 检索方式
select extra/true 延迟检索(n+1次查询) 所有
false 立即检索(n+1次查询) 所有
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
join true/extra left join fetch QBC,get()/load()
延迟检索(n+1次查询) HQL,SQLQuery
false left join fetch QBC,get()/load()
立即检索(n+1次查询) HQL,SQLQuery
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
subselect false 立即检索(n+1次查询) get()/load(),SQLQuery
立即检索(batch fetch) HQL,QBC(使用in子查询进行批量检索)
true/extra 延迟检索(n+1次查询) get()/load(),SQLQuery
延迟检索(batch fetch) HQL,QBC(使用in子查询进行批量检索)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注:1,1,n+1次查询问题解决办法:
A:可以改用连接查询fetch=join
B:设置批量抓取(batch-size),设置<set>的batch-size属性,建议3-10之间,这时会使用in(?,?,?)来减少查询语句
C:设置fetch=subselect,这时只会出现两条SQL语句,第1条SQL查询主键表数据,第2条SQL使用子查询in来查询相关联数据
2,subselect:在检索集合中元素时subselect可以把n+1的检索变为1+1,即一共只出现2条SQL语句,示例:
hql:from Customers
sql://查询customers
select id, username, password, address, email, age from customers
//使用子查询in来查询相关联的orders
select o.id,o.customerid,o.productid,o.amount,o.buytime from orders o where o.customerid in (select id from customers)
3,extra:一种比较聪明的延迟检索策略,即调用集合的size/contains等方法的时候,hibernate并不会去加载整个集合的数据,
而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语
句加载所有对象的数据,
示例A:
List<Customers> list = session.createQuery("from Customers").list();
for (Customers order : list)
System.out.println(order.getOrderses().size());
sql如下:
//查询customers
select id, username, password, address, email, age from customers
//因为调用的是list.size(),所以执行以下SQL
select count(id) from orders where customerid =?
select count(id) from orders where customerid =?
select count(id) from orders where customerid =?
示例B:
List<Customers> list = session.createQuery("from Customers").list();
for (Customers order : list) {
Orders o = new Orders();
o.setId(1001L);
System.out.println(order.getOrderses().contains(o));
}
sql如下:
//查询customers
select id, username, password, address, email, age from customers
//因为调用的是list.contains(),所以执行以下SQL
select 1 from orders where customerid =? and id =?
select 1 from orders where customerid =? and id =?
select 1 from orders where customerid =? and id =?
==================================================================================================
==================================================================================================
注:1,只有QBC,get()/load()支持配制文件中的inner join,其它不支持
2,不管使用何种设置,HQL语句中都可显示使用连接抓取
==================================================================================================
==================================================================================================
联合查询
HQL提供了以下几种联合查询机制:
inner join fetch,left join fetch,right join fetch,full join
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A,inner join fetch(实际上是SQL中的显示内连接:inner join on)
hql="from TPerson tp inner join fetch tp.address";
inner join 返回所有满足关联条件的记录组合,对应的sql语句是:
sql="select * from t_person tp inner join t_address addr on tp.id=addr.person_id";
注:“inner join fetch ”中的fetch关键字表明TAddress对象读出后立即填充到对应的TPerson对象(address属性)中。如果
忽略该关键字,则得到的结果集中,每个条目都是一个Object数组,包括了一个TPerson对象及其对应的TAddress对象
以下的fetch都是这个意思。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
B、left join fetch(实际上是SQL中的左外连接:left outer join on)
hql="from TPerson tp left join fetch tp.address";
返回的结果集中,包含了t_person表(HQL中位于左侧的表)中的所有记录,及其对应的地址信息,如无则以NULL代替。
sql="select * from t_person tp left outer join t_address addr on tp.id=addr.person_id";
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C、right join fetch(实际上是SQL中的右外连接:right outer join on)
hql="from TPerson tp right join tp.address";
与left outer join相反,right outer join 返回的是t_address(HQl中位于右侧的表)中的所有记录及其对应的t_person记录,
如无则以NULL代替。
注:fetch关键字只对inner join和left outer join有效。对right outer join 而言,
1>,hql="from TPerson tp right join tp.address",由于作为关联对象容器的t_person对象可能为null,所以也就无法通过
关键字fetch强制Hibernate进行集合填充操作。意味着只能通过对返回集合中的各个对象数组进行处理,获取所需数据。
2>,hql="from Address a right join a.person",而此时是可以使用fetch的,使用fetch时,集合元素为Address对象,否则为数组
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
D、full join(实际上是SQL中的交叉连接)
hql="from TPerson tp full join tp.address";
报错:org.hibernate.AssertionFailure: undefined join type 23(未解决:mysql5)
返回连接表中所有数据的笛卡尔积,结果集数:person表总条数*address表总条数。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
E:子查询
hql="from Tperson tp where (select count(*) from tp.address)>1";
sql="select ...... from t_person tp where ((select count(*) from t_address addr where tp.id=addr.person_id)>1)";
HQL中,子查询必须出现在where子句中,且必须以一对圆括号包围。
此处转载并修改部分说明:http://blog.csdn.net/fhwbj/archive/2008/12/16/3527950.aspx
==================================================================================================
==================================================================================================
连接查询 customers(id,name) orders(id,name,price,customer_id)
1.交叉连接(cross join,full join) 不带on子句,返回连接表中所有数据的笛卡尔积,结果集数:customers总条数*orders总条数
select * from customers,orders
select * from customers cross join orders
select * from customers full join orders
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.内连接(inner join) 返回连接表中符合连接条件及查询条件的行
1>,显示内连接(select ... from 表1 inner join 表2 on 条件 where ...)
select * from customers c inner join orders o on c.id=o.customer_id
2>.隐式内连接(select ... from 表1,表2 where 条件)
select * from customers c,orders o where c.id=o.customer_id;
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3.外连接(outer join)
1>,左外连接(select ... from 左表 left outer join 右表 on 条件 where ...) 返回左表所有数据和右表符合条件的数据
select * from customers c left outer join orders o on c.id=o.customer_id where c.id=6
2>,右外连接(select ... from 左表 right outer join 右表 on 条件 where ...) 返回右表所有数据和左表符合条件的数据
select * from customers c right outer join orders o on c.id=o.customer_id where c.id=7
分享到:
相关推荐
### Hibernate的检索策略详解 #### 一、概述 在Java持久化框架Hibernate中,检索策略是一种重要的机制,它主要用于控制对象何时以及如何加载到应用程序内存中。合理的检索策略不仅可以提高应用性能,还能简化代码...
### Hibernate知识点总结 #### 一、Hibernate概述 ...通过以上内容,我们了解了Hibernate的基本概念、配置步骤、核心类以及查询语言和检索策略等内容,这对于高效地使用Hibernate框架是非常有帮助的。
一、Hibernate检索方式 1. **HQL(Hibernate Query Language)**: HQL是Hibernate提供的面向对象的查询语言,类似于SQL,但它是基于类和对象的。你可以通过HQL来查询、更新和删除对象,而无需关心底层的SQL语法。...
【Hibernate 简单 PPT 总结】 Hibernate 是一个流行的开源对象关系映射(ORM)框架,它简化了Java应用程序对数据库的操作。通过提供一套API和元数据,Hibernate允许开发者将业务对象直接映射到数据库表,从而避免了...
### Hibernate检索方式详解 #### 一、概述 Hibernate是一个强大的对象关系映射(ORM)框架,它可以将Java对象与数据库表进行映射,使得开发者能够更方便地进行数据的持久化操作。在Hibernate中,提供了多种检索...
**三、Hibernate的检索策略** 1. **类级别的检索策略** - **立即检索**(默认):`lazy="true"`,加载对象时立即执行SQL。 - **延迟检索**(`lazy="false"`):不立即执行SQL,返回代理对象。 2. **关联的检索...
### J2EE系统之-hibernate学习总结 #### 对象持久化理论 - **对象持久化定义**:将对象中的数据转换存储至外部持久性存储设备的过程,如数据库、磁盘等。 - **对象持久化的原因**: - 内存易失性:断电后数据丢失...
学习成长路,Hibernate总结: 1.Hibernate入门优缺点、 2.Hibernate的操作CRUD、 3.主键生成机制、 4.持久化对象的状态、 ...8.Hibernate检索策略(fetch抓取策略)、 9.二级缓存、 10.Hbernate的检索方式(HQL语句)
**Hibernate 二级缓存总结整理** 在Java的持久化框架中,Hibernate是一个广泛使用的ORM(对象关系映射)工具,它极大地简化了数据库操作。在处理大数据量或高并发的场景下,为了提高性能和减少数据库负载,...
**使用Hibernate Search实现全文检索及文档管理** 在Java开发中,全文检索和文档管理是常见的需求,特别是对于大型的企业级应用。Hibernate Search是Hibernate ORM框架的一个扩展,它提供了对数据库中的对象进行...
- **Hibernate中的n+1查询问题**:当使用默认的立即检索策略时,Hibernate会在检索一个对象的同时检索其关联的所有对象。例如,在一个`Customer`与多个`Order`的关联关系中,如果数据库中有`n`个客户,则Hibernate将...
总结来说,选择合适的检索策略是优化Hibernate应用性能的关键。立即检索策略适合简单场景,延迟检索策略适用于优化内存和减少数据库交互,而迫切左外连接检索策略则在需要一次性加载所有关联数据时发挥作用。开发者...
Hibernate支持多种主键策略,如自动生成(GenerationType.AUTO)、固定值(GenerationType.IDENTITY)等。 4. Session:它是Hibernate的主要工作单元,用于在应用程序和数据库之间建立会话。Session提供了一种透明...
1. 配置 Hibernate:通过 `hibernate.cfg.xml` 文件设定数据库连接信息和其他配置。 2. 创建 SessionFactory:使用 Configuration 加载配置并生成 SessionFactory 实例。 3. 获取 Session:通过 SessionFactory 创建...
为了解决这个问题,Hibernate提供了两种主要的检索策略:延迟检索和迫切左外连接检索。 1. **延迟检索策略**:这种策略允许我们在需要时才加载关联对象。默认情况下,Hibernate对集合关联使用的就是延迟加载。在...
**Hibernate开发各类项目的技术总结** Hibernate,作为Java领域的一个强大对象关系映射(ORM)框架,极大地简化了数据库操作,让开发者可以专注于业务逻辑而非繁琐的SQL语句。在我一年半的开发经验中,我逐渐积累了...
此外,为了优化性能,Hibernate Search还提供了高级特性,如倒排索引、分词器选择、过滤器设置、评分策略等。通过这些手段,开发者可以进一步定制检索行为,满足特定的应用场景需求。 总的来说,Hibernate Search是...
总结起来,Hibernate 3.6 作为一款成熟的 ORM 框架,通过对象化的数据库操作方式,极大地提升了 Java 应用的开发效率,同时也提供了丰富的功能和优化选项,帮助开发者更好地应对复杂的数据访问需求。