ShardingSphere + Pagehelper 组合sql查询中包含 DISTINCT GROUP BY 等关键字和聚合函数时,导致报错

  

Pagehelper 中配置说明
  1. params:为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero

  2. supportMethodsArguments:支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest


Pagehelper 配置 supportMethodsArguments 为true ,当sql传入条件中包含 pageNum pageSize 时会自动分页 ,此时如果sql中使用了DISTINCT GROUP BY 等关键字和聚合函数时,Pagehelper会先查询表名为
table_count的总条数的sql,这时ShardingSphere 就会匹配不到对应的分表导致报错

SELECT count(0) FROM (SELECT DISTINCT DATE_FORMAT(dc.content_time, '%Y-%m-%d %H:%i') content_time FROM sys_data_content AS dc
WHERE dc.content_time BETWEEN ? AND ? GROUP BY content_time) table_count
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql

解决 :

Pagehelper 提供了自定义count搜索,在xml文件中加上 方法名 +"_COUNT ",会率先匹配该方法的sql
此时执行的分页sql为
SELECT COUNT(0) FROM sys_data_content AS dc WHERE dc.content_time between #{startTime} and #{endTime} GROUP BY content_time ORDER BY content_time ASC
<select id="findTime" resultType="java.lang.String">
        SELECT DISTINCT
            DATE_FORMAT( dc.content_time, '%Y-%m-%d %H:%i' ) content_time
        FROM
            sys_data_content AS dc
        <where>
            <trim prefixOverrides="AND">
                <if test="startTime != '' and startTime != null and endTime != '' and endTime != null">
                    AND dc.content_time between #{startTime} and #{endTime}
                </if>
            </trim>
        </where>
        GROUP BY
            content_time
        ORDER BY
            content_time ASC
    </select>

    <select id="findTime_COUNT" resultType="java.lang.Long">
        SELECT
            COUNT(0)
        FROM
        sys_data_content AS dc
        <where>
            <trim prefixOverrides="AND">
                <if test="startTime != '' and startTime != null and endTime != '' and endTime != null">
                    AND dc.content_time between #{startTime} and #{endTime}
                </if>
            </trim>
        </where>
        GROUP BY
            content_time
        ORDER BY
            content_time ASC
    </select>

 

posted @ 2023-05-17 16:17  Sea_wxx  阅读(372)  评论(0编辑  收藏  举报