CQRS:CQRS+AJAX架构 之 查询(Q)模型设计
2013-05-23 08:57
267 查看
背景
准备采用CQRS架构,之前也简单的应用过(只是把读和写在程序级别进行了分离),这篇文章是我最近几天的思考,写下来希望大家多提意见。这篇文章不会涉及Command端的设计,重点关注如何设计查询。真心的希望大家看完后能给出你们的意见和想法。
什么是CQRS
CQRS:Command Query Responsibility Separation。我喜欢职责分离,这也是我采用这种架构的原因,确实能带来单一职责的优点。
简单的CQRS
复杂的CQRS
CQRS的常见查询需求
下面是系统的一些查询需求:查询面板
高级查询
数据行级别的权限
如:个人、部门、分公司、品种。固定约束
如:启用、合法、租户ID。需求总结
CQRS的查询设计
充分利用SQL和动态类型的优势,不做太多无谓的封装。
关键决策:
直接查询数据库返回Dynamic类型,不需要定义强类型。直接用SQL,支持动态查询面板和动态数据行权限。目前没有找到封装SQL的理由,最多是在外围再封装一层,但是不会隐藏SQL(我之前写过一个简单的查询对象)。
利用一些策略防止SQL注入和权限提升(这篇文章不介绍)。
示例代码
下载地址:http://happy.codeplex.com/SourceControl/latest。AJAX程序
/// <reference path="Ext/ext-all-debug-w-comments.js" /> Ext.onReady(function () { var query = { TableOrViewName: 'Users', WhereClause: "Name NOT LIKE '%段%'" }; Ext.Ajax.request({ url: 'TestDynamicQuery/Fetch', method: 'POST', params: { query: Ext.encode(query) }, success: function (response) { console.log(response.responseText); } }); query = { TableOrViewName: 'Users', WhereClause: "Age >= 20 AND Age <= 27" }; Ext.Ajax.request({ url: 'TestDynamicQuery/Fetch', method: 'POST', params: { query: Ext.encode(query) }, success: function (response) { console.log(response.responseText); } }); });
万能查询控制器
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.Mvc; using Newtonsoft.Json; using Happy.Query; namespace Happy.Web.Mvc { /// <summary> /// 动态查询控制器。 /// </summary> public abstract class DynamicQueryController<TDynamicQueryService> : AjaxController where TDynamicQueryService : IDynamicQueryService { /// <summary> /// 动态查询服务。 /// </summary> protected abstract TDynamicQueryService QueryService { get; } /// <summary> /// 获取分页数据,面向表格。 /// </summary> public ActionResult Page(DynamicQueryObject query) { var result = this.QueryService.Page(query); return this.Json(result); } /// <summary> /// 获取列表数据,面向不需要分页的表格或下拉框。 /// </summary> public ActionResult Fetch(DynamicQueryObject query) { var result = this.QueryService.Fetch(query); return this.NewtonsoftJson(result); } /// <summary> /// 获取一个数据,面向表单。 /// </summary> public ActionResult SingleOrDefault(DynamicQueryObject query) { var result = this.QueryService.Fetch(query); return this.NewtonsoftJson(result); } } }
万能查询对象
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Happy.Query { /// <summary> /// 动态查询对象。 /// </summary> public sealed class DynamicQueryObject { /// <inheritdoc /> public DynamicQueryObject() { this.Columns = new List<string>(); this.Page = 1; this.ItemsPerPage = 25; } /// <summary> /// 表或试图名字。 /// </summary> public string TableOrViewName { get; set; } /// <summary> /// 表或试图名字。 /// </summary> public List<string> Columns { get; set; } /// <summary> /// Where子句。 /// </summary> public string WhereClause { get; set; } /// <summary> /// Order子句。 /// </summary> public string OrderClause { get; set; } /// <summary> /// 第几页数据。 /// </summary> public long Page { get; set; } /// <summary> /// 每页条数。 /// </summary> public long ItemsPerPage { get; set; } } }
备注
写这篇文章的目的,是系统大家多给些意见,我想知道你们是如何应对这种查询需求的。相关文章推荐
- CQRS:CQRS+AJAX架构 之 查询(Q)模型设计
- IDDD 实现领域驱动设计-CQRS(命令查询职责分离)和 EDA(事件驱动架构)
- 插件式设计的架构模型与实例
- 插件式设计的架构模型与实例
- 9.4.1: 常见的架构设计策略---贫血模型
- 架构设计中领域模型设计思路
- 基于模型、模式的技术架构设计
- 使用Apworks开发基于CQRS架构的应用程序(二):创建领域模型项目
- 【架构设计】领域模型(概念模型) 、逻辑模型、物理模型、贫血模型、充血模型概念总结【待读与标记】
- Spark2.1.0模型设计与基本架构(下)
- 插件式设计的架构模型与实例
- 架构设计:系统间通信(4)——IO通信模型和JAVA实践 中篇
- 【系统设计】“查询推荐好友”服务在不同架构风格下如何设计?
- 插件式设计的架构模型与实例
- Azure设计模式之命令与查询隔离(CQRS)
- 9.4.2: 常见的架构设计策略---领域对象模型
- 【设计模式 2】设计模式的来源,及其相混淆的模型、框架、架构区别
- 关注网银系统:安全模型和架构设计
- CISSP的成长之路(十三):安全架构和设计之安全模型
- 云计算设计模式(六)——命令和查询职责分离(CQRS)模式