Hibernate 的SQLQuery接口addScalar方法 (原生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类:

public class ProductBillInfo implements Serializable{

	private static final long serialVersionUID = 1L;
	private String productId;//产品标识
	private String serverId;//服务标示
	private int realAmount;//实收金额(sum求和)
	private int 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> findByAcctIdAndCycle(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");

		System.out.printf(buf.toString());
		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);
		List<ProductBillInfo> lnfo =query.list();
		return lnfo;
	}

需要说明的一点是

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语句中

时间: 2024-10-13 22:00:14

Hibernate 的SQLQuery接口addScalar方法 (原生sql查询)的相关文章

Hibernate 的原生 SQL 查询

Hibernate除了支持HQL查询外,还支持原生SQL查询.         对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口.该接口是Query接口的子接口.         执行SQL查询步骤如下:         1.获取Hibernate Session对象         2.编写SQL语句         3.通过Session的createSQLQuery方法创建查询对象         4.调用SQ

Hibernate SQLQuery 原生SQL 查询及返回结果集处理-1

第一篇:官方文档的处理方法,摘自官方 在迁移原先用JDBC/SQL实现的系统,难免需要采用hibernat native sql支持. 1.使用SQLQuery hibernate对原生SQL查询执行的控制是通过SQLQuery接口进行的. Session.createSQLQuery(); 1.1标量查询 最基本的SQL查询就是获得一个标量(数值)的列表. sess.createSQLQuery("SELECT * FROM CATS").list(); sess.createSQL

hibernate使用原生SQL查询返回结果集的处理

今天没事的时候,看到公司框架里有一个用原生SQL写的函数,说实在以前自己也干过这事,但好久都没有用,都忘得差不多了,现在基本都是用的hql语句来查询结果.hibernate中使用createSQLQuery拉来来实现SQL语句的查询,具体用法:session.createSQLQuery(sql),对于用SQL返回的结果集是一个什么样的结果集都毫无记忆.自己查了下,才知道,原来是返回一个Object类型数组的list集合,而其中Object类型的数组里的值则与sql语句中的查询项相对应,如果是s

使用hibernate原生sql查询,结果集全为1的问题解决

问题如下: String sqlTest ="select summary,summaryno from F_Summary"; List<Map<Object, Object>> listTest = this.getService().getListBySql(sqlTest); for (Map<Object, Object> m : listTest) { for (Object k : m.keySet()) { System.out.pr

hibernate中SQLQuery的addEntity()方法

如果使用原生sql语句进行query查询时,hibernate是不会自动把结果包装成实体的.所以要手动调用addEntity(Class class)等一系列方法. 如session.createSQLQuery(sql).addEntity(Class class);注意hibernate3.0.5不支持,单个参数的addEntity方法 另外,hibernate3.2可以对原生sql 查询使用ResultTransformer.这会返回不受Hibernate管理的实体. session.cr

Hibernate原生SQL查询多表关联,SQL语句要注意的问题

Hibernate原生SQL查询多表关联,SQL语句要注意的问题 @for&ever 2009-9-4 系统环境: MySQL5.1 Hibernate3.3 有如下的假定: 实体类 Question 和 Answer分别对应数据表 question 和answer. 并且表 question 和answer 的字段大部分都一样,字段数目也一样. 执行如下的操作: 1> 使用hibernate 使用原生SQL查询, Query q = session.createSQLQuery(sql).

Hibernate5.2之原生SQL查询

Hibernate5.2之原生SQL查询 一. 介绍  在上一篇博客中笔者通过代码的形式给各位读者介绍了Hibernate中最重要的检索方式--HQL查询.在本博文中笔者将向各位读者介绍Hibernate中的原生SQL查询,虽为原生SQL查询,但是笔者认为Hibernate在针对不同的数据库在分页语句的处理上做的很不错,我们不用去关心使用的是何种的数据库.本博文会沿用<Hibernate5.2之HQL查询>中的POJO类和配置文件,请各位看官在阅读本博文之前请先阅读该文章,本篇文章会将HQL中

Hibernate 使用原生SQL查询无法使用别名问题

最近遇到一个问题就是Hibernate在使用原生SQL进行多表联合查询别名的问题,一直报错,说是找不到某列,经过向别人咨询最后得出了解决方案 需要向数据库连接字符串中加入属性,具体如下 common.db.driverClassName=com.mysql.jdbc.Driver common.db.url=jdbc:mysql://10.10.11.8:3306/cm_mini_1?useOldAliasMetadataBehavior=true common.db.username=user

springDataJPQL实现增删改查及分页,原生sql查询,根据方法命名规则实现查询

一.使用方法 1.在dao中定义开一个方法,使用方法的参数设置jpql,并且使用方法的返回值接受查询结果,在方法上添加@query注解,在注解中写jpql语句进行增删改查,测试 2.使用原生的sql语句:dao中定义一个方法,在方法中添加@query注解,在注解中添加原生sql语句,并且添加一个属性:nativeQuery=true,测试 3.方法命名规则查询: 通过以肯定的规则,定义一个方法,框架本身就可以根据方法名生成一块个sql语句进行查询,规则: 1.必须以findBy开头 2.查询某个