在你所描述的场景中,如果 a
表有 15 条数据,经过 LEFT JOIN
之后查询结果是 20 条数据,这说明 LEFT JOIN
产生了重复记录。如果你希望分页是基于 a
表的记录数而不是 LEFT JOIN
后的总记录数,那么需要确保每一页的数据量是基于 a
表的记录数,而不是 LEFT JOIN
后的总记录数。
为了实现这一点,可以通过以下步骤:
- 获取
a
表的分页记录:首先进行a
表的分页查询,以确定分页逻辑。 - 基于分页后的
a
表记录进行LEFT JOIN
查询:使用获取到的a
表分页记录的 ID 列表进行LEFT JOIN
查询,从而避免多余的记录。
实现步骤
1. 在 Mapper 中编写 SQL 查询
你需要两个查询:一个是仅查询 a
表的分页数据,另一个是基于 a
表 ID 列表的 LEFT JOIN
查询。
仅查询 a
表的分页数据
<select id="selectAPaged" resultType="YourAType">
SELECT a.*
FROM tableA a
<!-- 其他条件 -->
</select>
基于 a
表 ID 列表的 LEFT JOIN
查询
<select id="selectWithLeftJoinByIds" resultType="YourResultType">
SELECT a.*, b.*
FROM tableA a
LEFT JOIN tableB b ON a.id = b.a_id
WHERE a.id IN
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
</select>
2. 在 Service 层实现分页查询逻辑
在 Service 层中,首先获取 a
表的分页数据,然后基于这些数据获取详细信息。
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class YourService {
@Autowired
private YourMapper yourMapper;
public PageInfo<YourResultType> getPagedResults(int pageNum, int pageSize) {
// 设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 查询表 a 的分页数据
List<YourAType> aPagedResults = yourMapper.selectAPaged();
PageInfo<YourAType> pageInfoA = new PageInfo<>(aPagedResults);
// 获取表 a 的 ID 列表
List<Integer> aIds = aPagedResults.stream().map(YourAType::getId).collect(Collectors.toList());
// 基于表 a 的 ID 列表查询包含 LEFT JOIN 的详细数据
List<YourResultType> detailedResults = yourMapper.selectWithLeftJoinByIds(aIds);
// 创建 PageInfo 对象来返回分页信息和详细结果
PageInfo<YourResultType> pageInfo = new PageInfo<>(detailedResults);
pageInfo.setTotal(pageInfoA.getTotal());
pageInfo.setPageNum(pageInfoA.getPageNum());
pageInfo.setPageSize(pageInfoA.getPageSize());
pageInfo.setPages(pageInfoA.getPages());
return pageInfo;
}
}
3. 在 Controller 层调用 Service 方法
在 Controller 层中调用 Service 方法并返回结果:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.github.pagehelper.PageInfo;
@RestController
@RequestMapping("/yourApi")
public class YourController {
@Autowired
private YourService yourService;
@GetMapping("/getPagedResults")
public PageInfo<YourResultType> getPagedResults(@RequestParam int pageNum, @RequestParam int pageSize) {
return yourService.getPagedResults(pageNum, pageSize);
}
}
总结
通过这种方法,你可以确保分页逻辑是基于 a
表的记录数,而 LEFT JOIN
后的结果仅基于当前页的 a
表记录。这可以避免因为 LEFT JOIN
产生的重复记录而导致的分页不准确问题。