在平时开发中Hibernate提供的hql基本能够满足我们的日常需求。但是在有些特殊的情况下,还是需要使用原生的sql,并且希望sql查询出来的结果能够绑定到pojo上。hibernate API中的createSQLQuery  和createQuery接口。
就像在这次的项目中,因为表结构要变化,有个新的需求:
要从一个表中查询极个别的字段并且还有几个是求多条数据的和的,之前一直在使用hibernate的API,使用的都是映射过得对象。
原对象及表结构是这样的:
@Entity
@Table(name="T_BILL_ACCT_ITEM")
@NamedQuery(name="TBillAcctItem.findAll", query="SELECT t FROM TBillAcctItem t")
public class TBillAcctItem implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="ACCT_ITEM_ID")
private long acctItemId; @Column(name="ACCT_ID")
private long acctId; @Column(name="BILLING_CYCLE_ID")
private String billingCycleId; @Column(name="PRODUCT_ID")
private String productId; @Column(name="SERVICE_ID")
private String serviceId; @Column(name="ACCT_ITEM_CODE")
private String acctItemCode; @Column(name="ORIGINAL_AMOUNT")
private int originalAmount; @Column(name="CDR_DISCOUNT")
private int cdrDiscount; @Column(name="ACCT_DISCOUNT")
private int acctDiscount; @Column(name="RECE_AMOUNT")
private int receAmount; @Column(name="REAL_AMOUNT")
private int realAmount; @Column(name="CHARGE_OFF_SOURCE")
private int chargeOffSource; @Column(name="STATE")
private int state;

但是我现在需要查询出来的信息是这样的一个pojo类:(因为int类型的值不能为空,所以我需要将字段定义为 java.long.Integer类型)

public class ProductBillInfo implements Serializable{

    private static final long serialVersionUID = 1L;
private String productId;//产品标识
private String serverId;//服务标示
private Integer realAmount;//实收金额(sum求和)
private Integer receAmount;//应收金额(sum求和)
private int state;//账目状态
private String billingCycle;//账期(月)

因为hibernate要查询的对象是要和表结构一一映射的,现在求和字段这些个是映射不了的, 之前的方法就有问题了。 找了很多看了hibernate的API 找到这个东西。  如下:

大概的使用过程:
        StringBuffer b = new StringBuffer();
//... 省略SQL拼接代码
String sql = b.toString();
SQLQuery query = session.createSQLQuery(sql);
query.addScalar("productId", StandardBasicTypes.STRING);//要查询出来的字段、类型
List<ProductBillInfo> lnfo =query.list();

下面是我用到的查询pojo的方法中的实现:

@SuppressWarnings("unchecked")
public List<ProductBillInfo> findByAcctIdAndCycle1(long acctId,
String cycleBegin, String cycleEnd, int state){ List<String> cycles = DateUtil.getAllCycle(cycleBegin, cycleEnd);
StringBuffer buf = new StringBuffer();
buf.append("select t.PRODUCT_ID as productId , t.SERVICE_ID as serviceId ," +
"sum(t.REAL_AMOUNT) as realAmount ,sum(t.RECE_AMOUNT) as receAmount ," +
"t.STATE as state ,t.BILLING_CYCLE_ID as billingCycleId " +
" from T_BILL_ACCT_ITEM t where t.STATE= '" + state + "' AND t.ACCT_ID='" + acctId + "' AND t.BILLING_CYCLE_ID in (");
StringBuffer bf = new StringBuffer();
for(String id : cycles){
if(bf.toString().equals("")){
bf.append("'"+id+"'");
} else{
bf.append(","+"'"+id+"'");
}
}
buf.append(bf.toString());
buf.append(") GROUP BY t.PRODUCT_ID,t.BILLING_CYCLE_ID,t.SERVICE_ID"); SQLQuery query = getSession().createSQLQuery(buf.toString());
query.addScalar("productId", StandardBasicTypes.STRING);
query.addScalar("serviceId", StandardBasicTypes.STRING);
query.addScalar("realAmount", StandardBasicTypes.INTEGER);
query.addScalar("receAmount", StandardBasicTypes.INTEGER);
query.addScalar("state", StandardBasicTypes.INTEGER);
query.addScalar("billingCycleId", StandardBasicTypes.STRING); query.setResultTransformer(Transformers.aliasToBean(ProductBillInfo.class));
List<ProductBillInfo> lnfo =query.list();
return lnfo;
}

注:示例中addScalar及setResultTransformer很关键,我在使用的时候还报了一个错(原因是在实体中需要有一个无参构造函数),否则错误如下:

org.hibernate.HibernateException: Could not instantiate resultclass:com.eastelsoft.framework.formbean.interfaceBean.ProductBillInfo
还需要说明的一点是
query.addScalar("deviceId", Hibernate.STRING);  ,老版本的使用的数据的类型都是 org.hibernate.type包下面的,
新版本的是在:org.hibernate.type.StandardBasicTypes包下面的
并且在语法中要使用到in(‘’、‘’、‘’)的语法,于是写了下面的一个拼接小方法:
public static void main(String[] args) {
List<String> c = new ArrayList<String>();
c.add("1");c.add("2");c.add("3");
StringBuffer bf = new StringBuffer();
for(String id : c){
if(bf.toString().equals("")){
bf.append("'"+id+"'");
} else{
bf.append(","+"'"+id+"'");
}
}
System.out.println(bf.toString());
}

打印结果是:     '1','2','3'   

使用StringBuffer拼接到原生的sql语句中

hibernate使用setResultTransformer()将SQL查询结果放入集合中的更多相关文章

