news 2026/6/15 19:40:45

SpringBoot + 动态 SQL + 条件编排器:报表查询条件自由组合,业务人员也能配查询!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot + 动态 SQL + 条件编排器:报表查询条件自由组合,业务人员也能配查询!

业务需求的痛点

相信很多同学都遇到过这样的场景:

  • 产品经理:"这个报表要支持各种条件组合查询,用户可以自定义筛选条件"
  • 业务人员:"我想要查近30天,销售额大于1000,且在华北地区,客户等级是VIP的订单"
  • 另一个业务人员:"我想要查近7天,商品类别是手机,价格在500-2000之间的商品"

这种需求听起来简单,但实现起来却很复杂。传统的做法往往是写一堆 if-else,或者为每种组合写一个查询接口,维护成本极高。

解决方案思路

我们今天要解决的,就是让业务人员能够自由组合查询条件,而不需要后端开发每次都写新的查询逻辑。

核心思路是:

  1. 动态SQL:根据用户选择的条件动态生成SQL语句
  2. 条件编排器:将查询条件抽象成可配置的组件
  3. 规则引擎:处理复杂的条件组合逻辑

技术选型

  • SpringBoot:快速搭建应用
  • MyBatis-Plus:动态SQL构建
  • Easy Rules:条件编排规则引擎
  • MySQL:数据存储

核心实现思路

1. 查询条件模型设计

首先,我们需要定义一个查询条件的数据模型:

public class QueryCondition { private String field; // 字段名,如 "order_amount" private String operator; // 操作符,如 ">", "<", "=" private Object value; // 值 private String logic; // 逻辑连接符,如 "AND", "OR" }

2. 动态SQL构建器

使用MyBatis-Plus的QueryWrapper来构建动态SQL:

public class DynamicQueryBuilder { public QueryWrapper<T> buildQueryWrapper(List<QueryCondition> conditions) { QueryWrapper<T> wrapper = new QueryWrapper<>(); for (int i = 0; i < conditions.size(); i++) { QueryCondition condition = conditions.get(i); // 根据操作符构建查询条件 switch (condition.getOperator()) { case ">": wrapper.gt(condition.getField(), condition.getValue()); break; case "<": wrapper.lt(condition.getField(), condition.getValue()); break; case "=": wrapper.eq(condition.getField(), condition.getValue()); break; // ... 其他操作符 } // 添加逻辑连接符 if (i < conditions.size() - 1) { String nextLogic = conditions.get(i + 1).getLogic(); if ("OR".equalsIgnoreCase(nextLogic)) { wrapper.or(); } } } return wrapper; } }

3. 条件编排规则引擎

使用Easy Rules来处理复杂的条件组合逻辑:

@Rule(name = "dateRangeRule", description = "日期范围条件规则") public class DateRangeRule { @Condition public boolean evaluate(@Fact("conditions") List<QueryCondition> conditions) { // 检查是否包含日期范围条件 return conditions.stream() .anyMatch(c -> "create_date".equals(c.getField())); } @Action public void execute(@Fact("wrapper") QueryWrapper wrapper, @Fact("conditions") List<QueryCondition> conditions) { // 处理日期范围条件 conditions.stream() .filter(c -> "create_date".equals(c.getField())) .forEach(c -> { if (">=".equals(c.getOperator())) { wrapper.ge("create_date", c.getValue()); } else if ("<=".equals(c.getOperator())) { wrapper.le("create_date", c.getValue()); } }); } }

4. 查询服务实现

将上述组件整合起来:

@Service public class ReportQueryService { private final DynamicQueryBuilder queryBuilder; private final RulesEngine rulesEngine; public List<ReportData> queryReport(ReportQueryRequest request) { // 1. 获取规则 Rules rules = getRulesByReportType(request.getReportType()); // 2. 执行规则引擎处理条件 Facts facts = new Facts(); facts.put("conditions", request.getConditions()); QueryWrapper<ReportData> wrapper = new QueryWrapper<>(); facts.put("wrapper", wrapper); rulesEngine.execute(rules, facts); // 3. 执行查询 return reportDataMapper.selectList(wrapper); } private Rules getRulesByReportType(String reportType) { // 根据报表类型获取对应的规则 Rules rules = new Rules(); // 添加通用规则 rules.register(new DateRangeRule()); rules.register(new AmountRangeRule()); rules.register(new TextMatchRule()); // 根据报表类型添加特定规则 if ("order_report".equals(reportType)) { rules.register(new OrderSpecificRule()); } return rules; } }

配置化实现

为了让业务人员能够配置查询条件,我们需要提供一个配置界面:

@RestController @RequestMapping("/api/config") public class ConditionConfigController { @PostMapping("/condition") public Result<Void> saveConditionConfig(@RequestBody ConditionConfig config) { // 保存条件配置到数据库 conditionConfigService.save(config); return Result.success(); } @GetMapping("/condition/{reportType}") public Result<List<ConditionConfig>> getConditionConfig(@PathVariable String reportType) { // 获取指定报表类型的条件配置 List<ConditionConfig> configs = conditionConfigService.getByReportType(reportType); return Result.success(configs); } }

前端交互设计

前端页面可以设计成拖拽式配置:

