业务上遇到了一个问题,需要进行一对多的分页查询,同时还存在对主表和子表的条件限制,经过查询后参考其他人的经验进行了处理,记录如下.
其中的坑就是正常的分页查询下,一对多的分页是错误的,它不会按主表的查询条数来返回数量,而是把主表-一个子表记录这样的形式来返回数量,导致返回数量跟预期不符.例如一个MiddleWareDto对象里nodes大小为5,应该返回数量是1,结果它会返回5.
这里使用子查询的方式来避免这个坑.
public class MiddleWareDto implements Serializable {
//主表的id
private Integer groupId;
....................
//其他属性
....................
private List nodes;
}
public class MiddleWareNodeDto {
//对应主表中的groupId
private Integer groupId;
......................
//其他属性
}
@Override
public CommResponse> list(MiddleWareReq req) {
Page page = new Page<>(req.getPageIndex(), req.getPageSize());
IPage list = middleWareGroupMapper.getList(page, req);
.......................
}
mapper方法声明如下,包括主查询和子查询方法,Service中调用的是主查询方法
IPage getList(@Param("page") Page page, @Param("req") MiddleWareReq req);
List getNodeList(Integer groupId);
xml文件编写
主查询如下:
可以看到主查询主要是查询的主表,查询结果通过resultMap进行了映射,就是在这里调用进行子查询.
这里前两个查询条件是对主表的限制,直接写即可;后两个条件是对子表的限制,没法直接实现,只能通过这种间接的形式来实现.
我们看一下resultMap的具体内容:
.......其他属性的映射
......其他属性映射
这里面 collection 指的就是一对多的实现,
property 指主对象中的属性,即我们的list
ofType 指list中的类型
select 子查询语句
column 子查询的参数
javaType 子查询集合的类型,即我们的nodes的类型
最后看看我们的子查询语句
总结一下:通过resutlMap映射的方式调用子查询,实现一对多的查询,使用自带的page分页实现,使用了间接的限制方式实现了对子表查询条件的查询