如何在Spring Boot中结合jQuery DataTables与PagingAndSorting Repository
问题解答
先明确你的核心疑问
DataTables开启**服务端模式(serverSide: true)**后,完全是按需加载数据的——只有在点击翻页按钮、切换每页显示条数、执行搜索、触发排序操作时,才会向后端发起AJAX请求,仅获取当前需要的那一页数据,不会一次性加载全量数据,完美匹配你说的10万条数据只加载目标页的需求。
结合Spring PagingAndSortingRepository的实现方案
1. 前端DataTables配置(关键部分)
开启服务端模式,指定后端接口地址,配置列映射,让DataTables自动传递分页、排序、搜索参数:
$(document).ready(function() { $('#dataTable').DataTable({ serverSide: true, // 必须开启服务端模式 ajax: { url: '/api/data/list', // 后端接口地址 type: 'POST', contentType: 'application/json', data: function(d) { return JSON.stringify(d); } }, columns: [ { data: 'id' }, { data: 'name' }, { data: 'createTime' }, // 其他业务列映射 ], order: [[2, 'desc']], // 默认排序列(对应columns数组下标)和方向 pageLength: 10, // 默认每页10条 lengthMenu: [10, 20, 50] // 可选每页条数 }); });
DataTables会自动传递的核心参数:
draw: 客户端请求标识,后端需原样返回start: 数据起始索引(比如第2页、每页10条的话,start=10)length: 每页条数search[value]: 全局搜索关键词order[0][column]: 排序的列索引(对应columns数组的下标)order[0][dir]: 排序方向(asc/desc)
2. 后端Spring实现(关键部分)
(1)创建参数接收DTO
用来接收DataTables传递的请求参数:
public class DataTableRequest { private int draw; private int start; private int length; private Search search; private List<Order> order; // 内部类封装搜索、排序子参数 public static class Search { private String value; // getter/setter } public static class Order { private int column; private String dir; // getter/setter } // getter/setter }
(2)Controller层处理请求
调用Repository完成分页查询,返回DataTables要求的格式:
@RestController @RequestMapping("/api/data") public class DataController { @Autowired private DataRepository dataRepository; @PostMapping("/list") public ResponseEntity<DataTableResponse<DataEntity>> getDataList(@RequestBody DataTableRequest request) { // 1. 处理排序:根据列索引匹配对应字段(需和前端columns顺序对应) String[] sortColumns = {"id", "name", "createTime"}; String sortField = sortColumns[request.getOrder().get(0).getColumn()]; Sort.Direction direction = Sort.Direction.fromString(request.getOrder().get(0).getDir()); Sort sort = Sort.by(direction, sortField); // 2. 处理分页:Spring Pageable页码从0开始,需用start/length计算页码 int pageNum = request.getStart() / request.getLength(); Pageable pageable = PageRequest.of(pageNum, request.getLength(), sort); // 3. 处理搜索:模糊匹配关键词 String keyword = request.getSearch().getValue(); Page<DataEntity> dataPage; if (StringUtils.hasText(keyword)) { // 自定义模糊查询,需在Repository中定义对应方法 dataPage = dataRepository.findByNameContainingOrIdContaining(keyword, keyword, pageable); } else { dataPage = dataRepository.findAll(pageable); } // 4. 封装DataTables要求的返回格式 DataTableResponse<DataEntity> response = new DataTableResponse<>(); response.setDraw(request.getDraw()); response.setRecordsTotal((int) dataRepository.count()); // 未过滤的总记录数 response.setRecordsFiltered((int) dataPage.getTotalElements()); // 过滤后的总记录数 response.setData(dataPage.getContent()); // 当前页数据 return ResponseEntity.ok(response); } }
(3)Repository层(基于PagingAndSortingRepository)
public interface DataRepository extends PagingAndSortingRepository<DataEntity, Long> { // 自定义搜索查询方法,支持分页 Page<DataEntity> findByNameContainingOrIdContaining(String nameKeyword, String idKeyword, Pageable pageable); }
(4)返回结果DTO
public class DataTableResponse<T> { private int draw; private long recordsTotal; private long recordsFiltered; private List<T> data; // getter/setter }
3. 注意事项
- 后端返回的字段必须和前端columns中
data属性完全对应,否则DataTables无法正确渲染数据 - Spring Pageable的页码从0开始,需用
start/length计算正确的请求页码 - 搜索逻辑可根据业务需求调整,比如多字段精确匹配、区间查询等
内容的提问来源于stack exchange,提问作者Jaiylon
相关产品推荐
相关产品推荐

