`

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.在涉及到复合主键的类时也存在问题。

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    linux基础进阶笔记

    linux基础进阶笔记,配套视频:https://www.bilibili.com/list/474327672?sid=4493093&spm_id_from=333.999.0.0&desc=1

    IMG20241115211541.jpg

    IMG20241115211541.jpg

    Sen2_ARI_median.txt

    GEE训练教程——Landsat5、8和Sentinel-2、DEM和各2哦想指数下载

    毕业设计&课设_基于 flask-whoosh-jieba 的代码,涉及文件管理及问题修复.zip

    该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过严格测试运行成功才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

    基于springboot家政预约平台源码数据库文档.zip

    基于springboot家政预约平台源码数据库文档.zip

    Ucharts添加stack和折线图line的混合图

    Ucharts添加stack和折线图line的混合图

    基于springboot员工在线餐饮管理系统源码数据库文档.zip

    基于springboot员工在线餐饮管理系统源码数据库文档.zip

    2015-2021年新能源汽车分地区、分类型、分级别销量逐月数据和进出口数据-最新出炉.zip

    新能源汽车进出口数据 1、时间跨度:2018-2020年 2、指标说明:包含如下指标的进出口数据:混合动力客车(10座及以上)、纯电动客车(10座及以上)、非插电式混合动力乘用车、插电式混合动力乘用车、纯电动乘用车 二、新能源汽车进出口月销售数据(分地区、分类型、分 级别) 1、数据来源:见资料内说明 2、时间跨度:2014年1月-2021年5月 4、指标说明: 包含如下指标 2015年1月-2021年5月新能源乘用车终端月度销量(分类型)部分内容如下: 新能源乘用车(单月值、累计值 )、插电式混合动力 月度销量合计(狭义乘用车轿车、SUV、MPV、交叉型乘用车); 月度销量同比增速(狭义乘用车轿车、SUV、MPV、交叉型乘用车); 累计销量合计(狭义乘用车轿车、SUV、IPV、交叉型乘用车); 累计销量同比增速(狭义乘用车轿车、SUV、MPV、交叉型乘用车); 累计结构变化(狭义乘用车轿车、SUV、IPV、交叉型乘用车); 2015年1月-2021年5月新能源乘用车终端月度销量(分地区)内容如下: 更多见资源内

    中心主题-241121215200.pdf

    中心主题-241121215200.pdf

    蓝奏云下载链接与密码整理

    内容概要:本文档提供了多个蓝奏云下载链接及其对应解压密码,帮助用户快速获取所需文件。 适合人群:需要从蓝奏云下载文件的互联网用户。 使用场景及目标:方便地记录并分享蓝奏云上文件的下载地址和密码,提高下载效率。 阅读建议:直接查看并使用提供的链接和密码即可。若遇到失效情况,请尝试联系上传者确认更新后的链接。

    Javaweb仓库管理系统项目源码.zip

    基于Java web 实现的仓库管理系统源码,适用于初学者了解Java web的开发过程以及仓库管理系统的实现。

    Python-文件重命名-自定义添加文字-重命名

    资源名称:Python-文件重命名-自定义添加文字-重命名 类型:windows—exe可执行工具 环境:Windows10或以上系统 功能: 1、点击按钮 "源原文"【浏览】表示:选择重命名的文件夹 2、点击按钮 "保存文件夹"【浏览】表示:保存的路径(为了方便可选择保存在 源文件中 ) 3、功能①:在【头部】添加自定义文字 4、功能②:在【尾部】添加自定义文字 5、功能③:输入源字符 ;输入替换字符 可以将源文件中的字符替换自定义的 6、功能④:自动加上编号_1 _2 _3 优点: 1、非常快的速度! 2、已打包—双击即用!无需安装! 3、自带GUI界面方便使用!

    JDK8安装包,为各位学习的朋友免费提供

    JDK8安装包

    Centos-7yum的rpm包

    配合作者 一同使用 作者地址没有次下载路径 https://blog.csdn.net/weixin_52372189/article/details/127471149?fromshare=blogdetail&sharetype=blogdetail&sharerId=127471149&sharerefer=PC&sharesource=weixin_45375332&sharefrom=from_link

    setup_python_geospatial_analysis.ipynb

    GEE训练教程

    毕业设计&课设_文成公主微信公众号全栈工程,含技术栈、架构及部署流程等内容.zip

    该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过严格测试运行成功才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

    基于springboot交通感知与车路协同系统源码数据库文档.zip

    基于springboot交通感知与车路协同系统源码数据库文档.zip

    基于springboot+vue 雅妮电影票购买系统源码数据库文档.zip

    基于springboot+vue 雅妮电影票购买系统源码数据库文档.zip

    使用 HTML5 实现拖放交互:音效与提示功能的完整实现

    为了更好地理解 HTML5 的拖放功能,我们设计了一个简单有趣的示例:将水果从水果区拖放到购物笼中,实时更新数量和价格,并在所有水果被成功放置后,播放音效并显示提示。

    毕业设计&课设_基于 SSM 的大学生综合成绩测评系统(含信息及数据库脚本,体现系统架构及功能设计).zip

    该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过严格测试运行成功才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

Global site tag (gtag.js) - Google Analytics