Skip to main content

cqrs

命令查询责任分离,将数据的写入操作和读取操作分别用不同的模型处理,优化各自的性能。

소스 정보

저장소
microwind/ai-skills
최근 소스 활동
2026년 5월 25일 13:32
감지된 SKILL.md 언어
중국어
스타
83
포크
24

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
CQRS模式
description
命令查询责任分离,将数据的写入操作和读取操作分别用不同的模型处理,优化各自的性能。
# CQRS 模式 (Command Query Responsibility Segregation) ## 概述 CQRS 将系统分为**命令端(写)和查询端(读)**,使用不同的模型处理各自的需求。 **核心思想**: - 命令(Command):改变系统状态,不返回数据 - 查询(Query):返回数据,不改变状态 - 写模型为业务规则优化,读模型为查询性能优化 ``` ┌─────────────┐ 命令 → │ 写模型 │ → 领域模型(充血、聚合、事务) │ (Command) │ → 数据库(规范化) └─────────────┘ │ 事件/同步 ▼ ┌─────────────┐ 查询 → │ 读模型 │ → 查询优化的视图 │ (Query) │ → 数据库(反规范化) └─────────────┘ ``` ## 代码示例 ```java // 命令端:严格的领域模型 public class OrderCommandHandler { private final OrderRepository orderRepo; public void handle(PlaceOrderCommand cmd) { Order order = orderRepo.findById(cmd.getOrderId()); order.place(); // 领域逻辑 orderRepo.save(order); // 发布事件 → 更新读模型 } public void handle(CancelOrderCommand cmd) { Order order = orderRepo.findById(cmd.getOrderId()); order.cancel(cmd.getReason()); orderRepo.save(order); } } // 查询端:为展示优化的模型 public class OrderQueryService { private final JdbcTemplate jdbc; // 直接查询优化后的视图,不走领域模型 public OrderListDTO findOrders(OrderSearchCriteria criteria) { String sql = "SELECT o.id, o.status, c.name as customer_name, " + "o.total_amount, o.created_at " + "FROM order_view o JOIN customer c ON o.customer_id = c.id " + "WHERE o.status = ? ORDER BY o.created_at DESC LIMIT ?"; return jdbc.query(sql, criteria.getStatus(), criteria.getLimit()); } public OrderDetailDTO findOrderDetail(String orderId) { // 从反规范化的视图中一次查出所有需要的数据 return jdbc.queryForObject( "SELECT * FROM order_detail_view WHERE id = ?", orderId); } } ``` ```python # 命令端 class PlaceOrderCommandHandler: def __init__(self, order_repo, event_publisher): self.order_repo = order_repo self.event_publisher = event_publisher def handle(self, cmd: PlaceOrderCommand): order = self.order_repo.find_by_id(cmd.order_id) order.place() self.order_repo.save(order) for event in order.collect_events(): self.event_publisher.publish(event) # 查询端 class OrderQueryService: def __init__(self, read_db): self.read_db = read_db def search_orders(self, filters: dict) -> list[OrderSummaryDTO]: """直接从读优化的视图查询""" return self.read_db.query("order_summary_view", filters) # 读模型更新器(监听事件) class OrderReadModelUpdater: def on_order_placed(self, event: OrderPlacedEvent): self.read_db.upsert("order_summary_view", { "id": event.order_id, "status": "PLACED", "customer_name": event.customer_name, "total": event.total_amount, }) ``` ## 何时使用 CQRS ``` ✅ 适用场景: - 读写比例悬殊(读多写少) - 读和写的模型差异大 - 需要独立扩展读和写 - 需要复杂的查询(报表、搜索) ❌ 不适用场景: - 简单的 CRUD 应用 - 读写模型几乎相同 - 团队不熟悉事件驱动 - 最终一致性不可接受 ``` ## CQRS 变体 | 变体 | 说明 | 复杂度 | |------|------|--------| | 同一数据库 | 写和读用同一个库的不同视图 | 低 | | 独立数据库 | 写用关系数据库,读用 Elasticsearch/Redis | 中 | | 事件溯源 + CQRS | 写端用事件,读端从事件投影 | 高 | ## 与其他DDD概念的关系 | 概念 | 关系 | |------|------| | [领域事件](../domain-events/) | 事件驱动读模型更新 | | [事件溯源](../event-sourcing/) | 常与 CQRS 配合使用 | | [读模型优化](../read-model-optimization/) | 读端的具体优化策略 | | [聚合根](../aggregate-root-design/) | 命令端使用聚合模型 | ## 总结 **核心**:读写分离,各自优化。命令端用领域模型保证业务正确,查询端用反规范化视图保证性能。 **权衡**:增加了架构复杂度,换来了读写各自的可扩展性和性能。
GitHub에서 보기