hibernate使用HibernateCallback 回调的方法查询SQL时could not execute query--作怪的别名

最近用hibernate3,发现一个奇怪的现象,写的sql语句查询有时报错有时正常。

下面是我用的DAO层的实现类:

 /**
	     * 使用 sql 语句进行操作
	     *
	     * @param sql SQL 查询语句(使用回调函数访问外部变量,必须是final的)
	     * @return List 结果集
	     */
	    public List getListBySQL(final String sql) {
	        System.out.println("BrandStatisticsDao getListBySQL(final String sql )...");
	        List list = (List) getHibernateTemplate().execute(new HibernateCallback() {
	            public Object doInHibernate(Session session) throws HibernateException {
	                Query query = session.createSQLQuery(sql);
	                List list = query.list();
	                return list;
	            }
	        });
	        return list;
	    }

当SQL语句如下时,报错could not execute query:

select sales_detail.id as id,
brand,
money,
sales.sales_no as salesId,
sales_date as salesDate,
goods.id as goodId,
goods_name as goodsName,
num as salesNum,
goods_type as goodsType 
 from goods,sales,sales_detail where goods.id=sales_detail.good_id and sales.sales_no=sales_detail.sales_id;

(这是三张表联合查询的sql语句)。

一开始摸不着头脑,明明在sql里运行没问题,但是用hibernate就死活报错。

将sql语句替换成稍微简单些的检索语句时,可以运行了:

 select brand,
sum(money) as brandSales,
 from goods as g,sales as s,sales_detail as sd 
  where g.id=sd.good_id 
  and s.sales_no=sd.sales_id;

可以返回List集合,里面的值也是正确的。

SQL语句加上分组和区间查询也没问题:

 select brand,
sum(money) as brandSales,
 from goods as g,sales as s,sales_detail as sd 
  where g.id=sd.good_id 
  and s.sales_no=sd.sales_id 
  and sales_date 
  between '2017-01-01' and '2017-01-09' 
  group by brand;

这就让我很郁闷了。到底问题出在哪里呢?继续尝试。

我将检索结果增加到5个,依然正常:

select brand,
money,
goods_name,
num,
goods_type 
  from goods,sales,sales_detail 
  where goods.id=sales_detail.good_id 
    and sales.sales_no=sales_detail.sales_id;

这个问题一直困扰了我很久。按道理说,5个值正常,按条件检索也正常,聚合函数和分组都可以使用,区间查询也支持,那么第一条SQL语句应该也没问题才对啊。

会不会是别名的写法有问题呢?可是在上面使用sum函数时也用了别名,列名和表名都用了别名,并没有出现问题啊。

这个问题我昨天实在解决不了,就搁置了一天干别的去了。

今天做条件查询时,又报错了,实在让我很头疼。还是could not execute query。报错的SQL语句如下:

select brand,
money,
sales_date as salesDate
 from goods,sales,sales_detail where goods.id=sales_detail.good_id and sales.sales_no=sales_detail.sales_id and sales_date between '2017-01-01' and '2017-01-07';
 在SQL命令行里执行,并没有问题。想了半天,又仔细看了看数据库吗,发现除了字符串和数字以外, sales_date是date类型的。虽然取出来是字符串格式,但是存入的时候用的是date类型。date类型实际上是个时间戳,是一个很大的毫秒数。会不会是数据类型不支持导致的错误呢?

于是我尝试将sales_date as salesDate这个结果字段删掉,SQL如下:

select brand,
 money
 from goods,sales,sales_detail where goods.id=sales_detail.good_id and sales.sales_no=sales_detail.sales_id and sales_date between '2017-01-01' and '2017-01-07';

发现可以运行了,不会报错!这真是让我开心坏了,感觉自己好像找到了问题所在。可是新的问题又来了,我要用到时间时该怎么办呢?

正当我带着疑惑继续其他的工作时,又一条SQL出现了could not execute query!!报错的SQL语句如下:

 select sales_detail.id,
  brand,
money,
goods_name
 from goods,sales,sales_detail where goods.id=sales_detail.good_id and sales.sales_no=sales_detail.sales_id;

这就让我又郁闷了。明明没有时间数据了,为什么还是不能执行SQL语句呢?

对比了成功和失败的SQL,突然发现一个问题(也是之前被我忽略了的问题)。同样都是用别名,不报错的SQL语句使用的别名只用在了聚合函数和表上,没有用在原始列名上;而报错的SQL语句,都是拿表的原始列名取了别名。如: sales_detail.id as id,sales_date as salesDate。会不会是这里的问题呢?

于是我尝试着将表内原始列名的别名删掉,SQL语句如下:

select sales_detail.id,
brand,
money,
sales.sales_no,
sales_date,
goods.id,
goods_name ,
num ,
goods_type
 from goods,sales,sales_detail where goods.id=sales_detail.good_id and sales.sales_no=sales_detail.sales_id and sales_date between '2017-01-01' and '2017-01-09' 

  group by brand;

奇迹发生了!终于不报错了,从控制台的输出信息也可以看到能够正确的返回List对象了!果然是别名在作怪啊!


总结:使用HibernateCallback 回调的方法根据SQL或者HQL语句查询时,查询语句中的别名只能加在聚合函数的结果及表名上,不可以加在表的原始列名上。否则就会出现could not execute query无法执行查询语句的错误。

PS:我试着猜测了一下原因,发现hibernate查询以后,数据都是存在对象里(包括实体类或者集合),给表的原始列取别名的意义其实已经不大了。之所以允许给表和聚合函数取别名,应该是为了子查询的需要吧。大概不这么设计的话,SQL可能就无法正确识别语句和条件了。没有精力去深究了,就这样吧。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值