  1. 在查询时将查询条件放入Session中,导出时直接根据qpniRGaFiler取查询条件即可

    在查询时将查询条件放入Session中,导出时直接根据qpniRGaFiler取查询条件即可

  2. java集合-把商品放入集合中调用(新手)

    //创建的一个包名. package qige; //导入的一个包.import java.util.*; //定义一个类.public class Ipcs { //公共静态的主方法. public ...

  3. java通过文件路径读取该路径下的所有文件并将其放入list中

    java通过文件路径读取该路径下的所有文件并将其放入list中   java中可以通过递归的方式获取指定路径下的所有文件并将其放入List集合中.假设指定路径为path,目标集合为fileList,遍 ...

  4. 用SQL查询方式显示GROUP BY中的TOP解决方法[转]

    用SQL查询方式显示GROUP BY中的TOP怎样用一个SQL语句来显示 分组后每个组的前几位 比如把一个学校所有学生的成绩按班级分组,再显示每个班级前五名的信息. 班级     学生   成绩 一班 ...

  5. tuple放入dict中

    tuple放入dict中是否可以正常运行 # 将tuple放入dict中 a = ('AI','Kobe','Yao') b = ('AI',['Kobe','Yao']) dict1 = {'a': ...

  6. 用MT.exe将exe中的manifest文件提取出来和将manifest文件放入exe中

     前一种方法是将manifest文件放入exe中,但是要记得需要在工程中设置 这样的话exe中就不存在manifest了,在debug目录下就会看到相应的manifest文件.后者是将exe中的man ...

  7. pyqt字符串分离开,放入列表中

    string1 = ''''' the stirng Has many line In THE fIle ''' list_of_string = string1.split() print list ...

  8. .Net中把图片等文件放入DLL中,并在程序中引用

    原文:.Net中把图片等文件放入DLL中,并在程序中引用 [摘要] 有时我们需要隐藏程序中的一些资源,比如游戏,过关后才能看到图片,那么图片就必须隐藏起来,否则不用玩这个游戏就可以看到你的图片了,呵呵 ...

  9. MyBatis 遍历数组放入in中

    必须要遍历出数组的值放入in中 如果直接将"'2','3','4','5','6','7','8'" 字符串放入in中,只会查出 inv_operate_type的值为2的数据,因 ...

随机推荐

  1. NYOJ15-括号匹配(二)-区间DP

    pid=15">http://acm.nyist.net/JudgeOnline/problem.php? pid=15 dp[i][j]表示从i到j至少须要加入多少个括号才干满足匹配 ...

  2. hdu5304 Eastest Magical Day Seep Group&#39;s Summer 状压dp+生成树

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5304 16个点的无向图,问能生成多少个n条边的连通图.(即多一条边的树) 先n^3 * 2^n 枚举全部的 ...

  3. 【剑指offer】扑克牌的顺子

    个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想測測自己的手气,看看能不能抽到顺子,假设抽到的话,他决定去买体育彩票,嘿嘿! ."红心A,黑桃3,小王,大王,方片 ...

  4. 注册Azure AD 应用程序

    作者:陈希章 发表于2017年3月22日 在此前的文章中,我给大家介绍了分别用Graph 浏览器以及第三方工具(POSTMAN)快速体验Microsoft Graph的功能,其中有一个重要的环节就是, ...

  5. IEEE Trans 2007 Signal Recovery From Random Measurements via OMP

    看了一篇IEEE Trans上的关于CS图像重构的OMP算法的文章,大部分..看不懂,之前在看博客的时候对流程中的一些标号看不太懂,看完论文之后对流程有了一定的了解,所以在这里解释一下流程,其余的如果 ...

  6. Java的流程控制结构,细节详解

    位运算符 &与 |或 ^异或 <<左移 >>右移 >>>无符号右移  ~取反 注意:位运算是针对整数运算的 int i = 6,j = 10; 方式一 ...

  7. Hue上的Oozie构建工作流和定时任务步骤

    Oozie是什么? Oozie是一种Java Web应用程序,它运行在Java servlet容器--即Tomcat--中,并使用数据库来存储以下内容: 工作流定义 当前运行的工作流实例,包括实例的状 ...

  8. 【java】获取当前环境属性及编码乱码示例

    package 字符编码; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; impo ...

  9. HTML状态码大全(301,404,500等)

    HTML状态码大全(301,404,500等)HTML状态码大全(301,404,500等)HTML状态码大全(301,404,500等)HTML状态码大全(301,404,500等) 这些状态码被分 ...

  10. Visual Studio 2017 : client version 1.22 is too old

    使用Vs2017 编译 eShopOnContainers-ServicesAndWebApps 时,报了错误: Microsoft.DotNet.Docker.CommandLineClientEx ...