最近遇到一个烦人的问题,费了不少时间才解决出来,把它贴出来分享!
问题如下:
产品对象TProduct和标签对象TTag,是通过中间表连接的双向多对多关联关系,要求是列出所有的标签,按标签的使用次数倒排序(即哪个标签关联的产品数最多,哪个标签放在第一个).
省略掉pojo的代码,其映射文件如下:
----------------------TProduct.hbm.xml-----------------------
------------------------TTag.hbm.xml-------------------------
条件很简单,就这么多,要求列出所有的标签,按照其关联的产品的数量倒排序(即标签使用次数倒排序),难就难在其排序上,
这样的写法肯定是不行的,生成的sql语句是错误的!
正确的写法如下:
问题如下:
产品对象TProduct和标签对象TTag,是通过中间表连接的双向多对多关联关系,要求是列出所有的标签,按标签的使用次数倒排序(即哪个标签关联的产品数最多,哪个标签放在第一个).
省略掉pojo的代码,其映射文件如下:
----------------------TProduct.hbm.xml-----------------------
xml 代码
- <id name="id" type="integer" column="id">
- <generator class="native"/>
- id>
- <property name="name" column="name" type="string" not-null="false" length="50"/>
- <set name="tags" table="TableLink_Product_Tags" order-by="tagId">
- <key column="productId"/>
- <many-to-many column="tagId" class="TTag"/>
- set>
------------------------TTag.hbm.xml-------------------------
xml 代码
- <id name="id" type="integer" column="id">
- <generator class="native" />
- id>
- <property name="name" column="name" type="string" />
- <set name="products" table="TableLink_Product_Tags">
- <key column="tagId" />
- <many-to-many class="TProduct" column="productId" />
- set>
条件很简单,就这么多,要求列出所有的标签,按照其关联的产品的数量倒排序(即标签使用次数倒排序),难就难在其排序上,
java 代码
- select t from TTag as t order by t.products.size desc
这样的写法肯定是不行的,生成的sql语句是错误的!
正确的写法如下:
java 代码
- select a from TProduct as t inner join t.tags as a group by a.id,a.name order by count(t.id) desc
这种写法才是正确的.
这个问题看起来简单,写起来麻烦,如果用sql写,我觉得还是比较好写的,而用hql来写,感觉有点抽象,大家还有别的实现方法么?
此外,还发现了一个sql语句的小特点,这个不能算问题,只是比较容易产生错误!
看这个sql语句:
select * from Table_Tag where id in(8,7,6,3,9)
这样得出的结果其顺序又会如何呢?
其实这么写的结果的显示顺序并非:8,7,6,3,9
应该是:3,6,7,8,9
所以为了追求结果排序,where id in()这个想法是不可取的