hibernate使用setResultTransformer()将SQL查询结果放入集合中

在平时开发中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语句中

原文地址:https://www.cnblogs.com/daweige/p/8289174.html

时间: 2024-08-08 05:25:31

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

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

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

[摘要] 有时我们需要隐藏程序中的一些资源,比如游戏,过关后才能看到图片,那么图片就必须隐藏起来,否则不用玩这个游戏就可以看到你的图片了,呵呵. 本文就讲述了如何把文件(比如图片,WORD文档等等) 隐藏到DLL中,然后在程序中可以自己根据需要导出图片进行处理. 注:本站原创,转载请注明本站网址:http://www.beinet.cn/blog/ [全文] 第1步:我们要生成一个资源文件,先把要隐藏的文件放入到这个资源文件中 (资源文件大致可以存放三种数据资源:字节数组.各种对象和字符串) 首

maven项目放入tomcat中找不到jar包

maven项目放入tomcat中时,总是报错,而且这些jar都是真实存在的,错误如下: maven eclipse tomcat java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener 解决办法:

OC--有这么一个 整数 123456789,如何将这个整数的每一位数,从末位开始依次放入数组中,并遍历 倒序输出字符串

有这么一个 整数 123456789,如何将这个整数的每一位数,从末位开始依次放入数组中,并遍历 1 NSInteger num=123456789; 2 NSString *str=[[NSString alloc]initWithFormat:@"%ld",num ]; 3 NSMutableArray *arr=[NSMutableArray array]; 4 for(NSInteger i=str.length-1;i>=0;i--){ 5 //从末位开始截取字符串,每

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

string1 = ''''' the stirng Has many line In THE fIle ''' list_of_string = string1.split() print list_of_string #将字符串分离开,放入列表中 print '*'*50 def case_insensitive_sort(liststring): listtemp = [(x.lower(),x) for x in liststring] listtemp.sort() return [x

MyBatis 遍历数组放入in中

必须要遍历出数组的值放入in中 如果直接将"'2','3','4','5','6','7','8'" 字符串放入in中,只会查出 inv_operate_type的值为2的数据,因为myBatis将这个判断成了字符串,逗号失效了.

【算法与数据结构实战】线性表操作-实现A并B,结果放入A中

//数据结构与算法基础题1:线性表操作,实现A并B,结果放入A中 #include "stdafx.h" #include <iostream> #include <string> #include <vector> #include <algorithm> #pragma warning(disable:4996) using namespace std; int main() { vector<int> set_A, se

python:将一个数逆序列放入列表中,例如1234 => [4,3,2,1]

今天有小伙伴问题了一个题:将一个数逆序列放入列表中,例如1234 => [4,3,2,1].要求用递归实现.粗看这个题的话,很容易实现的:int 转成str ,然后倒序,再把列表里面的 str 转成 int.再来看递归:一般递归里面都是要有个结束条件,这个题的结束条件也很好确定,它是这个列表,列表有长度,每次pop 一个 元素,直到列表的长度 等于 0 的时候,那就可以结束了.先来看个普通的递归方法: def reverse_order_list1(lst:list, tmp=[]): if l

python:递归将一个数逆序列放入列表中

接上回:将一个数逆序列放入列表中,例如1234 => [4,3,2,1].要求用递归实现.不允许使用str和map,那就直接用除法和取模来做: lst = [] def int_to_list(tmp:int): division_number = tmp / 10 demo_number = tmp % 10 tmp3 = division_number - demo_number / 10 if tmp3: int_to_list(int(tmp3)) lst.append(demo_num