`

hibernate的连接查询

阅读更多

连接查询:

   关系型数据库之所以强大,其中一个原因就是可以统一使用表来管理同类数据信息,并且可以在相关数据之间建立关系。作为支持关系型数据库的SQL语句来说,自然要对全面发挥这种强大功能提供支持,这个支持就是连接查询。同样作为一种关系型数据库的持久层框架,Hibernate也对连接查询提供了丰富的支持,在Hibernate中通过HQL与QBC两种查询方式都可以支持连接查询。下面这一部分我们将通过这两种查询技术,来详细讨论有关Hibernate对连接查询支持的各个细节。在讲解连接查询之前,我们先来回忆一下在第一部分中讲解的有关实体关联关系的映射,在实体的配置文件中可以通过配置集合元素来指定对关联实体的映射以及检索策略。(请参考第一部分相关内容)因此我们可以在实体映射配置文件中,指定关联实体检索策略,对关联实体的检索策略可以指定为“延迟检索”,“立即检索”,“迫切左外连接检索”,如下所示对与Customer实体关联的Order实体设置延迟加载:<set name=”orders” inverse=”true” lazy=”true”>,这种在实体映射配置文件中设定的检索策略,称为默认检索策略,但是这种默认检索策略是可以被覆盖的,那就是在程序代码当中可以动态指定各种迫切检索策略来覆盖默认检索策略。

1、    迫切左外连接查询和左外连接查询:

我们看以下代码,这段代码将覆盖映射文件中的检索策略,显示指定采用迫切左外连接查询。

HQL查询方式:

Query query=session.createQuery(“from Customer c left join fetch c.orders o where c.name       like ‘zhao%’ ”);

List list=query.list();

for(int i=0;i<list.size();i++){

Customer customer=(Customer)list.get(i);

}

//QBC检索方式:

List list=session.createCriteria(Customer.class).setFetchMode(“orders”,FetchMode.EAGER)

        .add(Expression.like(“name”,”zhao%”,MatchMode.START).list();

for(int i=0;i<list.size();i++){

Customer customer=(Customer)list.get(i);

}

我们看到在HQL以及QBC查询中分别通过left join fetch和FetchMode.EAGER来指定采用迫切左外连接检索策略,当采用了迫切左外连接检索策略时,当进行检索时即执行查询的list()方法时,将会立即初始化用来容纳关联实体的集合对象元素,如果在实体映射配置文件中对关联实体设置了延迟加载,那么此时将会忽略延迟加载设置,而采用迫切左外连接策略,并且立即用关联实体对象填充集合对象元素,即使用Order对象填充Customer对象的orders集合。因此这种检索策略会马上创建关联实体对象,此时我想你一定会想到这种检索策略会同时检索出Customer和Order实体对象对应的数据,并且分别创建这两个对象。恭喜你答对了,因此上面代码会生成类似如下的SQL语句:

Select * from customer c left join order o on c.id=o.id where c.name like ‘zhao%’;

如果我们忽略了fetch关键字,就变成了左外连接查询,如下面代码:

Query query=session.createQuery(“from Customer c left join c.orders o where c.name       like ‘zhao%’ ”);

List list=query.list();

for(int i=0;i<list.size();i++){

Object[] objs=(Object[])list.get(i);

Customer customer=(Customer) objs[0];

order order=(Order)objs[1];

}

我们可以看到采用左外连接查询返回的结果集中包含的是对象数组,对象数组中的每个元素存放了一对相互关联的Customer对象和Order对象,而迫切左外连接会返回Customer对象,与Customer对象相关联的Order对象存放在Customer对象的集合元素对象中,这就是迫切左外连接和左外连接查询的其中一个区别(这两种检索生成的SQL语句是一样的),另一个区别是当使用左外连接时,对关联对象的检索会依照实体映射配置文件所指定的策略,而不会像迫切左外连接那样忽略它,比如此时对Customer对象关联的Order对象采用延迟加载,那么左外连接检索也会使用延迟加载机制检索Order对象。

2、内连接,迫切内连接以及隐式内连接:

若采用迫切内连接通过一下代码可以实现:

Query query=session.createQuery(“from Customer c inner join fetch c.orders o where c.name       like ‘zhao%’ ”);

List list=query.list();

for(int i=0;i<list.size();i++){

Customer customer=(Customer)list.get(i);

}

这段代码将会采用迫切内连接检索,对集合元素的检索策略以及返回结果集中的对象类型都采用与迫切左外连接一样的方式,我这里就不再赘述,另外QBC查询不支持迫切内连接检索。

如果去掉fetch就是内连接检索,如下面代码:

Query query=session.createQuery(“from Customer c innerjoin c.orders o where c.name       like ‘zhao%’ ”);

List list=query.list();

for(int i=0;i<list.size();i++){

Object[] objs=(Object[])list.get(i);

Customer customer=(Customer) objs[0];

order order=(Order)objs[1];

}

内连接检索,对集合元素的检索策略以及返回结果集中的对象类型都采用与左外连接一样的方式,QBC查询也同样支持内连接检索,如下代码:

List list=session.createCriteria(Customer.class)

.add(Expression.like(“name”,”zhao%”,MatchMode.START))

.createCriteria(“orders”)

.add(Expression.like(“ordernumber”,”T”,MatchMode.START)).list();

      上面代码等价于如下的HQL语句:

      Select c from Customer c join c.orders o where c.name like ‘zhao%’ and o.ordernummber like ‘T%’;因此可以采用下面的方式访问结果集:

for(int i=0;i<list.size();i++){

Customer customer=(Customer)list.get(i);

}

      由此可见,采用内连接查询时,HQL与QBC查询有不同的默认行为,HQL会检索出成对的Customer和Order对象,而QBC仅会检索出Customer对象。如果QBC查询想检索出成对的Customer和Order对象,可以采用如下代码:

List list=session.createCriteria(Customer.class)

.createAlias(“orders”,”o”)

.add(Expression.like(“this.name”,”zhao%”,MatchMode.START))

.add(Expression.like(“ordernumber”,”T”,MatchMode.START))

.returnMap()

.list();

for(int i=0;i<list.size();i++){

   Map map=(Map)list.get(i);

Customer customer=(Customer)map.get(“this”);

order order=(Order)map.get(“o”);

}

    “o”和”this”分别是orders集合和Customer对象的别名。

    在HQL查询中,还有一种查询成为隐式内连接,我们看下面的HQL语句,

      From order o where o.customer.name like ’ zhao% ’;这个语句通过o.customer.name访问与Order对象关联的Customer对象的name属性,尽管没有使用join关键字,其实隐式指定了采用内连接检索,它和下面这条HQL语句等价:

From order o join o.customer c where c.name like ‘zhao%’;

隐式内连接只适用于多对一和一对一关联,不适用于一对多和多对多关联,另外QBC查询不支持隐式内连接检索。

3、右外连接检索:

由于fetch关键字只能应用于innner join和left join,因此对于右外连接检索而言,就不存在所谓的迫切右外连接查询了,使用右外连接见如下代码:

Query query=session.createQuery(“from Customer c right join c.orders o where c.name       like ‘zhao%’ ”);

List list=query.list();

for(int i=0;i<list.size();i++){

Object[] objs=(Object[])list.get(i);

Customer customer=(Customer) objs[0];

order order=(Order)objs[1];

}

      右外连接检索,对集合元素的检索策略以及返回结果集中的对象类型都采用与左外连接一样的方式。

4、交叉连接:

对于不存在关联关系的两个实体对象,不能使用内连接查询,也不能使用外连接查询,此时可以使用具有SQL风格的交叉连接,如下面代码:

Select c.ID,c.name,c.age,o.ID,o.ordernumber,o.customer_ID

From Customer c,Order o;

这个HQL语句将会执行交叉连接检索,而且将会返回customer表和order表的笛卡儿积关联结果。

5、连接查询运行时检索策略总结:

①、如果在HQL和QBC查询中没有指定检索策略,那么将会使用映射配置为件中指定的检索策略,但是这里有一个例外,那就是HQL检索总是会忽略实体映射配置文件中对关联实体指定的迫切左外连接检索策略,也就是说如果配置文件中指定对关联实体采用迫切走外连接检索,但是在HQL查询语句中没有指定这种检索策略,此时Hibernate将会忽略这种检索策略,而依然采用立即检索。因此如果希望采用迫切左外连接检索,就必须在HQL语句中明确指定。

②、如果在HQL或者QBC检索中明确指定了检索策略,就会覆盖配置文件中的默认检索策略,在HQL查询中通过left join fetch和inner join fetch来明确指定检索策略,在QBC查询中通过FetchMode.DEFAULT,FetchMode.EAGER,FetchMode.LAZY来明确指定检索策略。

①、             目前的Hibernate的各种版本中,只允许在一个查询中迫切左外连接检索一个集合,即只允许存在一个一对多关联,但是允许存在多个一对一和多对多关联。

分享到:
评论

相关推荐

    day36 04-Hibernate检索方式:多表连接查询

    标题中的“day36 04-Hibernate检索方式:多表连接查询”表明这是一个关于Hibernate框架的教程,重点讲解如何在Hibernate中进行多表连接查询。在这个主题中,我们将深入探讨Hibernate的ORM(对象关系映射)机制以及...

    hibernate分页查询 数据库连接

    本篇将深入探讨Hibernate中的分页查询功能以及它如何处理数据库连接,帮助你更有效地管理大数据量的查询操作。 首先,我们来看一下什么是分页查询。在Web应用中,当用户需要浏览大量数据时,一次性加载所有数据不仅...

    hibernate 连接池配置详解

    以下是使用C3P0配置Hibernate连接池的方法: 1. **添加依赖**:确保项目中有C3P0相关的JAR包,例如`c3p0-0.8.4.5.jar`。 2. **配置连接池参数**: - 在`hibernate.cfg.xml`文件中设置以下属性来配置C3P0连接池: ...

    Hibernate连接SQLite配置说明和方言代码

    Hibernate连接SQLite配置步骤: 1、添加SQLite库: 1.1、将两个jar包:com.zy.hibernate.dialect.SQLiteDialect.jar、sqlite-jdbc-3.7.2.jar拷贝到“\WEB-INF\lib”文件夹下; 2、配置hibernate: 2.1、将...

    java hibernate连接池源码

    配置Hibernate连接池通常涉及到以下几个步骤: 1. **选择连接池**:首先,你需要决定使用哪个连接池实现。比如,如果你选择C3P0,你需要添加对应的依赖到项目中。 2. **配置Hibernate**:在Hibernate的配置文件...

    hibernate连接池.doc

    在Java的持久化框架Hibernate中,连接池是一个关键组件,用于优化数据库的连接管理,减少创建和关闭数据库连接的开销。文档中的标题和描述提到了Hibernate对第三方连接池的支持,特别是C3P0、Proxool和DBCP。下面...

    Hibernate 多表连接分页查询示范项目

    Hibernate 支持多种方式来实现多表连接查询,包括 HQL(Hibernate Query Language)和 Criteria 查询。本项目主要关注 Criteria API 的使用,这是一种基于 Java 对象的查询方式,更加灵活且易于理解和维护。 **...

    hibernate连接金仓数据库所需jar包集合lib.7z

    在使用Hibernate连接金仓数据库时,需要特定的驱动和其他相关jar包来支持这种连接。下面我们将详细介绍这些jar包的作用以及如何配置它们。 首先,"hibernate连接金仓数据库所需jar包集合lib.7z"这个压缩包中包含了...

    hibernate连接Access应用项目例子

    在本项目中,“hibernate连接Access应用项目例子”展示了如何使用Hibernate ORM框架与Microsoft Access数据库进行集成,实现数据的增、删、改、查(CRUD)操作。Hibernate是Java开发中的一个流行ORM(对象关系映射)...

    Hibernate连接数据库的注册的项目

    首先,Hibernate连接数据库的核心在于`hibernate.cfg.xml`配置文件。这个文件包含了数据库连接的所有必要信息,如数据库URL、用户名、密码、驱动类等。例如: ```xml &lt;hibernate-configuration&gt; ...

    hibernate连接池

    总结来说,Hibernate连接池是提升数据库访问效率的关键,它提供了多种连接池的集成,包括C3P0、DBCP、HikariCP和Druid。开发者可以根据项目需求和性能指标,选择合适的连接池并进行精细配置,以优化数据库操作,提高...

    hibernate的查询方式介绍和hibernate的批处理和连接池配置hibernate

    ### Hibernate 查询方式与批处理及连接池配置详解 #### 一、Hibernate 查询方式介绍 Hibernate 是一款优秀的 ORM(对象关系映射)框架,它能够极大地简化数据库操作,并提供多种查询方式来满足不同的业务需求。 #...

    hibernate 连接sqlserver2000

    当使用Hibernate连接SQL Server 2000时,我们需要考虑以下几个关键点: 1. **驱动兼容性**:SQL Server 2000使用的是JDBC 3.0驱动,因此需要确保选用的Hibernate版本和JDBC驱动兼容此版本。通常,较早的Hibernate...

    hibernate连接池驱动

    总的来说,理解并正确配置Hibernate连接池驱动对于提升应用的性能和可扩展性至关重要。无论是c3p0还是Proxool,它们都是为了优化数据库连接的生命周期管理,减少数据库连接创建和释放带来的开销,从而提高系统整体的...

    使用Hibernate连接MySql的入门小程序

    **使用Hibernate连接MySQL的入门小程序** 在Java编程领域,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,将复杂的SQL查询转换为简单的Java对象操作。本入门程序将带你了解如何使用Hibernate...

    Hibernate连接Access

    标题“Hibernate连接Access”指的是在Java编程环境中使用Hibernate框架与Microsoft Access数据库进行交互的技术。Hibernate是一个流行的开源对象关系映射(ORM)工具,它允许开发者使用面向对象的编程方式来操作...

    用hibernate连接mycat的例子

    本示例"用hibernate连接mycat",旨在展示如何在Java项目中结合这两个技术,利用Hibernate的ORM能力处理Mycat分片后的数据。以下将详细介绍这个过程,以及相关的配置和注意事项。 首先,我们需要在项目中集成Mycat。...

    hibernate连接数据[Mysql]的代码实例

    **hibernate连接数据[Mysql]的代码实例** 在Java应用程序中,Hibernate是一个非常流行的ORM(Object-Relational Mapping)框架,它提供了强大的数据库操作能力,简化了Java与关系型数据库如MySQL之间的交互。本实例将...

    java利用hibernate连接数据库

    Java通过Hibernate连接数据库是Java开发中的常见操作,Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了数据库操作。本篇文章将详细讲解如何利用Hibernate在Java项目中建立数据库连接,以及提供一个...

    hibernate 自连接 emp例子

    在这个特定的例子中,我们关注的是如何在Hibernate中实现自连接查询,以处理Oracle数据库中EMP表的树状结构问题。 首先,自连接查询是指一个表与自身进行连接的操作,常用于处理具有层级关系的数据,例如员工的上...

Global site tag (gtag.js) - Google Analytics