MyBatis中一对多,导致limit获取条数比预期少(或相等)
一.问题
-
现有classes(班级表)和student(学生表),班级表:学生表 = 1对多 = 1:n
-
在ResultMap中需要使用标签来收集多个student记录。
-
此时,由于连接查询本质是笛卡尔积,因此classes表中每条数据会对student表中的每条数据做判断,又因为sql语句最后有limit关键字,因此会取出一定的条数;
-
我们发现,因为limit的限制,确实是取出了前8条数据。但与我们预期想要的结果不相符。第7,8两条数据是同一个班级,并且如果按照下图这样的搜索结果来做的话,如果cno=21002490这个班级有大于等于3个学生的话,第3个学生不会被查询到,因为只会取前8条数据,尽管第9条数据仍然是cno=21002490这个班级的记录,也不会被搜索到了
-
出现这个问题的原因主要是我们先对classes表与student表进行连接(做笛卡尔积),最后再limit限制连接(笛卡尔积)后的数据。
二.解决方法
解法1:在classes表与student表连接之前,先对classes进行limit限制出条数,然后再与student表进行连接查询。(这边用到的是嵌套子查询)解法2:若先将classes表与student表进行连接,则先获得所有连接条数,再使用in关键字来限制查询出的所有条数。需要使用嵌套子查询+limit查询出限制的条数关键字(id或no字段)
三.总结
- (问题)一对多查询+limit限制条数时,先连接再limit限制,条数会与预期不符。
- (解法1)一对多查询+limit限制条数时,先对一对多中的“一”表限制取出条数,再与“多”表进行连接查询。
- (解法2)一对多查询+limit限制条数时,若想先连接,那么也可以就是,要先拿到所有连接的结果,再通过in关键字进行限制。