`

hibernate hql 书写 投影查询 问题

阅读更多

 

开发万步网后台管理系统的用户详情和改名功能时用到了hibernate 其中有多出异常都是由hibernate引起的,下面我就把我遇到的

问题和解决方法一一列出供大家参考。。。

 

1. hql书写问题

  1.1  当我们写hql的时候如果用?占位符方式传参切记如果是字符串的千万不要再hql中对?左右加'  ' 我们只写? 下面有那个query

        .setString(); 来赋值就行了。

   1.2 用hql更新或插入的时候不要用”++“来拼接中文参数那样是不会起到作用的而要用:参数名称 或 ? 这两种方式来赋值英文的参数是可以的 当然这只是针对于hibernate3来讲的 听说 >=hibernate3.1的已经支持用“++”方式操作中文了。

   1.3. 用hql执行update 时候不能再为表起别名,在对涉及到复合主键的表update时候也不能用别名.id.属性方式操作属性了。

        错误代码:hql="update WanbuRankStar  w  set w.id.username=:username where w.id.username=:beforename";

        正确代码:hql="update WanbuRankStar  set username=:username where username=:beforename";

  1.4 当用hql进行多表联查时候记住hibernate的hql是不支持inner join on 或 left join on 的 只要带on就不对不管是内,左,右,交叉,全  什 么形式的连接所以我们只能用sql来进行了。

2. 投影查询问题

/**
  * 根据参数,hql语句查询
  * @param hql
  * @param params
  * @return
  */
 public List getList(String hql, String[] params) {
  Session session = getSession();
  Query query = null;
  try {
   
   query = session.createQuery(hql);
   if(params!=null)
   {
    for (int i=0;i<params.length;i++) {
     query.setString(i, params[i]);
    }
   }
   List list=query.list();
   if(list!=null &&list.size()!=0){
     
       return list;
   
   }
   
  } catch (Exception e) {
   e.printStackTrace();
   return null;
  } finally {
   try {
    if (session != null && session.isOpen()) {
     closeSession();
    }
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
   return null;
 }

 1.投影查询如果只查询一个字段query.ist() 是返回list<.object> 列表的而每一个object对象里面放的就是改字段的实际类型需要我们转换一下

    来用 用例代码:

public List<String> getUsername() {
     String hql="select u.username from  PreUcenterMembers u";
     List<String> ulist=super.getList(hql, null); //getList();方法返回一个包含object对象的 List<object >列表。
     if(ulist !=null){
       return ulist;
     }
  return null;
 }

//结果输出

 public static void main(String[] args) throws UnsupportedEncodingException {
    IUserManageDao um=new UserManageImpl();
 List<String> s=um.getUsername();  
 System.out.println(s); //输出 [得实陈其, 得实陈庆义, 得实陈尚岩, 得实陈世华, 得实陈薇薇] String 类型的数组。
    }

 

2. 投影查询查询多个字段(无论是一个表中多个字段还是多个表中的不同字段 有或者是不同库中不同表的一些字段 都适用 我们只需将

涉及到的表和类 映射好就行了)

     2.1 当查询多个字段的时候query.list() 返回list<object [] > 列表而每一个object[]就是查询的这几个字段的集合并且也类型也对应着实际字段的类型 我们用的时候可以遍历list<object []> 将其元素封装成我们的实体列表当然这个实体类中的属性类型应该和查询返回字段类型一一对应。 用例代码:

public UserDetailData getUserInfo(String uname) {

String hql="select p.address,u.email,p.gender,p.mobile,j.nickname,p.realname,FROM_UNIXTIME(u.regdate),u.regip,u.username,p.resideprovince,p.residecity,p.residecommunity,p.residesuite,p.residedist " +
  " from PreUcenterMembers u"
 +" ,PreCommonMemberProfile p  "
 +" ,JishigouMembers j  where u.uid=j.uid and u.uid=p.uid and u.username=?";
 
  List<Object []> uinfo=super.getList(hql,new String[]{uname});
  UserDetailData ud=null;
  if(uinfo !=null){
   
   for(Object [] u : uinfo){
       ud=new UserDetailData();
          ud.setAddress((String)u[0]);
          ud.setEmail((String)u[1]);
          ud.setGender((Byte)u[2]);
          ud.setMobile((String)u[3]);
          ud.setNickname((String)u[4]);
          ud.setRealname((String)u[5]);
             ud.setRegdate(u[6].toString());
          ud.setRegip((String)u[7]);
          ud.setUsername((String)u[8]);
                   ud.setResideprovince((String)u[9]);
                   ud.setResidecity(u[10].toString());
                   ud.setResidedist(u[11].toString());
                   ud.setResidecommunity(u[12].toString());
                   ud.setResidesuite(u[13].toString());
          }
        return ud; 
  }  
  return null;
 }

public class UserDetailData {

 // Fields  这些类型要与查询后返回的字段类型一致 查询返回字段类型并不是数据库中的字段或你映射好的属性类型而是实实在在返回的类型 例: regdate 在PreUcenterMembers 中为Interger 而此处要为timestamp因为当查询regdate时 FROM_UNIXTIME(u.regdate) 返回的是timestamp 但因为 ud.setRegdate(u[6].toString()); 做了转换所以该类regdate在此处为String,当然因为此查询返回的list<object>所以可以这么写,要是你想用new 方式来实现则该类属性是必须与数据库字段类型对应的。

 private String address;
 private String email;
 private Byte gender;
 private String mobile;
 private String nickname;
 private String realname;
 private String regdate;
 private String regip;
 private String username;
 private String resideprovince;
 private String residecity;
 private String residedist;
 private String residecommunity;
 private String residesuite;
 public UserDetailData(String address, String email, Byte gender,
   String mobile, String nickname, String realname, String regdate,
   String regip, String username) {
  super();
  this.address = address;
  this.email = email;
  this.gender = gender;
  this.mobile = mobile;
  this.nickname = nickname;
  this.realname = realname;
  this.regdate = regdate;
  this.regip = regip;
  this.username = username;
 }

  //此处省略get/set 方法

}

}

 上面这种形式完全可以解决对多表联查的投影查询返回结果封装问题而且对要封装返回结果的实体类属性类型没什么严格限制我们可以根据我们要在页面上展示的数据形式来决定他的类型相对new方式比较灵活,所以推荐使用。

    2.2 一种更简单的方式我们可以事先建立好一个类用来封装查询结果,这个类中的属性和数据库的字段类型一致并且有无参构造和对应查询字段的构造,然后采用select new(放入字段对应的属性)from 类名 方式为其实例化,这个query.list()返回的就是list<这个类> 列表,用例代码:

public UserDetailData getUserInfo(String uname) {
     /*
      * private String resideprovince;
 private String residecity;
 private String residedist;
 private String residecommunity;
 private String residesuite;
      */
  String hql="select new UserDetailData(p.address,u.email,p.gender,p.mobile,j.nickname, p.realname,u.regdate,u.regip,u.username,p.resideprovince,p.residecity,p.residedist,p.residecommunity,p.residesuite) " +
  " from PreUcenterMembers u"
 +" ,PreCommonMemberProfile p  "
 +" ,JishigouMembers j  where u.uid=j.uid and u.uid=p.uid and u.username=?";
         List<UserDetailData> u=super.getList(hql, new String [] {uname});
   if(u!=null ){
   return u.get(0); 
   }
   return null;
 }

 

public class UserDetailData {

 // Fields  此处regdate 必须为Integer 也就是要和数据库表的字段类型一致了。。。

 private String address;
 private String email;
 private Byte gender;
 private String mobile;
 private String nickname;
 private String realname;
 private Integer regdate;
 private String regip;
 private String username;
 private String resideprovince;
 private String residecity;
 private String residedist;
 private String residecommunity;
 private String residesuite;
 public UserDetailData(String address, String email, Byte gender,
   String mobile, String nickname, String realname, String regdate,
   String regip, String username) {
  super();
  this.address = address;
  this.email = email;
  this.gender = gender;
  this.mobile = mobile;
  this.nickname = nickname;
  this.realname = realname;
  this.regdate = regdate;
  this.regip = regip;
  this.username = username;
 }

  //此处省略get/set 方法

}

}

 

这里说明一下吧,我在使用这种方式的时候出现过问题 1.org.hibernate.hql.ast.QuerySyntaxError: Unable to locate class [UserDetailData]

 2.在涉及到复合主键的类时也存在问题。

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    hibernateHQL关联查询

    ### Hibernate HQL 关联查询详解 #### 一、引言 在进行数据库操作时,关联查询是必不可少的一部分,尤其在处理复杂的数据结构时更是如此。Hibernate作为一种流行的Java持久层框架,提供了强大的对象关系映射(ORM...

    hibernate hql语句 投影查询的三种方式.docx

    本篇文章将详细介绍在Hibernate中进行投影查询的三种主要方式:直接查询、查询返回对象以及查询返回Map键值对。 1. **直接查询** 直接查询是最基础的投影方式,它允许我们选择特定的属性进行检索,而不是整个对象...

    Hibernate hql查询语法总结

    《Hibernate HQL查询语法详解》 Hibernate,作为Java领域中广泛应用的对象关系映射(ORM)框架,极大地简化了数据库操作。其内置的HQL(Hibernate Query Language)是一种面向对象的查询语言,它允许开发者以类和...

    Hibernate HQL查询 分页查询 模糊查询.docx

    ### Hibernate HQL 查询详解 #### 一、HQL(Hibernate Query Language)简介 HQL(Hibernate Query Language)是一种面向对象的查询语言,它允许开发者使用类及其属性来编写查询语句,而不是传统的SQL语句。这使得...

    Hibernate HQL基础练习小列子+数据库文件

    Hibernate HQL基础练习小列子+数据库

    Hibernate(HQL、QBC查询)源码

    Hibernate(HQL、QBC查询)源码 Hibernate(HQL、QBC查询)源码 Hibernate(HQL、QBC查询)源码 Hibernate(HQL、QBC查询)源码 Hibernate(HQL、QBC查询)源码

    Hibernate查询语言HQL.PPT

    Hibernate 查询语言 HQL Hibernate 查询语言 HQL 是一种面向对象的查询语言,用于检索对象。它提供了灵活多样的查询机制,包括导航对象图、通过标识符检索、使用 HQL 检索对象、使用 Hibernate 条件 API 和使用本地...

    HibernateHQL.zip_更新

    此压缩包中的`HibernateHQL.chm`文件很可能是Hibernate HQL的详细教程或参考手册,包含了HQL的语法、用法示例、最佳实践以及可能遇到的问题解决方案。它可以帮助开发者深入理解如何在实际项目中高效地使用HQL进行...

    hibernate hql各类查询范例

    以上内容涉及了使用 HQL 和 DetachedCriteria 进行查询、参数化查询、执行更新操作以及简单的统计查询等常见的 Hibernate 操作。这些知识点对于理解和掌握 Hibernate 框架的基本使用至关重要,同时也是开发基于 ...

    hibernateHQL基本查询

    ### Hibernate HQL 基本查询详解 #### 一、HQL 概述 HQL (Hibernate Query Language) 是一种面向对象的查询语言,由 Hibernate 官方提供,用于简化数据库查询过程。与传统的 JDBC 方式相比,使用 HQL 进行数据库...

    Hibernate_HQL.rar_hibernate HQL_hibernate hql src

    对hibernate的hql进行了详尽的讲解

    Hibernate HQL查询语句总结.docx

    Hibernate HQL 查询语句总结 Hibernate HQL 查询语句是 Hibernate 框架中的一种查询语言,它提供了更加丰富的和灵活的查询特性,具有类似标准 SQL 语句的查询方式,同时也提供了更加面向对象的封装。以下是 ...

    Hibernate-HQL.rar_HQL_hibernate hql

    本篇文档将深入探讨Hibernate中的HQL(Hibernate Query Language),一种面向对象的查询语言,它提供了与SQL类似的语法,但更贴近于面向对象的思维模式,使得开发者可以更加便捷地进行数据查询。 一、HQL简介 HQL是...

    hibernate的HQL的模糊查询

    下面我们将深入探讨Hibernate的HQL模糊查询及其应用。 一、HQL概述 HQL是一种面向对象的查询语言,它的语法结构与SQL类似,但更关注于对象和实体,而不是数据库表和列。HQL允许开发者直接操作Java对象,避免了直接...

    Hibernate HQL基础 限定查询条件 .doc

    Hibernate 中,HQL(Hibernate Query Language)是一种面向对象的查询语言,它允许开发者用类名、属性和关联来编写查询,而不是直接使用数据库的SQL语句。HQL的基础包括了各种查询条件的设定,这些条件使得我们可以...

    HibernateHql综合测试小程序

    本程序“HibernateHql综合测试小程序”是针对Hibernate中的HQL(Hibernate Query Language)进行的一系列功能测试,涵盖了二十多种不同的HQL语句,旨在帮助开发者深入理解和熟练运用Hibernate的查询能力。...

    另类查询 Hibernate HQL 深度历险

    【Hibernate HQL 深度历险】是一个关于掌握Hibernate查询语言高级特性的技术主题。Hibernate Query Language(HQL)是Hibernate框架提供的面向对象的查询语言,它与SQL类似但针对对象模型,允许开发者直接查询对象而...

    Hibernate HQL.txt

    根据提供的文件信息,我们可以深入探讨Hibernate HQL(Hibernate Query Language)的相关知识点,特别是关于其查询功能、连接操作、条件过滤以及聚合函数的应用等。 ### Hibernate HQL简介 Hibernate HQL是一种...

    Hibernate 课件_HQL

    ### Hibernate 课件_HQL 知识点解析 #### HQL查询 ...这些知识点涵盖了HQL的基本概念、查询方法、各种高级查询技巧以及Session的管理等方面,希望能够帮助大家更好地理解和掌握Hibernate的HQL查询技术。

    Hibernate HQL 结合 velocity

    **Hibernate HQL(Hibernate Query Language)** 是Hibernate提供的一个面向对象的查询语言,类似于SQL,但它是针对对象模型设计的。HQL允许开发者使用类和属性的名字而不是表和列名进行查询,从而降低了对底层...

Global site tag (gtag.js) - Google Analytics