Skip to content

Commit

Permalink
docs: synced via GitHub Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
nop-cao committed Apr 26, 2024
1 parent b05c675 commit 0c39d59
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 11 deletions.
Binary file added src/dev-guide/orm/dql.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 10 additions & 8 deletions src/dev-guide/orm/mdx-query.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ DQL(Dimentinal Query Language)语言是润乾公司提出的一种面向OLAP的

## QueryBean表达多表查询

比如现在下面的表结构
比如对于下面的表结构

```
NopAuthGroup <--- NopAuthGroupDept ---> NopAuthDept
Expand All @@ -19,7 +19,8 @@ DQL(Dimentinal Query Language)语言是润乾公司提出的一种面向OLAP的
如果要查询`NopAuthGroup`表并同时返回每个分组关联的部门的总数,类似于下面的SQL语句

```sql
select o.groupId, o.name, (select count(g.deptId) from NopAuthUserDept g where g.groupId= o.groupId) as deptCount
select o.groupId, o.name,
(select count(g.deptId) from NopAuthGroupDept g where g.groupId= o.groupId) as deptCount
from NopAuthGroup o
```

Expand All @@ -28,22 +29,22 @@ DQL(Dimentinal Query Language)语言是润乾公司提出的一种面向OLAP的
```javascript
QueryBean query = new QueryBean();
query.setSourceName(NopAuthGroup.class.getName());
query.fields(mainField("groupId"), mainField("name"), subField("deptMappings", "deptId").count().alias("deptCount"));
query.fields(mainField("groupId"), mainField("name"),
subField("deptMappings", "deptId").count().alias("deptCount"));
query.addOrderField("name", true);

List<Map<String, Object>> list = ormTemplate.findListByQuery(query);
```

上面的代码中,`mainField`表示主表字段,`subField`
表示子表字段,subField的第一个参数是关联的字段名,第二个参数是要查询的子表上的字段名,`count`表示统计子表的总数,`alias`
表示别名。
表示子表字段,subField的第一个参数是关联的字段名,第二个参数是要查询的子表上的字段名,`count`表示统计子表的总数,`alias`表示别名。

实际的实现原理不是生成一个复杂SQL,而是在内存中分成多个查询,然后在内存中通过HashJoin来把数据整合为一个大宽表。

```sql
select o.groupId, o.name from NopAuthGroup o;

select g.groupId, count(g.deptId) as deptCount from NopAuthUserDept g group by g.groupId;
select g.groupId, count(g.deptId) as deptCount from NopAuthGroupDept g group by g.groupId;
```

这样的查询方式可以大大简化复杂的多表查询,提高开发效率。
Expand Down Expand Up @@ -103,7 +104,8 @@ query.setLimit(10);
Underscore.leftjoinMerge(listA,listB, leftPropName, rightPropName, Arrays.asList(fldB1,fldB2));
```

以上函数相当于
以上函数调用相当于实现

```sql
select listA.*, listB.fldB1,listB.fldB2
from listA, listB
Expand All @@ -121,4 +123,4 @@ table.numberColumn("count").sum();

NopORM查询得到的`IDataSet`数据集可以直接被转换为`tablesaw``Table`接口,然后就可以调用`select/pivot/summarize/count`等一系列操作函数。

> NopORM内部讲所有的数据集合对象都统一封装为IDataSet接口,因此并不对外暴露ResultSet等泄露实现细节的接口。NopORM底层可以不运行在JDBC之上。
> NopORM内部将所有的数据集合对象都统一封装为IDataSet接口,因此并不对外暴露ResultSet等泄露实现细节的接口。NopORM底层可以不运行在JDBC之上。
8 changes: 5 additions & 3 deletions src/dev-guide/xlang/xmeta.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ NopGraphQL引擎返回的对象信息完全由XMeta来定义。如果一个属
<prop name="parent">
<schema bizObjName="NopAuthDepartment" />
</prop>
<prop name="children">
<schema>
<item bizObjName="NopAuthDepartment" />
Expand All @@ -164,9 +164,11 @@ NopGraphQL引擎返回的对象信息完全由XMeta来定义。如果一个属

通过GraphQL的findPage当方法查询时,可以直接查询关联对象上的字段,但是要求在xmeta中设置允许queryable。这是从安全性角度考虑,避免客户端可以任意查询所有字段导致安全漏洞。

如果未正确定义,控制台可能出现的错误信息:`desc=未定义的查询字段:parent.name`

```xml
<prop name="parent.name" querable="true">
<prop name="parent.name" queryable="true">

</prop>
```

Expand Down
17 changes: 17 additions & 0 deletions src/theory/ddd-in-nop.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ DDD只有在一种低代码平台或者模型驱动的框架中才能发挥最
1. 分而治之自然得到多层分解
2. 在边界设置瓶颈

结构化的模型而不是平面式的领域服务。
与依赖注入的关系:对象树与业务流分离

## 领域语言

* 一种语言可以看作是一种描述坐标系
Expand All @@ -41,11 +44,21 @@ DDD只有在一种低代码平台或者模型驱动的框架中才能发挥最

聚合根首先是逻辑的聚合,BizModel的切片构造就是一种聚合方式,这种做法不是传统的面向对象中的继承方式和组合方式。另外聚合的对偶概念是动态切片,GraphQL恰好提供了一种在获取信息时的一种动态切片能力,使得我们可以在概念层面上维持一个庞大的聚合根概念,但是在实际层面每次都只加载少量数据。没有对偶的切片概念,本身聚合根就会非常臃肿,成为性能的拖累。

从坐标的观点理解聚合

取数据是为了用,纯粹的历史数据查询,走专门的查询服务

## 贫血还是充血

* 均衡分工
* 不同的稳定性和信息范围

## CQRS
* 是否要封装为明确的Command形式? ApiRequest + 领域特定结构,通用结构的唯一目的是以标准方式引入扩展数据。但在实现层没有必要显式表达
* 结合TCC,需要请求可以被持久化
* 边界层和内部模型层的表示是不同的:id => entity。对内视角与对外视角
* 领域事件与Command的区别. Event作为建模的切入点。状态的Delta

## 差量更新

* 领域事件作为Delta
Expand All @@ -62,6 +75,10 @@ DDD只有在一种低代码平台或者模型驱动的框架中才能发挥最

面向领域的编排要求对领域逻辑进行抽象,将它对应的具体的技术实体,然后通过各种手段来操纵。传统上数据建模比较成熟,但是逻辑建模就很薄弱,特别是建模之后如何使用建模结果缺乏系统化手段。

## 实现技术

sqlalchemy的延迟加载属性如果要改成eager加载,需要在获取数据时指定。

## 总结

1. 对象化是很自然的抽象手段
Expand Down

0 comments on commit 0c39d59

Please sign in to comment.