  1. 业务人员从条件库中拖拽需要的条件到配置区域
  2. 设置条件的参数(字段、操作符、值等)
  3. 设置条件之间的逻辑关系
  4. 保存配置

这样,业务人员就可以通过简单的配置完成复杂的查询条件组合。

优势分析

这种方案的优势显而易见:

  1. 灵活性:业务人员可以自由组合查询条件,无需开发介入
  2. 可维护性:规则化管理,便于维护和扩展
  3. 性能:通过动态SQL,只查询必要的数据
  4. 复用性:同一套规则可以应用于多个报表
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 16:40:27

邦芒干货:想要跳槽成功得拼这6项

想要在职场跳槽中获得成功&#xff0c;需在多个关键维度上进行系统性准备与提升。以下是六个核心要素&#xff0c;它们共同构成了跳槽成功的竞争力基石。‌一、工作能力&#xff1a;核心竞争力的基石‌ 工作能力是职业发展的根本&#xff0c;如同行走江湖所需的“绝世武功”。它…

作者头像 李华
网站建设 2026/6/15 9:21:56

从零开始掌握RAG技术:让大模型突破知识局限的终极指南

文章详细介绍了检索增强生成&#xff08;RAG&#xff09;技术&#xff0c;通过引入外部知识库解决大语言模型的局限性、幻觉问题。RAG系统通过检索器获取相关知识&#xff0c;结合原始问题传递给大语言模型&#xff0c;提高生成内容的准确性和时效性。文章阐述了RAG的工作流程、…

作者头像 李华
网站建设 2026/6/15 9:20:07

数字图像处理篇---边缘检测

我用最简单的方式解释“边缘检测” —— 这是让计算机拥有“找轮廓”能力的关键技术。一句话核心思想边缘检测 教计算机“描边”就像小孩子给图画书里的动物描边一样&#xff0c;边缘检测就是让计算机自动找出图像里所有物体的轮廓线。一、最生活化的比喻比喻1&#xff1a;积水…

作者头像 李华
网站建设 2026/6/14 15:39:02

BEAR基准深度解析:多模态大语言模型的体现能力评估与提升指南

BEAR基准是首个全面评估多模态大语言模型(MLLM)体现能力的综合测试&#xff0c;包含4469个多模态样本。研究发现当前MLLM表现普遍不佳(20%-40%)&#xff0c;最佳模型GPT-5仅达52%&#xff0c;远低于人类84%基准。研究团队提出BEAR-Agent多模态代理&#xff0c;成功将GPT-5性能提…

作者头像 李华
网站建设 2026/6/15 9:18:27

NFL新一代数据分析系统十年创新历程

每次NFL比赛的每一次对抗都会产生大量的物理数据。22名球员在几分之一秒内加速、碰撞并改变方向&#xff0c;而橄榄球则在有序的混乱中划出一道轨迹。然而在这项运动的大部分历史中&#xff0c;许多复杂性都未被测量。NFL新一代数据分析系统的研究与分析高级经理Mike Band说&am…

作者头像 李华
网站建设 2026/6/15 9:21:30

大数据领域分布式存储的异构存储融合

大数据领域分布式存储的异构存储融合&#xff1a;从“信息孤岛”到“智能协同”的进化之路 一、引入&#xff1a;当“存储拼图”遇到“大数据洪流” 深夜11点&#xff0c;某电商公司的技术总监李明盯着监控屏幕&#xff0c;额头上渗出细密的汗珠——距离“双11”大促还有3小时…

作者头像 李华