`
shonghuanc
  • 浏览: 84292 次
文章分类
社区版块
存档分类
最新评论

hibernate dc查询

阅读更多
Hibernate3的DetachedCriteria支持2005-07-12 09:55 作者: robbin 出处: Java视线 责任编辑:方舟    Hibernate3支持DetachedCriteria,这是一个非常有意义的特性!我们知道,在常规的Web编程中,有大量的动态条件查询,即用户在网页上面自由选择某些条件,程序根据用户的选择条件,动态生成SQL语句,进行查询。

  针对这种需求,对于分层应用程序来说,Web层需要传递一个查询的条件列表给业务层对象,业务层对象获得这个条件列表之后,然后依次取出条件,构造查询语句。这里的一个难点是条件列表用什么来构造?传统上使用Map,但是这种方式缺陷很大,Map可以传递的信息非常有限,只能传递name和value,无法传递究竟要做怎样的条件运算,究竟是大于,小于,like,还是其它的什么,业务层对象必须确切掌握每条entry的隐含条件。因此一旦隐含条件改变,业务层对象的查询构造算法必须相应修改,但是这种查询条件的改变是隐式约定的,而不是程序代码约束的,因此非常容易出错。

  DetachedCriteria可以解决这个问题,即在web层,程序员使用DetachedCriteria来构造查询条件,然后将这个DetachedCriteria作为方法调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后,可以在session范围内直接构造Criteria,进行查询。就此,查询语句的构造完全被搬离到web层实现,而业务层则只负责完成持久化和查询的封装即可,与查询条件构造完全解耦,非常完美!这恐怕也是以前很多企图在web层代码中构造HQL语句的人想实现的梦想吧!

  示例代码片段如下:

  web层程序构造查询条件:

  java代码:

DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class);
detachedCriteria.add(Restrictions.eq("name", "department")).createAlias("employees", "e").add(Restrictions.gt(("e.age"), new Integer(20)));

  Department和Employee是一对多关联,查询条件为:

  名称是“department”开发部门;
  部门里面的雇员年龄大于20岁;

  业务层对象使用该条件执行查询:

  java代码:

detachedCriteria.getExecutableCriteria(session).list();

  最大的意义在于,业务层代码是固定不变的,所有查询条件的构造都在web层完成,业务层只负责在session内执行之。这样代码就可放之四海而皆准,都无须修改了。

  然而Spring和Hibernate3的DetachedCriteria有不兼容的问题,因此在Spring环境下面使用Hibernate3需要注意:

  Spring的HibernateTemplate提供了Hibernate的完美封装,即通过匿名类实现回调,来保证Session的自动资源管理和事务的管理。其中核心方法是:

  java代码:

HibernateTemplate.execute(new HibernateCallback() {
 public Object doInHibernate(Session session) throws HibernateException {
  ....
 }
}

  回调方法提供了session作为参数,有了session,就可以自由的使用Hibernate API编程了。使用了spring的之后,代码修改如下:

  web层代码:

  java代码:

DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class);
detachedCriteria.createAlias("employees", "e").add(Restrictions.eq("name", "department")).add(Restrictions.gt(("e.age"), new Integer(20)));
departmentManager.findByCriteria(detachedCriteria);

  构造detachedCriteria,作为参数传递给departmentManager

  业务层代码使用spring,DepartmentManager的findByCriteria如下:

  java代码:

public List findByCriteria(final DetachedCriteria detachedCriteria) {
 return (List) getHibernateTemplate().execute(new HibernateCallback() {
  public Object doInHibernate(Session session) throws HibernateException {
   Criteria criteria = detachedCriteria.getExecutableCriteria(session);
   return criteria.list();
  }
 });
}

  实际上也就是:

  java代码:

Criteria criteria = detachedCriteria.getExecutableCriteria(session);
return criteria.list(); 

  而已

  但是该程序代码执行,会抛出强制类型转换异常!

  我跟踪了一下spring和Hibernate源代码,原因如下:

  spring的HibernateTemplate的execute方法提供的回调接口具有Session作为参数,但是实际上,默认情况下,HibernateTemplate传递给回调接口的session并不是org.hibernate.impl.SessionImpl类,而是SessionImpl类的一个Proxy类。之所以替换成为一个Proxy类,HibernateTemplate的注释说明,Proxy提供了一些额外的功能,包括自动设置Cachable,Transaction的超时时间,Session资源的更积极的关闭等等。

  java代码:

private boolean exposeNativeSession = false;
... 

  execute方法内部:

Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));

  但是遗憾的是,Hibernate的DetachedCriteria的setExecutableCriteria方法却要求将session参数强制转为SessionImpl,但是spring传过来的却是一个Proxy类,因此就报错了。

  java代码:

public Criteria getExecutableCriteria(Session session) {
 impl.setSession( (SessionImpl) session ); // 要求SessionImpl,Spring传递的是Proxy
 return impl;
}

  解决方法,禁止Spring的HibernateTemplate传递Proxy类,强制要求它传递真实的SessionImpl类,即给exexute方法增加一个参数,提供参数为true,如下:

  java代码:

public List findByCriteria(final DetachedCriteria detachedCriteria) {
 return (List) getHibernateTemplate().execute(new HibernateCallback() {
  public Object doInHibernate(Session session) throws HibernateException {
   Criteria criteria = detachedCriteria.getExecutableCriteria(session);
   return criteria.list();
  }
 }, true);

分享到:
评论

相关推荐

    HQL是hibernate自己的一套查询

    根据提供的标题、描述以及部分代码内容,我们可以了解到这段材料主要涉及的是Hibernate框架中的HQL(Hibernate Query Language)查询语言的使用。接下来将详细介绍HQL的相关知识点。 ### HQL概述 HQL是Hibernate...

    六种方式实现hibernate查询

    六种方式实现Hibernate查询 Hibernate是一个功能强大的持久层框架,它提供了多种方式来查询数据库。下面我们将详细介绍六种方式实现Hibernate查询。 HQL查询 HQL(Hibernate Query Language)是Hibernate自己的...

    Hibernate中Criteria的用法

    而在Hibernate提供的多种查询方式中,Criteria API是一种非常灵活且强大的查询工具,它支持复杂的条件组合以及分组、排序等功能,为开发者提供了更为方便的查询手段。 #### 二、Criteria简介 Criteria是Hibernate...

    Hibernate 一对多外键单向关联

    - 创建`address_1nfk`表时,定义了addressid为主键,addressdetail为可空字段,personid为外键,通过外键约束`FK9B93456DC08D1667`关联到`person_1nfk`表的personid。 在配置Hibernate映射文件时,对于Person实体...

    hiberante 学习PDF

    - **HQL(Hibernate Query Language)**:一种面向对象的查询语言,类似于 SQL,但更加面向对象。 - **Criteria API**:提供了一种更灵活的查询方式,支持动态构建查询条件。 #### 缓存机制 Hibernate 提供了两级...

    dc.rar_网上购物

    5. **数据库操作**:为了持久化数据,项目可能使用了关系型数据库,如MySQL或Oracle,配合JDBC或ORM工具(如Hibernate)进行数据访问。购物车中的商品信息、用户订单等都需要存储在数据库中。 6. **安全考虑**:在...

    Criteria详解

    其中,Criteria API作为Hibernate提供的一个强大的查询工具,为开发者提供了灵活且易于使用的接口来构建复杂的查询逻辑。本文将详细介绍Criteria的相关知识点,包括其基本概念、使用场景以及具体的实现细节。 #### ...

    DC-Resources:ignoooooooooreeeee说

    4. **Java库和框架**:如果DC-Resources涉及到了具体的Java库或框架,例如Spring Boot、Hibernate、MyBatis等,这些都是Java开发中的常用工具,可以大大简化开发工作。 5. **单元测试**:Java项目通常会包含JUnit或...

    CLAS12-DC-Database

    6. **ORM(对象关系映射)框架**:Hibernate和MyBatis是常见的Java ORM框架,它们简化了Java与数据库的交互,通过映射Java对象到数据库表,使得开发人员可以使用面向对象的方式来操作数据库。 7. **SQL优化**:高效...

    DC全栈部署

    JavaScript通过ORM(对象关系映射)库如Sequelize(Node.js)或Hibernate(Java)可以方便地操作数据库。 四、服务器与网络 服务器硬件选择、操作系统安装(如Linux发行版)、负载均衡配置、网络安全策略等都是DC...

    java面试题集锦(附答案)

    Hibernate中的Criteria API提供了去除查询结果重复项的方法,`dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);`这行代码会确保返回的结果集中不会有重复的根实体对象。 2. **HTTP与SMTP协议及其端口**:...

    Java面试题

    Java面试题涵盖了许多核心知识点,包括ORM框架Hibernate的使用、网络协议、文件操作、Servlet的生命周期、SQL查询、集合框架的特性和关键字的区别。以下是这些知识点的详细解释: 1. **Hibernate离线查询去除重复项...

    java工程师面试题大全100%公司笔试题你都能碰到几个

    1. Hibernate离线查询去除重复项 在Hibernate中,使用dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)可以去除重复项。 2. HTTP协议及端口、SMTP协议及端口 HTTP(HyperText Transfer Protocol)是一种...

    java软件工程师面试题

    在 Criteria 查询中,添加 `dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);` 可以确保返回的实体不包含重复。 2. **HTTP和SMTP协议及其端口**: - HTTP(超文本传输协议)通常运行在端口 80 上,用于...

    Java程序员面试题搜集

    Hibernate 提供了 `dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);` 来去除查询结果中的重复实体。这会在查询执行后对结果进行处理,确保返回的根实体是唯一的。 2. **HTTP和SMTP协议及端口**: HTTP...

    java面试大全

    Hibernate 提供了一个方便的方法来去除查询结果中的重复实体,即 `dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);` 这行代码会确保返回的实体结果是唯一的,避免了由于关联查询导致的重复数据。 2. **...

    尚硅谷S4S2H4整合案例视频教程

    - JavaWeb:https://www.pipipan.com/dir/15166809-24058584-e8dc5e/ - Linux:https://www.pipipan.com/dir/15166809-24182994-919455/ - Office/办公软件:https://www.pipipan.com/dir/15166809-24132591-75c645/...

    SSM框架的图书管理系统(新增登录注册下载功能)

    3 同时使用了了hibernate提供的校验框架,对客户端数据进行校验! 4 Mybati数据库DAO层采用的是Mapper代理开发方法,输入映射采用的是POJO包装类型实现,输出映射采用了resultMap类型,实现了数据库多对一映射。 5 ...

    tomcat部署,数据库备份,清空

    - 首先,需要从指定路径`\\changsha-p-dc\Drops\内蒙人保PICC\Webservices\PICCWebservicesDailyBuild_20110829.1\MavenOutput\Webservices\PICC\target`获取每日构建的包。 - 在获取到的包中,找到`WEB-INF`...

    Java笔试题目.doc

    1. **离线查询去除重复项**:在Hibernate的Criteria查询中,使用`dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)`可以去除结果集中重复的根实体。 2. **网络协议与端口**:HTTP协议通常使用80端口,SMTP...

Global site tag (gtag.js) - Google Analytics