MyBatisPlus一对多分页查询处理主表子表查询条件

业务上遇到了一个问题,需要进行一对多的分页查询,同时还存在对主表和子表的条件限制,经过查询后参考其他人的经验进行了处理,记录如下.

其中的坑就是正常的分页查询下,一对多的分页是错误的,它不会按主表的查询条数来返回数量,而是把主表-一个子表记录这样的形式来返回数量,导致返回数量跟预期不符.例如一个MiddleWareDto对象里nodes大小为5,应该返回数量是1,结果它会返回5.
这里使用子查询的方式来避免这个坑.

各实体类如下

public class MiddleWareDto implements Serializable {
	//主表的id
    private Integer groupId;
	....................
	//其他属性
	....................
    private List<MiddleWareNodeDto> nodes;

}
public class MiddleWareNodeDto {
	//对应主表中的groupId
    private Integer groupId;
    ......................
	//其他属性
}

Service

 @Override
    public CommResponse<PageResult<MiddleWareDto>> list(MiddleWareReq req) {
        Page<MiddleWareDto> page = new Page<>(req.getPageIndex(), req.getPageSize());
        IPage<MiddleWareDto> list = middleWareGroupMapper.getList(page, req);
   		.......................
    }

Mapper

mapper方法声明如下,包括主查询和子查询方法,Service中调用的是主查询方法

IPage<MiddleWareDto> getList(@Param("page") Page<MiddleWareDto> page, @Param("req") MiddleWareReq req);

List<MiddleWareNodeDto> getNodeList(Integer groupId);

xml文件编写
主查询如下:

	<select id="getList" resultMap="MiddleWareDtoResultMap">
        SELECT * FROM MIDDLE_WARE_GROUP  w
        WHERE 1=1
        <if test="req.groupName != null and req.groupName != ''">
            AND w.group_name like '%'+#{req.groupName}+'%'
        </if>
        <if test="req.type != null and req.type != ''">
            ANd w.type=#{req.type}
        </if>
        <if test="req.hostId != null and req.hostId > 0">
            AND w.group_id IN (SELECT a.group_id FROM MIDDLE_WARE_GROUP a,MIDDLE_WARE_NODE b WHERE a.group_id = b.group_id AND b.host_id=#{req.hostId})
        </if>
        <if test="req.ip !=null and req.ip != ''">
            AND w.group_id IN (SELECT a.group_id FROM MIDDLE_WARE_GROUP a,MIDDLE_WARE_NODE b WHERE a.group_id = b.group_id AND b.ip_port LIKE '%'+#{req.ip}+'%')
        </if>
    </select>

可以看到主查询主要是查询的主表,查询结果通过resultMap进行了映射,就是在这里调用进行子查询.
这里前两个查询条件是对主表的限制,直接写即可;后两个条件是对子表的限制,没法直接实现,只能通过这种间接的形式来实现.

我们看一下resultMap的具体内容:

 <resultMap id="MiddleWareDtoResultMap" type="com.montnets.monitor.pcweb.entity.dto.MiddleWareDto">
        <id property="groupId" column="group_id"/>
        <result property="groupName" column="group_name"/>
		.......其他属性的映射
		
        <collection property="nodes" ofType="com.montnets.monitor.pcweb.entity.dto.MiddleWareNodeDto"
                    select="getNodeList" column="group_id" javaType="ArrayList">
            <result property="groupId" column="group_id"/>
         	......其他属性映射
        </collection>
    </resultMap>

这里面 collection 指的就是一对多的实现,
property 指主对象中的属性,即我们的list
ofType 指list中的类型
select 子查询语句
column 子查询的参数
javaType 子查询集合的类型,即我们的nodes的类型

最后看看我们的子查询语句

<select id="getNodeList" resultType="com.montnets.monitor.pcweb.entity.dto.MiddleWareNodeDto">
        SELECT * FROM MIDDLE_WARE_NODE n
        WHERE n.group_id = #{groupId}
    </select>

总结一下:通过resutlMap映射的方式调用子查询,实现一对多的查询,使用自带的page分页实现,使用了间接的限制方式实现了对子表查询条件的查询

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用SpringBoot和MybatisPlus进行多表分页模糊查询时,需要先配置MybatisPlus的分页插件,然后使用MybatisPlus的Wrapper对象进行多表查询,并且使用Page对象进行分页。 以下是一个示例代码,假设我们有两个实体类:User和Order,其中User有一个关联字段orderId。 ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public Page<User> getUserList(String keyword, Page<User> page) { QueryWrapper<User> userWrapper = new QueryWrapper<>(); userWrapper.like("user_name", keyword).or().like("user_email", keyword); // 模糊查询用户名称和邮箱 QueryWrapper<Order> orderWrapper = new QueryWrapper<>(); orderWrapper.like("order_no", keyword); // 模糊查询订单号 userWrapper.inSql("order_id", SqlHelper.getSqlParser().select("id").from(Order.class).where(orderWrapper).getSql()); // 使用子查询查询关联的订单信息 return userMapper.selectPage(page, userWrapper); } } ``` 在上面的示例代码中,我们首先使用MybatisPlus的QueryWrapper对象进行模糊查询,然后使用inSql方法将查询到的订单id作为子查询的参数,查询关联的订单信息。最后,我们使用MybatisPlus的selectPage方法进行分页查询。 需要注意的是,在使用MybatisPlus的分页插件时,我们需要在配置文件中添加以下配置: ```yaml mybatis-plus: page: helper-dialect: mysql reasonable: true ``` 其中,helper-dialect表示数据库方言,reasonable表示是否启用合理化分页

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值