问题
项目使用了Mybatis-PageHelper,项目有业务需要在指定范围(指定时间范围指定条数)内的数据里做查询,因此有了下面的Mybatis代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <select id="list" resultMap="TotalResultMap" parameterType="com.yl.dao.query.YlCaseListQuery"> select allData.* from ( select yce.*,yc.patient_id from yl_a yce left join yl_c yc on yc.id = yce.case_id where 1=1 <if test="ctimeStart!=null"> and DATE_FORMAT(yce.ctime, '%Y-%m-%d') <![CDATA[>=]]> DATE_FORMAT(#{ctimeStart}, '%Y-%m-%d') </if> <if test="ctimeEnd!=null"> and DATE_FORMAT(yce.ctime, '%Y-%m-%d') <![CDATA[<=]]> DATE_FORMAT(#{ctimeEnd}, '%Y-%m-%d') </if> order by yce.ctime desc limit 200) as allData <where> <if test="patientId!=null"> and allData.patient_id = #{patientId} </if> </where> </select>
|
当不使用patientId查询条件时没有问题,查询能正常查询出200条记录。
但添加查询条件后数据可能查询不出来。当时的情况是测试环境测试了一下可以查询,生产环境没有结果。
解决
当前看了好久没找到问题,后来打开生产环境的sql打印。发现mybatis-pagehelper在select count(0)查询时会默认将sql语句中的order by去掉,也就是count查询时上面的子查询没有order by排序但有limit 200, 有无排序的数据集是不一样的,此时查询出来的新的数据集确实没有包含对应patientId记录的话,count(0)值就是0。
因为查询前会count查询一下判断是否存在数据,再决定是否进行实际查询,count结果为0就直接导致了查询无数据。
查看Mybatis-PageHelper文档,在SQL中包含
注释时,count查询时不会移出order by。
因此更新代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <select id="list" resultMap="TotalResultMap" parameterType="com.yl.dao.query.YlCaseListQuery"> select allData.* from ( select yce.*,yc.patient_id from yl_a yce left join yl_c yc on yc.id = yce.case_id where 1=1 <if test="ctimeStart!=null"> and DATE_FORMAT(yce.ctime, '%Y-%m-%d') <![CDATA[>=]]> DATE_FORMAT(#{ctimeStart}, '%Y-%m-%d') </if> <if test="ctimeEnd!=null"> and DATE_FORMAT(yce.ctime, '%Y-%m-%d') <![CDATA[<=]]> DATE_FORMAT(#{ctimeEnd}, '%Y-%m-%d') </if> order by yce.ctime desc limit 200) as allData /*keep orderby*/ <where> <if test="patientId!=null"> and allData.patient_id = #{patientId} </if> </where> </select>
|
此时,count查询是order by没被删除,根据patientId查询成功。