JeecgBoot大数据量处理优化:分页查询与异步导出实现
在企业级应用开发中,大数据量处理是常见的性能瓶颈。JeecgBoot作为企业级低代码平台,提供了高效的分页查询机制和异步导出方案,本文将详细介绍其实现原理与最佳实践。
分页查询优化实现
JeecgBoot采用MyBatis-Plus作为ORM框架,结合自定义查询构建器实现高效分页。核心实现类为QueryGenerator,该工具类支持动态构建带分页参数的查询条件。
基础分页实现
在控制器层,通过QueryGenerator.initQueryWrapper方法创建分页查询条件,示例代码如下:
// [JeecgDemoController.java](https://link.gitcode.com/i/4213ebec43ad17c250f3a28c2c7f3ca0)
@GetMapping("/list")
public Result<?> queryPageList(JeecgDemo jeecgDemo,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<JeecgDemo> queryWrapper = QueryGenerator.initQueryWrapper(jeecgDemo, req.getParameterMap());
Page<JeecgDemo> page = new Page<>(pageNo, pageSize);
IPage<JeecgDemo> pageList = jeecgDemoService.page(page, queryWrapper);
return Result.OK(pageList);
}
高级分页特性
- 动态查询条件:QueryGenerator支持通过请求参数动态构建查询条件,无需硬编码
- 权限数据过滤:结合PermissionDataAspect实现数据权限控制
- 防SQL注入:内置SqlInjectionUtil工具类过滤危险字符
异步导出方案设计
当处理十万级以上数据导出时,同步导出会导致请求超时。JeecgBoot通过Spring的@Async注解和线程池实现异步导出,结合WebSocket实时推送导出进度。
异步导出实现步骤
- 创建导出任务:在控制器层接收导出请求,返回任务ID
- 异步处理数据:通过@Async注解标记导出方法,在独立线程中执行
- 生成Excel文件:使用ImportExcelUtil工具类生成Excel
- 通知导出结果:完成后通过WebSocket或消息队列通知前端
核心代码实现
控制器层
// 示例代码,实际实现参考[JeecgDemoController.java](https://link.gitcode.com/i/4213ebec43ad17c250f3a28c2c7f3ca0)
@GetMapping("/exportXls")
public Result<?> exportXls(HttpServletRequest request, JeecgDemo jeecgDemo) {
String taskId = UUID.randomUUID().toString();
// 启动异步导出任务
exportService.asyncExport(taskId, jeecgDemo, request.getParameterMap());
return Result.OK(taskId);
}
服务层
// 异步导出实现
@Async("exportTaskExecutor")
public void asyncExport(String taskId, JeecgDemo jeecgDemo, Map<String, String[]> params) {
try {
// 1. 查询数据(带分页,避免内存溢出)
QueryWrapper<JeecgDemo> queryWrapper = QueryGenerator.initQueryWrapper(jeecgDemo, params);
// 2. 生成Excel
ExportParams exportParams = new ExportParams("数据报表", "导出时间:" + DateUtils.now());
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, JeecgDemo.class, dataList);
// 3. 保存文件
String filePath = jeecgBaseConfig.getPath().getUpload() + "/" + taskId + ".xlsx";
FileOutputStream fos = new FileOutputStream(filePath);
workbook.write(fos);
fos.close();
// 4. 推送完成消息(通过WebSocket)
WebSocketUtil.sendInfo(taskId, "success", filePath);
} catch (Exception e) {
WebSocketUtil.sendInfo(taskId, "error", e.getMessage());
}
}
线程池配置
异步任务使用专用线程池JeecgAsyncConfig,配置如下:
@Configuration
@EnableAsync
public class JeecgAsyncConfig {
@Bean("exportTaskExecutor")
public Executor exportTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(100);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("export-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
性能优化最佳实践
分页查询优化建议
- 索引优化:确保查询条件字段都已建立索引
- **避免SELECT ***:通过QueryGenerator指定查询字段
- 合理设置pageSize:大数据量查询时建议pageSize不超过1000
异步导出优化建议
- 分片查询:单次查询数据量控制在1万条以内
- 内存管理:使用SXSSFWorkbook代替XSSFWorkbook避免OOM
- 任务监控:通过OnlineAuthAspect监控长时间运行任务
相关模块与扩展阅读
- 分页核心模块:jeecg-boot-base-core/src/main/java/org/jeecg/common/system/query/
- 异步任务配置:JeecgAsyncConfig.java
- Excel工具类:ImportExcelUtil.java
- 官方文档:README.md
通过以上方案,JeecgBoot能够高效处理百万级数据的查询与导出需求,既保证了系统性能,又提升了用户体验。实际项目中可根据数据量大小和业务复杂度,选择合适的优化策略。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



