[图解]企业应用架构模式2024新译本讲解17-活动记录1




1
00:00:01,070 --> 00:00:04,180
下一个我们要说的就是
2
00:00:04,190 --> 00:00:06,740
活动记录模式了
3
00:00:07,640 --> 00:00:11,210
同样是数据源架构模式
4
00:00:12,300 --> 00:00:18,480
里面的一个,活动记录
5
00:00:18,490 --> 00:00:21,710
我们看这里,定义,active record
6
00:00:24,230 --> 00:00:25,710
就是说,一个对象
7
00:00:26,000 --> 00:00:28,080
它包装数据库表或视图上
8
00:00:28,090 --> 00:00:30,160
某一行,主要是表了
9
00:00:30,170 --> 00:00:31,720
但视图也是可以的
10
00:00:31,990 --> 00:00:34,560
就是说,把它用在视图上也是可以的
11
00:00:36,590 --> 00:00:39,390
只不过视图你不能更新了
12
00:00:41,220 --> 00:00:42,380
不好更新
13
00:00:43,280 --> 00:00:45,870
如果你说不更新,也可以
14
00:00:48,980 --> 00:00:50,540
然后封装数据库访问
15
00:00:50,670 --> 00:00:53,620
并且在数据上增加了领域逻辑
16
00:00:56,020 --> 00:00:59,870
实际上,也就是说,把刚才Gateway
17
00:01:00,360 --> 00:01:04,770
入口对象
18
00:01:05,720 --> 00:01:07,990
连同它的查找器
19
00:01:10,370 --> 00:01:11,230
在这个基础上
20
00:01:12,160 --> 00:01:15,570
再往上叠加一个实体对象
21
00:01:15,980 --> 00:01:17,360
就相当于把Person
22
00:01:18,620 --> 00:01:19,850
PersonFinder
23
00:01:20,210 --> 00:01:21,840
还有PersonGateway
24
00:01:21,850 --> 00:01:22,280
25
00:01:23,490 --> 00:01:24,770
加起来
26
00:01:24,780 --> 00:01:26,910
就得到这个了
27
00:01:26,920 --> 00:01:29,660
显然什么都在里面了
28
00:01:31,980 --> 00:01:33,260
什么东西都在里面了
29
00:01:35,790 --> 00:01:36,880
有领域逻辑
30
00:01:36,890 --> 00:01:38,800
有数据操作,都在里面
31
00:01:38,810 --> 00:01:42,530
比如,上半部就是数据操作,crud
32
00:01:42,540 --> 00:01:50,670
下面是领域逻辑,活动记录
33
00:01:51,960 --> 00:01:58,190
特点就是,它跟关系数据库是紧密耦合的
34
00:02:01,610 --> 00:02:07,190
它这里面的属性或者字段
35
00:02:07,200 --> 00:02:12,330
它跟数据库是基本一致的
36
00:02:14,450 --> 00:02:16,760
也就是说,它就基本不考虑说
37
00:02:17,400 --> 00:02:21,420
用别的存储方式了
38
00:02:21,780 --> 00:02:23,510
当然你用别的也不是不可以
39
00:02:23,600 --> 00:02:27,540
但是它就跟这个没有那么匹配
40
00:02:32,490 --> 00:02:33,970
这是活动记录
41
00:02:36,340 --> 00:02:41,140
其他的基本上都是前面已经见过了
42
00:02:41,600 --> 00:02:45,580
刚才讲,就是这个、这个再加上这个
43
00:02:49,970 --> 00:02:51,570
所以怎么演化来的
44
00:02:51,580 --> 00:02:52,850
书上也说了
45
00:02:53,260 --> 00:02:55,650
你可以一开始先用入口
46
00:02:56,700 --> 00:02:57,980
入口用着用着
47
00:02:58,630 --> 00:03:01,440
就感觉到这里面的缺点了
48
00:03:02,400 --> 00:03:07,430
然后慢慢把行为
49
00:03:08,700 --> 00:03:09,760
把它合并
50
00:03:09,770 --> 00:03:11,240
或者移动
51
00:03:11,540 --> 00:03:14,600
最终就变成了一个活动记录
52
00:03:18,660 --> 00:03:22,580
53
00:03:22,590 --> 00:03:24,330
活动记录最有名的框架
54
00:03:26,460 --> 00:03:28,890
前些年的,现在已经不流行了
55
00:03:29,330 --> 00:03:32,180
前些年被某些团体吹得厉害的
56
00:03:33,160 --> 00:03:36,020
Ruby on Rails
57
00:03:36,030 --> 00:03:38,100
.net里面也有Castle
58
00:03:40,310 --> 00:03:42,050
这个活动记录的框架
59
00:03:42,410 --> 00:03:45,780
当然这个底层还是NHibernate的
60
00:03:52,900 --> 00:03:56,880
好,下面我们看一下案例
61
00:03:57,540 --> 00:04:01,560
案例跟行数据入口一样
62
00:04:01,770 --> 00:04:06,860
也是Person这个类或表
63
00:04:08,780 --> 00:04:11,570
这里译文做了一些修订
64
00:04:14,230 --> 00:04:18,020
包括原书上什么类
65
00:04:18,030 --> 00:04:19,180
是小写
66
00:04:19,890 --> 00:04:21,460
改过来大写
67
00:04:22,200 --> 00:04:23,680
因为代码是大写的
68
00:04:28,020 --> 00:04:28,650
一样的
69
00:04:30,350 --> 00:04:33,140
所以一会我们看代码的时候就会发现
70
00:04:33,150 --> 00:04:36,050
它里面的很多,在上一个
71
00:04:36,620 --> 00:04:38,080
我们说的模式里面
72
00:04:38,250 --> 00:04:39,280
已经出现过
73
00:04:41,190 --> 00:04:44,190
只不过现在把它统一合并到这里面来了
74
00:04:44,990 --> 00:04:48,310
再加上一些领域的操作
75
00:04:53,500 --> 00:04:55,800
这是类图
76
00:04:56,400 --> 00:05:03,620
显然,跟之前数据入口那个类图
77
00:05:03,790 --> 00:05:06,900
行数据入口的类图几乎是一样的
78
00:05:07,370 --> 00:05:09,290
只不过名字改成,你看这个是Person
79
00:05:09,420 --> 00:05:10,530
之前叫PersonGateway
80
00:05:11,270 --> 00:05:11,670
81
00:05:15,220 --> 00:05:15,970
基本上一样
82
00:05:18,270 --> 00:05:20,300
然后,注册表,一样
83
00:05:20,310 --> 00:05:25,710
然后注册表也是采用单例的模式,一样
84
00:05:25,720 --> 00:05:29,390
然后上面同样的有一个超类
85
00:05:30,080 --> 00:05:34,970
之前超类叫Gateway
86
00:05:34,980 --> 00:05:37,010
现在变成ActiveRecord
87
00:05:38,250 --> 00:05:40,480
原来是入口,现在变成活动记录
88
00:05:41,280 --> 00:05:41,940
这样而已
89
00:05:44,670 --> 00:05:48,570
其他的没有太大的差别
1
00:00:01,600 --> 00:00:02,960
无非就是这个地方
2
00:00:03,570 --> 00:00:06,640
这里有领域的一个操作了
3
00:00:06,890 --> 00:00:07,960
这个是领域操作
4
00:00:08,640 --> 00:00:11,440
就混杂在数据操作里面
5
00:00:13,260 --> 00:00:15,880
下面我们就来看一下代码
1
00:00:00,170 --> 00:00:03,160
我们同样一步一步来看这个代码
2
00:00:04,600 --> 00:00:06,950
初始化数据,这跟前面一样的
3
00:00:08,610 --> 00:00:13,160
跟前面入口一样
4
00:00:14,220 --> 00:00:17,160
建立表,都是一样的
5
00:00:18,010 --> 00:00:22,810
也是一样,这里,用SQLite
6
00:00:22,820 --> 00:00:26,290
7
00:00:26,300 --> 00:00:29,020
下面一样
8
00:00:37,820 --> 00:00:38,210
好
9
00:00:40,530 --> 00:00:49,010
下面这个,这里面,查找所有的人员
10
00:00:49,750 --> 00:00:58,870
所有的人员,在这里定义了一个操作
11
00:00:58,880 --> 00:01:01,070
返回就是一个人员的列表
12
00:01:03,930 --> 00:01:07,540
定义Person的列表
13
00:01:09,080 --> 00:01:12,550
然后,下面,创建并打开数据库连接,一样的
14
00:01:14,390 --> 00:01:16,610
然后创建命令对象
15
00:01:17,380 --> 00:01:19,100
那么这个SQL语句
16
00:01:25,740 --> 00:01:28,930
就是查询所有的人
17
00:01:31,370 --> 00:01:33,290
好,执行查询之后
18
00:01:34,080 --> 00:01:37,410
然后得到reader,得到reader之后
19
00:01:37,660 --> 00:01:40,610
我们就轮询reader
20
00:01:42,650 --> 00:01:44,090
然后把它的数据
21
00:01:44,100 --> 00:01:46,850
加载到Person的对象
22
00:01:47,680 --> 00:01:49,170
并把Person对象
23
00:01:49,180 --> 00:01:50,450
添加到列表里面
24
00:01:51,090 --> 00:01:53,190
到这个里面
25
00:01:57,670 --> 00:02:03,940
那么加载跟昨天PersonGateway
26
00:02:03,950 --> 00:02:05,380
是一样的
27
00:02:07,090 --> 00:02:08,300
只不过昨天是Gateway
28
00:02:08,310 --> 00:02:10,180
现在就直接在Person这里面了
29
00:02:11,550 --> 00:02:13,820
你看昨天这里,Gateway
30
00:02:13,830 --> 00:02:14,900
31
00:02:15,520 --> 00:02:18,840
PersonGateway,后缀去掉
32
00:02:18,930 --> 00:02:20,850
就得到这个
33
00:02:20,860 --> 00:02:22,920
定义对象数组,一样的
34
00:02:23,570 --> 00:02:29,010
然后把reader里面的值放到这里面来
35
00:02:29,020 --> 00:02:33,910
填充到这个对象数组里面来
36
00:02:34,430 --> 00:02:35,950
然后取第1列
37
00:02:36,200 --> 00:02:37,710
第0列,就是ID
38
00:02:39,410 --> 00:02:40,410
把ID取出来
39
00:02:41,120 --> 00:02:45,850
然后从注册表里面查
40
00:02:46,630 --> 00:02:51,000
这个ID能不能找到相应的Person的对象
41
00:02:51,440 --> 00:02:51,790
42
00:02:52,600 --> 00:02:53,030
有没有
43
00:02:53,040 --> 00:02:54,730
如果有就返回了
44
00:02:55,580 --> 00:02:56,340
查怎么查
45
00:02:58,630 --> 00:03:00,060
注册表,跟昨天一样的
46
00:03:00,070 --> 00:03:01,800
也是构造器私有
47
00:03:01,810 --> 00:03:03,480
这个一模一样
48
00:03:03,610 --> 00:03:06,120
也是用一个字典来存放
49
00:03:06,680 --> 00:03:07,120
一样的
50
00:03:09,650 --> 00:03:14,390
获取,看有没有这个1
51
00:03:18,940 --> 00:03:20,370
显然是没有的,为什么
52
00:03:20,990 --> 00:03:25,100
因为我们初始化的时候
53
00:03:25,110 --> 00:03:28,420
根本注册表还没东西
54
00:03:28,920 --> 00:03:29,640
没有
55
00:03:30,570 --> 00:03:32,610
注册表里面要是没有,说明什么
56
00:03:33,170 --> 00:03:37,310
这个对象它就没有在内存里面了
57
00:03:37,320 --> 00:03:42,890
内存里面之前就没有对应的映像
58
00:03:43,590 --> 00:03:49,030
那我们把数据拿出来
59
00:03:49,040 --> 00:03:50,710
就从数据库里面
60
00:03:50,720 --> 00:03:51,750
拿出来一行
61
00:03:53,060 --> 00:03:53,980
一行的
62
00:03:54,500 --> 00:03:55,940
各个列
63
00:03:55,950 --> 00:03:58,060
姓、名、家属人数
64
00:03:59,070 --> 00:04:01,500
然后创建一个Person对象
65
00:04:03,850 --> 00:04:13,350
创建,然后把它添加到注册表里面
66
00:04:16,650 --> 00:04:19,640
添加进来,ID就是它的键
67
00:04:20,640 --> 00:04:22,030
对象放这里
68
00:04:30,330 --> 00:04:32,930
一个一个就这样,这个一样的
69
00:04:55,630 --> 00:04:57,540
还有1行
相关文章:
[图解]企业应用架构模式2024新译本讲解17-活动记录1
1 00:00:01,070 --> 00:00:04,180 下一个我们要说的就是 2 00:00:04,190 --> 00:00:06,740 活动记录模式了 3 00:00:07,640 --> 00:00:11,210 同样是数据源架构模式 4 00:00:12,300 --> 00:00:18,480 里面的一个,活动记录 5 00:00:18,490 --> 00…...
[C++深入] --- malloc/free和new/delete
1 new运算符的拓展 1.1 自由存储区与堆的概念 在C++中,内存区分为5个区,分别是堆、栈、自由存储区、全局/静态存储区、常量存储区。 自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。 new操作符从自由存储区(free st…...
Spcok测试代码抛异常场景
测试代码抛异常场景 class ExceptionSpec extends Specification {def validateService new ValidateService()Unrolldef "验证UserInfo"() {when: "调用校验方法"validateService.validateUser(user)then: "捕获异常并设置需要验证的异常值&qu…...
【漏洞复现】脸爱云一脸通智慧管理平台 SystemMng 管理用户信息泄露漏洞(XVE-2024-9382)
0x01 产品简介 脸爱云一脸通智慧管理平台是一套功能强大,运行稳定,操作简单方便,用户界面美观,轻松统计数据的一脸通系统。无需安装,只需在后台配置即可在浏览器登录。 功能包括:系统管理中心、人员信息管理中心、设备…...
新手如何入门Web3?
一、什么是Web3? Web3是指下一代互联网,它基于区块链技术,致力于将各种在线活动变得更加安全、透明和去中心化。Web3是一个广义的概念,涵盖了包括数字货币、去中心化应用、智能合约等在内的多个方面。它的主要特点包括去中心化、…...
React.FC`<ChildComponentProps>`解释
代码场景 ParentComponent.tsx import React, { useState } from react; import ChildComponent from ./ChildComponent;function ParentComponent() {const [childData, setChildData] useState<string>();const handleChildData (data: string) > { // 可以直接…...
2024-06-24力扣每日一题
链接: 503. 下一个更大元素 II 题意 循环数组,找出每个元素的往后最近且大于它的元素 解: 今天没试暴力啊,大概率是过不了的 思路就是先找到最大的数,最大数的结果肯定是-1,然后倒着遍历数组…...
pyhon模块以及常用的第三方模块
import my_info as info print(info.name) info.show()from my_info import * print(name) show() pyhon中包的导入 import admin.my_admin as ad # 包名.模块名 admin是包名,my_admin是模块名print(ad.name) print(ad.info())from admin import my_admin as ad # …...
shell脚本—快速修改centos网络配置
shell-文本中自行修改想要的配置 #!/bin/bash# 网卡名称 eth"eth0"# IP 地址 ipaddr"192.168.1.100"# 子网掩码 netmask"255.255.255.0"# 网关 gateway"192.168.1.1"# 写入配置文件 echo "BOOTPROTOstatic" > /etc/sysc…...
线程池概念、线程池的不同创建方式、线程池的拒绝策略
文章目录 💐线程池概念以及什么是工厂模式💐标准库中的线程池💐什么是工厂模式?💐ThreadPoolExecutor💐模拟实现线程池 💐线程池概念以及什么是工厂模式 线程的诞生是因为,频繁的创…...
示例:WPF中如何绑定ContextMenu和Menu
一、目的:开发过程中,有些模块的右键ContextMenu菜单是需要动态显示的,既是根据不同条件显示不同的菜单,很多是通过代码去生成ContextMenu的MenuItem,本文介绍通过绑定的方式去加载ContextMenu,Menu菜单栏的…...
区块链小故事
大灰狼与小白兔 一天兔子妈妈出门了,在大门上安装了一个区块链的门把手,这个门把手只有兔子妈妈、小兔子、以及另一个客人都同意的时候,才会开门,有一天客人a的钥匙丢了,被大灰狼捡到了,大灰狼于是去开门&…...
Java | Leetcode Java题解之第167题两数之和II-输入有序数组
题目: 题解: class Solution {public int[] twoSum(int[] numbers, int target) {int low 0, high numbers.length - 1;while (low < high) {int sum numbers[low] numbers[high];if (sum target) {return new int[]{low 1, high 1};} else i…...
项目训练营第三天
项目训练营第三天 注册登录测试 前面我们编写了用户注册、登录的逻辑代码,每编写完一个功能模块之后,我们都要对该模块进行单元测试,来确保该功能模块的正确性。一般情况下使用快捷键Ctrl Shift Insert,鼠标左击类名可以自动生…...
计算机组成原理 | CPU子系统(1)基本概述
基本结构模型 运算与缓存部件 数据寄存部件 PSW不是很清楚 存储器是什么?属于那个结构里? 时序处理部件 cpu是大脑,控制器是神经元 ①通过硬件产生控制信号 ②通过软件产生控制信号 外频(系统时钟信号),…...
无引擎游戏开发(2):最简游戏框架 | EasyX制作井字棋小游戏I
一、EasyX中的坐标系 不同于数理中的坐标系,EasyX中的y轴是竖直向下的 二、渲染缓冲区 之前的程序添加了这三个函数改善了绘图时闪烁的情况: 小球在"画布“上移动的过程就是我们在调用绘图函数,这个”画布“就是渲染缓冲区,先绘制的内…...
排书 IDA*
原题链接 题目描述 给定 n 本书,编号为 1∼n。 在初始状态下,书是任意排列的。在每一次操作中,可以抽取其中连续的一段,再把这段插入到其他某个位置。我们的目标状态是把书按照 1∼n 的顺序依次排列。求最少需要多少次操作。 输…...
playwright录制脚本原理
Paywright录制工具UI 在上一篇博客中介绍了如何从0构建一款具备录制UI测试的小工具。此篇博客将从源码层面上梳理playwright录制原理。当打开playwright vscode插件时,点击录制按钮,会开启一个新浏览器,如下图所示,在新开浏览器页…...
awk脚本监控
awk脚本监控 使用脚本监控内存,cpu和硬盘的根目录,超过80%提示用户,写成函数库的行,每天早上 的8.50分,执行一次脚本 现在脚本中写需要的内容 cpuu () {aa$(top -b -n 1 |awk NR3 {printf "%.F",$2$4})if …...
Python高压电容导电体和水文椭圆微分
🎯要点 🎯二维热传导二阶偏微分方程 | 🎯调和函数和几何图曲率 | 🎯解潮汐波动方程 | 🎯解静止基态旋转球体流体运动函数 | 🎯水文空间插值 | 🎯流体流动模拟求解器 | 🎯随机算法解…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
