主题:BeetlSql分页查询Bug

snx_me 2019年09月20日 75

不方便贴图,直接说明情况;

如果我的分页有groupby语句。

在使用PageQuery查询的时候。

SELECT
  @pageTag(){
    stat.id,
    stat.ip 
  @}
FROM 
  stat 
WHERE   
  1 = 1    
  @if(!isEmpty(market)&& market != ""){
    AND stat.market = #market#     
  @}  
GROUP BY  
  stat.ip
order by     
   market_visit_time desc

这个查询,就是普普通通的一个聚合查询了

但是 beetlsql会将pageTag 代码块替换为 count(1);

结果会导致聚合ip查出多条结果;生成的sql如下:

SELECT   
  count(1)
FROM 
  stat 
WHERE   
  1 = 1    
  @if(!isEmpty(market)&& market != ""){
    AND stat.market = #market#     
  @}  
GROUP BY    
  stat.ip
order by     
   market_visit_time desc

期望生成的sql:

select count(1) from (
SELECT   
  1
FROM 
  stat 
WHERE   
  1 = 1    
  @if(!isEmpty(market)&& market != ""){
    AND stat.market = #market#     
  @}  
GROUP BY   
  stat.ip
order by     
   market_visit_time desc) t

翻了很久文档也没找到解决方案。

最后写了2条sql才将功能实现。

darren 2019年09月21日

貌似现在是不支持聚合的自动分页的,的确需要手写。

简单点的操作是将公共部分提取成sql片段,然后使用use函数分别写查询记录和查询条数的sql,然后在service层调用两个查询方法 或者 在mapper层使用java8的default方法封装一个独立的page查询的方法,分别调用两个sql查询,再将组装的结果返回。


@闲·大赋 感觉可以扩展sqlManage的pageQuery方法

        String sqlCountId = sqlId.concat("$count");
        boolean hasCountSQL = this.sqlLoader.exist(sqlCountId);
        if (query.getTotalRow() == -1) {
            try {
                if (hasCountSQL) {
                    totalRow = this.selectUnique(sqlCountId, root, Long.class);
                } else {
                    root.put(PageQuery.pageFlag, PageQuery.pageObj);
                    //这里 可以生成嵌套的分页count查询
                    totalRow = this.selectUnique(sqlId, root, Long.class);
                }

当用户需要查询有聚合或者distinct等sql的分页时,无需在原始的sql上面写 @pageTag 以及#page("xxx")#,让beetl自动生成包裹整个sql这样的嵌套count查询,此时上例的hasCountSQL为false,自动使用 select count(1) from 来包裹一下原始的sql

andnnl 2019年09月25日

目前的解决办法就是嵌套查询,获取总行数,希望能够不嵌套

可以参考如下

select syear,smonth,sday,
    @pageTag(){
        #use("cols")#
    @}
    from TBL_MMS_REPORT where 1=1 
    group by syear,smonth,sday
	@pageIgnoreTag(){
		order by syear desc,smonth desc,sday desc
	@}

第一次查询总行数的时候,生成的SQL会返回多列,希望能处理这个多列中带回的总行数,只读aaa参数即可。这样就不用嵌套查询了。

select syear,smonth,sday,count(1) aaa from TBL_MMS_REPORT where 1=1 
    group by syear,smonth,sday
andnnl 2019年09月25日

额。不对,会返回多行多列。还是得嵌套一下。

闲大赋 2019年09月25日

是的,不好做,beetlsql 翻页本来是用俩个sql语句完成,pageQuery会查询sqlId和sqlId+'$count"。俩个语句

pageTag用于简化,但对于groupby 确实容易误导。目前也想不出好办法