MyBatis查询无数据

目录
  1. 问题
  2. 解决

问题

项目使用了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中包含

1
/*keep orderby*/

注释时,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查询成功。