热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

:hibernatehql书写投影查询问题

开发万步网后台管理系统的用户详情和改名功能时用到了hibernate其中有多出异常都是由hibernate引起的,下面我就把我遇到的问题和解决方法一一列出供大家参考。。。1.hql书写问题1

开发万步网后台管理系统的用户详情和改名功能时用到了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     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 getUsername() {
     String hql="select u.username from  PreUcenterMembers u";
     List ulist=super.getList(hql, null); //getList();方法返回一个包含object对象的 List列表。
     if(ulist !=null){
       return ulist;
     }
  return null;
 }

//结果输出

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

 

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

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

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

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 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所以可以这么写,要是你想用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 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.在涉及到复合主键的类时也存在问题。

 


推荐阅读
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 从批量eml文件中提取附件的Python代码实现方法
    本文介绍了使用Python代码从批量eml文件中提取附件的实现方法,包括获取eml附件信息、递归文件夹下所有文件、创建目的文件夹等步骤。通过该方法可以方便地提取eml文件中的附件,并保存到指定的文件夹中。 ... [详细]
  • PreparedStatement防止SQL注入
    添加数据:packagecom.hyc.study03;importcom.hyc.study02.utils.JDBCUtils;importjava.sql ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 本文介绍了解决java开源项目apache commons email简单使用报错的方法,包括使用正确的JAR包和正确的代码配置,以及相关参数的设置。详细介绍了如何使用apache commons email发送邮件。 ... [详细]
  • C语言自带的快排和二分查找
    Author🚹:CofCaiEmail✉️:cai.dongjunnexuslink.cnQQ😙:1664866311personalPage&#x ... [详细]
author-avatar
焦作艾文斯
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有