hibernate使用HibernateCallback回调的方法查询SQL时couldnotexecutequery--作怪的别名
hibernate使用HibernateCallback回调的方法查询SQL时couldnotexecutequery--作怪的别名,最近用hibernate3,发现一个奇怪的现象,写的sql语句查询有时报错有时正常。
下面是我用的DAO层的实现类:
当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可能就无法正确识别语句和条件了。没有精力去深究了,就这样吧。
下一篇: js遮罩弹出层