Camunda任务查询API:灵活的任务检索与过滤
概述
在企业级业务流程管理(BPM)系统中,任务查询是日常操作的核心功能。Camunda BPM平台提供了强大而灵活的TaskQuery API,允许开发者根据各种条件精确检索和过滤任务。本文将深入探讨Camunda任务查询API的核心功能、使用场景和最佳实践。
任务查询基础
创建任务查询实例
在Camunda中,所有任务查询都通过TaskService创建:
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.task.TaskQuery;
// 获取TaskService实例
TaskService taskService = processEngine.getTaskService();
// 创建基础查询
TaskQuery taskQuery = taskService.createTaskQuery();
基本查询方法
// 获取所有任务列表
List<Task> allTasks = taskQuery.list();
// 获取单个任务
Task singleTask = taskQuery.singleResult();
// 统计任务数量
long taskCount = taskQuery.count();
// 分页查询
List<Task> pagedTasks = taskQuery.listPage(0, 10);
核心过滤条件
1. 任务属性过滤
// 按任务ID查询
taskQuery.taskId("task-123");
// 按任务名称查询(不区分大小写)
taskQuery.taskName("审批申请");
taskQuery.taskNameLike("%审批%");
taskQuery.taskNameNotEqual("草稿");
// 按任务描述查询
taskQuery.taskDescription("需要紧急处理");
taskQuery.taskDescriptionLike("%紧急%");
// 按优先级查询
taskQuery.taskPriority(10); // 精确优先级
taskQuery.taskMinPriority(5); // 最小优先级
taskQuery.taskMaxPriority(20); // 最大优先级
2. 分配和候选人过滤
// 分配人相关查询
taskQuery.taskAssignee("john"); // 分配给特定用户
taskQuery.taskAssigneeLike("%jo%"); // 分配人名称模糊匹配
taskQuery.taskAssigneeIn("john", "mary"); // 分配给多个用户之一
taskQuery.taskAssigneeNotIn("peter"); // 不分配给特定用户
// 候选人相关查询
taskQuery.taskCandidateUser("demo"); // 用户是候选人的任务
taskQuery.taskCandidateGroup("accounting"); // 组是候选人的任务
taskQuery.taskCandidateGroupIn("sales", "management"); // 多个候选组
// 分配状态查询
taskQuery.taskAssigned(); // 已分配的任务
taskQuery.taskUnassigned(); // 未分配的任务
// 包含已分配任务的候选人查询
taskQuery.taskCandidateUser("demo").includeAssignedTasks();
3. 流程实例关联过滤
// 流程实例相关
taskQuery.processInstanceId("pi-123");
taskQuery.processInstanceIdIn("pi-123", "pi-456");
taskQuery.processInstanceBusinessKey("INV-2024-001");
taskQuery.processInstanceBusinessKeyLike("INV-2024%");
// 流程定义相关
taskQuery.processDefinitionKey("invoice-process");
taskQuery.processDefinitionKeyIn("invoice-process", "approval-process");
taskQuery.processDefinitionName("发票审批流程");
taskQuery.processDefinitionNameLike("%审批%");
// 执行实例相关
taskQuery.executionId("execution-123");
4. 时间范围过滤
// 创建时间过滤
taskQuery.taskCreatedAfter(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000)); // 24小时内创建
taskQuery.taskCreatedBefore(new Date()); // 现在之前创建
taskQuery.taskCreatedOn(new Date()); // 特定日期创建
// 到期时间过滤
taskQuery.taskDueDate(new Date(System.currentTimeMillis() + 7 * 24 * 60 * 60 * 1000)); // 7天后到期
taskQuery.taskDueAfter(new Date()); // 现在之后到期
taskQuery.taskDueBefore(new Date(System.currentTimeMillis() + 30 * 60 * 1000)); // 30分钟内到期
taskQuery.withoutDueDate(); // 没有到期时间的任务
// 更新时间过滤
taskQuery.taskUpdatedAfter(new Date(System.currentTimeMillis() - 2 * 60 * 60 * 1000)); // 2小时内更新
5. 变量条件过滤
Camunda支持基于流程变量、任务变量和案例变量的复杂查询:
// 任务变量查询
taskQuery.taskVariableValueEquals("priority", "high");
taskQuery.taskVariableValueNotEquals("status", "completed");
taskQuery.taskVariableValueLike("description", "%urgent%");
taskQuery.taskVariableValueGreaterThan("amount", 1000);
taskQuery.taskVariableValueLessThan("progress", 50);
// 流程变量查询
taskQuery.processVariableValueEquals("department", "finance");
taskQuery.processVariableValueLike("customerName", "%corp%");
taskQuery.processVariableValueGreaterThanOrEquals("totalAmount", 5000);
// 变量名称大小写敏感设置
taskQuery.matchVariableNamesIgnoreCase();
taskQuery.matchVariableValuesIgnoreCase();
高级查询功能
排序和分页
// 多种排序方式
taskQuery.orderByTaskCreateTime().desc(); // 按创建时间降序
taskQuery.orderByTaskDueDate().asc(); // 按到期时间升序
taskQuery.orderByTaskPriority().desc(); // 按优先级降序
taskQuery.orderByTaskAssignee().asc(); // 按分配人升序
// 组合排序
taskQuery
.orderByTaskPriority().desc()
.orderByTaskCreateTime().asc();
// 分页查询
List<Task> tasks = taskQuery
.listPage(0, 20); // 第一页,每页20条
OR查询条件
Camunda支持复杂的OR条件查询:
TaskQuery orQuery1 = taskService.createTaskQuery()
.taskAssignee("john");
TaskQuery orQuery2 = taskService.createTaskQuery()
.taskCandidateGroup("management");
// 组合OR查询
List<Task> tasks = taskService.createTaskQuery()
.or()
.addTaskQuery(orQuery1)
.addTaskQuery(orQuery2)
.endOr()
.list();
实际应用场景
场景1:用户任务仪表板
public List<Task> getUserDashboardTasks(String userId, String... groups) {
return taskService.createTaskQuery()
.or()
.taskAssignee(userId)
.taskCandidateUser(userId)
.taskCandidateGroupIn(groups)
.endOr()
.taskUnassigned() // 只显示未分配的任务
.orderByTaskPriority().desc()
.orderByTaskDueDate().asc()
.list();
}
场景2:管理监控视图
public Map<String, Object> getManagementOverview() {
Map<String, Object> overview = new HashMap<>();
// 高优先级任务统计
overview.put("highPriorityTasks", taskService.createTaskQuery()
.taskMinPriority(8)
.count());
// 逾期任务
overview.put("overdueTasks", taskService.createTaskQuery()
.taskDueBefore(new Date())
.count());
// 部门任务分布
overview.put("departmentTasks", taskService.createTaskQuery()
.processVariableValueEquals("department", "finance")
.count());
return overview;
}
场景3:批量任务处理
public void processHighPriorityTasks() {
List<Task> highPriorityTasks = taskService.createTaskQuery()
.taskMinPriority(7)
.taskDueBefore(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000))
.list();
for (Task task : highPriorityTasks) {
// 发送提醒通知
sendReminderNotification(task);
// 自动升级优先级
if (task.getPriority() < 10) {
taskService.setPriority(task.getId(), task.getPriority() + 1);
}
}
}
性能优化建议
1. 查询优化
// 避免全表扫描,尽量使用索引字段
taskQuery
.processDefinitionKey("specific-process") // 使用索引字段
.taskAssignee("specific-user") // 使用索引字段
.list();
// 限制返回字段,减少数据传输
taskQuery
.withTaskVariablesInReturn(false) // 不返回任务变量
.withTaskLocalVariablesInReturn(false) // 不返回本地变量
.list();
2. 分页策略
// 使用分页避免内存溢出
int pageSize = 100;
int page = 0;
List<Task> tasks;
do {
tasks = taskQuery
.listPage(page * pageSize, pageSize);
processTasks(tasks);
page++;
} while (!tasks.isEmpty());
3. 缓存策略
// 对频繁查询使用缓存
@Cacheable("userTasks")
public List<Task> getCachedUserTasks(String userId) {
return taskService.createTaskQuery()
.taskAssignee(userId)
.list();
}
常见问题解决方案
问题1:变量查询性能慢
解决方案:
// 使用精确匹配代替模糊查询
taskQuery.processVariableValueEquals("status", "approved");
// 避免在大量数据上使用LIKE查询
// taskQuery.processVariableValueLike("name", "%search%"); // 避免
问题2:复杂查询组合
解决方案:
// 分解复杂查询
TaskQuery baseQuery = taskService.createTaskQuery()
.processDefinitionKey("invoice-process");
if (department != null) {
baseQuery.processVariableValueEquals("department", department);
}
if (highPriorityOnly) {
baseQuery.taskMinPriority(8);
}
List<Task> results = baseQuery.list();
问题3:权限控制
解决方案:
// 结合权限查询
public List<Task> getAuthorizedTasks(String userId, List<String> groups) {
return taskService.createTaskQuery()
.or()
.taskAssignee(userId)
.taskCandidateUser(userId)
.taskCandidateGroupIn(groups)
.endOr()
.list();
}
总结
Camunda的任务查询API提供了极其灵活和强大的任务检索能力,涵盖了从简单的属性过滤到复杂的变量查询和OR条件组合。通过合理使用这些API,开发者可以:
- 精确过滤:根据任务属性、分配状态、时间范围等条件精确检索任务
- 变量查询:基于流程变量、任务变量实现复杂的业务逻辑过滤
- 性能优化:通过分页、索引字段使用和缓存策略优化查询性能
- 权限集成:结合用户权限实现安全的任务访问控制
掌握Camunda任务查询API的使用,将显著提升BPM应用的开发效率和使用体验,为企业流程管理提供强有力的技术支撑。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



