`

CQRS:CQRS+AJAX架构 之 查询(Q)模型设计

阅读更多
原帖地址:http://www.cnblogs.com/happyframework/archive/2013/05/23/3094164.html

背景


准备采用CQRS架构,之前也简单的应用过(只是把读和写在程序级别进行了分离),这篇文章是我最近几天的思考,写下来希望大家多提意见。这篇文章不会涉及Command端的设计,重点关注如何设计查询。


真心的系统大家看完给出你们的意见和想法。


什么是CQRS


CQRS:Command Query Responsibility Separation。我喜欢职责分离,这也是我采用这种架构的原因,确实能带来单一职责的优点。


简单的CQRS



复杂的CQRS



CQRS的常见查询需求


下面是系统的一些查询需求:


查询面板



高级查询



数据行级别的权限


如:个人、部门、分公司、品种。


固定约束


如:启用、合法、租户ID。


需求总结



CQRS的查询设计


充分利用SQL和动态类型的优势,不做太多无谓的封装。


关键决策:




    1. 直接查询数据库返回Dynamic类型,不需要定义强类型。

    2. 直接用SQL,支持动态查询面板和动态数据行权限。目前没有找到封装SQL的理由,最多是在外围再封装一层,但是不会隐藏SQL(我之前写过一个简单的查询对象)。

    3. 利用一些策略防止SQL注入和权限提升(这篇文章不介绍)。



示例代码


下载地址:http://happy.codeplex.com/SourceControl/latest


AJAX程序



 1 /// <reference path="Ext/ext-all-debug-w-comments.js" />
2
3 Ext.onReady(function () {
4 var query = {
5 TableOrViewName: 'Users',
6 WhereClause: "Name NOT LIKE '%段%'"
7 };
8
9 Ext.Ajax.request({
10 url: 'TestDynamicQuery/Fetch',
11 method: 'POST',
12 params: { query: Ext.encode(query) },
13 success: function (response) {
14 console.log(response.responseText);
15 }
16 });
17
18 query = {
19 TableOrViewName: 'Users',
20 WhereClause: "Age >= 20 AND Age <= 27"
21 };
22
23 Ext.Ajax.request({
24 url: 'TestDynamicQuery/Fetch',
25 method: 'POST',
26 params: { query: Ext.encode(query) },
27 success: function (response) {
28 console.log(response.responseText);
29 }
30 });
31 });


万能查询控制器



 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Web.Mvc;
7
8 using Newtonsoft.Json;
9
10 using Happy.Query;
11
12 namespace Happy.Web.Mvc
13 {
14 /// <summary>
15 /// 动态查询控制器。
16 /// </summary>
17 public abstract class DynamicQueryController<TDynamicQueryService> : AjaxController
18 where TDynamicQueryService : IDynamicQueryService
19 {
20 /// <summary>
21 /// 动态查询服务。
22 /// </summary>
23 protected abstract TDynamicQueryService QueryService { get; }
24
25 /// <summary>
26 /// 获取分页数据,面向表格。
27 /// </summary>
28 public ActionResult Page(DynamicQueryObject query)
29 {
30 var result = this.QueryService.Page(query);
31
32 return this.Json(result);
33 }
34
35 /// <summary>
36 /// 获取列表数据,面向不需要分页的表格或下拉框。
37 /// </summary>
38 public ActionResult Fetch(DynamicQueryObject query)
39 {
40 var result = this.QueryService.Fetch(query);
41
42 return this.NewtonsoftJson(result);
43 }
44
45 /// <summary>
46 /// 获取一个数据,面向表单。
47 /// </summary>
48 public ActionResult SingleOrDefault(DynamicQueryObject query)
49 {
50 var result = this.QueryService.Fetch(query);
51
52 return this.NewtonsoftJson(result);
53 }
54 }
55 }


万能查询对象



 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Happy.Query
8 {
9 /// <summary>
10 /// 动态查询对象。
11 /// </summary>
12 public sealed class DynamicQueryObject
13 {
14 /// <inheritdoc />
15 public DynamicQueryObject()
16 {
17 this.Columns = new List<string>();
18 this.Page = 1;
19 this.ItemsPerPage = 25;
20 }
21
22 /// <summary>
23 /// 表或试图名字。
24 /// </summary>
25 public string TableOrViewName { get; set; }
26
27 /// <summary>
28 /// 表或试图名字。
29 /// </summary>
30 public List<string> Columns { get; set; }
31
32 /// <summary>
33 /// Where子句。
34 /// </summary>
35 public string WhereClause { get; set; }
36
37 /// <summary>
38 /// Order子句。
39 /// </summary>
40 public string OrderClause { get; set; }
41
42 /// <summary>
43 /// 第几页数据。
44 /// </summary>
45 public long Page { get; set; }
46
47 /// <summary>
48 /// 每页条数。
49 /// </summary>
50 public long ItemsPerPage { get; set; }
51 }
52 }


备注


写这篇文章的目的,是系统大家多给些意见,我想知道你们是如何应对这种查询需求的。


 

本文链接

分享到:
评论

相关推荐

    JdonFramework应用案例之一: JdonFrameworkTest CQRS+ES

    《JdonFramework实战:CQRS+ES在JdonFrameworkTest中的应用》 JdonFramework,由知名软件架构师钟道宏先生创立,是一款基于Domain-Driven Design(领域驱动设计,简称DDD)理念的轻量级Java框架。它以其简单易用、...

    magic-bottle项目是一套匿名社交系统,包括Andriod、WEB管理端以及服务端,采用DDD+CQRS架构

    magic-bottle项目是一套匿名社交系统,包括Andriod、WEB管理端以及服务端,采用DDD+CQRS架构 magic-bottle项目是一套匿名社交系统,包括Andriod、WEB管理端以及服务端,采用DDD+CQRS架构 magic-bottle项目是一套...

    billing:CQRS +事件源+ DDD

    CQRS +事件源+ DDD 此应用程序是一个测试,一个研究案例。 它基于Gregory Young CQRS Simple( )。 这是什么? 这是一个基于express.js的API,旨在将生成的事件存储在本地内存事件存储中。 也就是说,重新启动...

    Xer.Cqrs:轻巧易用的CQRS + DDD库

    什么是Xer.Cqrs? Xer.Cqrs是一个便捷程序包,其中包含构建具有DDD概念的CQRS写面所需的所有程序包。 它将其他轻量级XerProjects库分组在一起: -包含域驱动设计(DDD)组件/概念。 -包含用于处理命令的组件。 -...

    CQRS:轻量级Java CQRS框架

    在Java中,CQRS可以通过创建两个独立的数据模型来实现:一个用于查询,称为读模型,另一个用于更新,称为写模型。读模型通常设计为优化读取性能,而写模型则关注业务逻辑的正确性。两者之间的通信可以通过消息队列或...

    CQRS架构实例

    CQRS的核心思想是将一个应用程序的模型分为两个独立的部分:查询模型(用于读取数据)和命令模型(用于更新数据)。这种分离使得每个部分可以独立设计和优化,从而简化复杂系统的设计。 在基于C#的CQRS实现中,通常...

    CQRS:通用命令CQRS [命令和查询责任隔离]

    3. **事件溯源**:在CQRS中,当命令模型执行写操作时,会生成事件,这些事件被存储并可用于构建查询模型。事件溯源使得系统状态可以通过过去事件的历史重建,提供了对历史数据的审计和恢复能力。 4. **事件处理器**...

    php-microservice-cqrs-es:使用CQRS + Event SourcingPHP Microservice样板

    使用CQRS +事件源的微服务样板 这是一个非常简单的示例应用程序,具有两个端点,在该应用程序中,将模拟创建具有name属性的项目以及所有已注册项目的列表。 内置: 码头工人 PHP 7.3 Zend表现力 口才ORM ...

    CQRS介绍 CQRS概述

    CQRS(Command Query Responsibility Segration)架构,大家应该不会陌生了。简单的说,就是一个系统,从架构上把它拆分为两部分:命令处理(写请求)+查询处理(读请求)。然后读写两边可以用不同的架构实现,以...

    CQRS:CQRS研讨会

    CQRS,全称为Command Query Responsibility Segregation(命令查询责任分离),是一种软件设计模式,它将一个应用程序的读写操作分离,形成两个独立的操作域:一个是处理命令(写操作),另一个是处理查询(读操作)...

    cqrs:Haskell的CQRS实施

    Haskell的CQRS介绍这是CQRS + ES架构模式的Haskell实现。 它结合了两种模式,每种模式本身都具有强大的功能,但是它们的组合却成倍地强大。 第一种模式是命令查询责任隔离(CQRS),它用于将应用程序中进行写或更新...

    C#中的命令查询责任分离(CQRS):构建高效可扩展系统

    在现代软件架构中,CQRS(命令查询责任分离)模式已成为处理复杂业务逻辑和数据需求的有效手段。CQRS模式通过将数据的读取(查询)和写入(命令)操作分离,提高了应用程序的性能、可扩展性和维护性。本文将详细介绍...

    event-sourcing, Meteor的CQRS和事件采购基础架构.zip

    event-sourcing, Meteor的CQRS和事件采购基础架构 用于 Meteor的 CQRS &事件源 这个包提供了构建你的Meteor 应用程序的基础设施,以英镑 ( 命令/查询职责分离) 和英镑事件采购原则为基础。 这样可以使用强大的业务...

    【Java 设计模式-源码】Java 中的命令查询责任分离(CQRS):优化数据交互以实现可扩展性

    CQRS 设计模式将修改数据的操作(命令)与检索数据的操作(查询)分开,以提高软件系统的性能、可扩展性和可维护性。通过实现 CQRS,您可以独立优化系统的读写操作,从而实现更高效的数据处理和提高整体系统性能。 ...

    CQRS:[WIP] Kotlin中的CQ(R)S模式实现

    CQRS(Command Query Responsibility Segregation,命令查询责任分离)是一种设计模式,主要用于复杂的系统架构,它将一个应用程序的读取和写入操作分离,形成两个独立的模型,即命令处理部分和查询处理部分。...

    functional-cqrs:功能性CQRS的骨架

    功能性CQRS(Command Query Responsibility Segregation)是一种架构模式,它将读取操作和写入操作分离,以提高系统的可伸缩性和性能。在本项目"functional-cqrs"中,开发者使用了Kotlin语言和函数式编程方法来实现...

    awesome-elixir-cqrs:精选的Elixir和命令查询责任隔离(CQRS)资源的精选列表

    命令模型负责处理写操作,而查询模型则专注于提供高效的读取能力。这种分离有助于简化复杂系统的架构,提高性能,并便于实现领域驱动设计(DDD)。 **领域驱动设计(DDD)** 领域驱动设计是一种软件开发方法论,...

    CQRS:使用事件源和域事件实现数据管理模式CQRS

    **CQRS(命令查询职责分离)**是一种设计模式,它将应用程序的读取和写入操作分开,以提高系统的性能和可维护性。在传统的单一数据模型中,读取和写入操作通常共享同一个数据库,这可能导致复杂性和性能瓶颈。CQRS...

    node-cqrs:具有针对Node.js的事件源的CQRS主干

    它的灵感来自Lokad.CQRS,但并不局限于特定的存储实现或基础架构。 它支持ES6类和依赖项注入,因此可以修改或替换您自己的实现中的任何组件,而不会破坏软件包的代码库。 您的应用程序应使用与以下界面匹配的宽松...

    cqrs:用于CQRS的golang入门套件。 http

    将Edument的[EDUM]命令查询责任分离(CQRS)套件转换为Go。 有关CQRS设计的更多信息,请参见CQRS designcom / mbucc / cqrs / wiki上的 。 有关其他Go CQRS库,请参见 [EDUM] Edument AB(2013年4月30日)。 用于...

Global site tag (gtag.js) - Google Analytics