当前位置: 首页 > news >正文

重构数据访问层-优化数据访问的开发

        重新整理了一下过去开发的框架,在准备开发新项目时候,重新整理了一下思路,感觉数据访问层还是很鸡肋。过去几年中,急于完成项目开发和交付,框架都是迭代过来的,虽然满足了开发需求,但是,从安全性、复杂度等方面看,还是有不足的。

        从安全性角度看,查询参数和提交数据的安全校验必须增加。虽然已经使用了对象化参数传递查询参数,防止了SQL注入的情况,但是,数据合法性校验依然没有深度去实现。从过去的实践中发现,前端输入数据的随意性,例如应该是整数,用户输入了字母,但是前端没有做严格的数据限制,或者,前端就是模板生成的代码,校验不严谨,导致系统保存数据的时候,会直接报错。虽然底层对这些报错的情况做了拦截和记录日志,但是严重影响了系统性能。

        复杂度主要是指框架迭代过程中的一些冗余代码。数据访问层的设计,是基于通用性和框架性两个大方面来考虑的。通用性就是不限定映射实体的具体类型和格式,相当于兼容常规的系统开发。但是,从框架角度,特别是业务层面,这些通用的映射实体是很难满足系统框架需求的。因此在这个基础上,增加基于框架设计要求的实体基类,例如包含:

string recordId         数据行的唯一记录,通过uuid(guid)生成字符串

DateTime createDate        记录的创建时间,不允许修改

DateTime updateDate        记录最后修改时间

string createBy                记录创建人ID,这里是员工的编号,不允许修改

string updateBy                记录最后修改人的ID

bool deleted                        记录软删除标记,true表示记录被删除

还有其他一些字段的定义,就不一一列举。

        系统开发离不开与数据库的交互,框架设计初衷就是最大化简化数据交互的方法,降低开发的随意性和复杂性。

        一般来说,系统开发尽量不要直接使用数据库脚本进行数据交互。dotnet中,有丰富的orm可以选择使用,例如ef,dapper,sqlsugar,freesql等等,但是,学习这些组件,也需要花费不少时间,这是其一。其二就是程序员可能直接操作组件,进行任意性的数据操作。从数据库优化角度看,尽量单表查询,减少join表查询,然后程序员有时候为了方便,直接就来join,甚至是好几个表join,也没有注意锁的应用,在数据增加到一定程序,就出现死锁情况。

        orm提供了丰富的lambda方法进行查询,也避免了写错字段的情况。框架把insert\update\delete\get\getlist\getpagelist等方法进行了封装,可以减少95%以上的操作orm的机会,通过封装一层,屏蔽掉了orm的使用,也降低了程序员的学习难度。

        这次重构数据访问层,主要从以下几点考虑:

        一、兼容读写分离。这里两个概念,一个是,有些业务需求,数据是只能读的,例如第三方同步过来的数据。框架增加了Read/Write两层数据访问层,出现只能读的数据,则继承只读的基类即可;二个是主从数据库的读写分离,业务流程的功能代码,使用写的数据库,分析用的数据,使用读的数据库。前段时间自己开发了一个同步软件,把sqlserver数据同步到了clickhouse,读写分离不限制数据库的类型,有利于按需求选择数据库和优化系统开发。

        二、提升分布式事务的安全性。防止某个微服务宕机导致请求等待的情况,例如某个微服务已经接受了分布式事务,但是,突然就宕机了,无法接收提交事务的请求或者回滚事务的请求,导致数据的一致性被破坏。

        三、业务表单支持多个从表的通用访问。在面向对象中,不确定的数据访问层,无法赋予对应的泛型来确定对象,如果使用没有泛型的数据访问对象,根本无法使用lambda进行查询,因此,把数据访问层的接口,拆分成三组,一组是没有泛型的,一组是带实体泛型的,一组是使用逆变泛型的。这样,无论在什么情况下,都可以使用一个统配实体接口,来描述数据访问对象。

        四、更换目前的orm,过去使用ef、chloe,但是使用过程中,存在各种问题,比较了几个orm,选择freesql,比常规的orm支持更多的数据库类型,特别是clickhouse.但是替换难度有点大,尽量轻量化,为不同的数据库要建立不同的接口或者组件,按需动态加载,这里和注入有点不一样,只是用于解析不同数据或者交互的,从开发层面上看,这一层应该是透明的。

        五、强化正则表达式的提交前的数据校验。除了可以在实体属性上定义规则外,还允许在数据访问层添加或者制定验证规则。例如字段的长度、合法内容等,在不同的业务中,可能相同的字段会存在不同的校验规则。

        以下是重新设计后的数据访问层结构图。框架设计把数据归为3类

        1、基础数据,例如员工信息、部门信息这类的

        2、配置数据,流入多对多的关联表

        3、表单数据,例如采购、销售等业务单据

        

相关文章:

重构数据访问层-优化数据访问的开发

重新整理了一下过去开发的框架,在准备开发新项目时候,重新整理了一下思路,感觉数据访问层还是很鸡肋。过去几年中,急于完成项目开发和交付,框架都是迭代过来的,虽然满足了开发需求,但是&#xf…...

云计算概述报告

以下是一篇论述类文章 文章目录 I. 云计算介绍(1)云计算基本概念(2)云计算基本特征 II. 云计算发展历程(1)云计算的起源(2)云计算的发展阶段 III. 云计算特点(1&#xff…...

C++:线程库的使用

文章目录 Windows和Linux平台的线程线程构造函数模板参数包 最近发现C11的线程库还没有进行总结,因此本篇对于C11当中新增的线程库的一些基本用法进行总结 Windows和Linux平台的线程 在Linux平台下是存在一些原生的线程系统调用的,比如有pthread_creat…...

机器学习模型:决策树笔记

第一章:决策树原理 1-决策树算法概述_哔哩哔哩_bilibili 根节点的选择应该用哪个特征?接下来选什么?如何切分? 决策树判断顺序比较重要。可以使用信息增益、信息增益率、 在划分数据集前后信息发生的变化称为信息增益&#xff0c…...

20.2k stars项目搭建私人网盘界面美功能全

Nextcloud是一套用于创建网络硬盘的客户端-服务器软件。其功能与Dropbox相近,但Nextcloud是自由及开放源代码软件,每个人都可以在私人服务器上安装并执行它。 GitHub数据 20.2k stars561 watching3.2k forks 开源地址:https://github.com/ne…...

卷积篇 | YOLOv8改进之引入全维度动态卷积ODConv | 即插即用

前言:Hello大家好,我是小哥谈。ODConv是一种关注了空域、输入通道、输出通道等维度上的动态性的卷积方法,一定程度上讲,ODConv可以视作CondConv的延续,将CondConv中一个维度上的动态特性进行了扩展,同时了考虑了空域、输入通道、输出通道等维度上的动态性,故称之为全维度…...

Pytorch实用教程:torch.from_numpy(X_train)和torch.from_numpy(X_train).float()的区别

在PyTorch中,torch.from_numpy()函数和.float()方法被用来从NumPy数组创建张量,并可能改变张量的数据类型。两者之间的区别主要体现在数据类型的转换上: torch.from_numpy(X_train):这行代码将NumPy数组X_train转换为一个PyTorch张…...

深度学习pytorch好用网站分享

深度学习在线实验室Featurizehttps://featurize.cn/而且这个网站里面还有一些学习教程 免费好用 如何使用 PyTorch 进行图像分类https://featurize.cn/notebooks/5a36fa40-490e-4664-bf98-aa5ad7b2fc2f...

C语言 | Leetcode C语言题解之第2题两数相加

题目: 题解: struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {struct ListNode *head NULL, *tail NULL;int carry 0;while (l1 || l2) {int n1 l1 ? l1->val : 0;int n2 l2 ? l2->val : 0;int sum n1 n2 …...

Oracle基础

Oracle基础 Oracle,作为全球最大的数据库软件供应商,其数据库产品在企业级应用市场中占据了举足轻重的地位。Oracle数据库以高性能、高可用性、高安全性以及强大的数据管理能力赢得了广泛认可。本文旨在为读者提供Oracle数据库的基础知识,帮…...

从0到1实现RPC | 04 负载均衡和静态注册中心

一、Router的定义 Router路由用于预筛选,Dubbo有这样的设计,SpringCloud没有。 二、LoadBanlancer定义 负载均衡器:默认取第一个 当前支持随机和轮询两种负载均衡器。 随机:从所有provider中随机选择一个。 轮询:每…...

卷积神经网络-池化层

卷积神经网络-池化层 池化层(Pooling Layer)是深度学习神经网络中的一个重要组成部分,通常用于减少特征图的空间尺寸,从而降低模型复杂度和计算量,同时还能增强模型的不变性和鲁棒性。 池化操作通常在卷积神经网络&am…...

【干货集】C# XmlHelper帮助类操作Xml文档的通用方法汇总

前言 该篇文章主要总结的是自己平时工作中使用频率比较高的Xml文档操作的一些常用方法和收集网上写的比较好的一些通用Xml文档操作的方法(主要包括Xml序列化和反序列化,Xml文件读取,Xml文档节点内容增删改的一些通过方法)。当然可…...

Coursera自然语言处理专项课程04:Natural Language Processing with Attention Models笔记 Week01

Natural Language Processing with Attention Models Course Certificate 本文是学习这门课 Natural Language Processing with Attention Models的学习笔记,如有侵权,请联系删除。 文章目录 Natural Language Processing with Attention ModelsWeek 01…...

mysql MHA高可用

目录 工作原理 Node(节点) Manager(管理器) Node和Manager的协作 故障转移流程 优势 配置和管理 配置主从复制 MHA实现高可用 MySQL Master High Availability(MHA)是一个开源的高可用性解决方案&…...

android 扫描二维码

1.在你的build.gradle文件中添加Mobile Vision库的依赖: dependencies {implementation com.google.android.gms:play-services-vision:20.1.0 } 2.创建一个新的Activity来处理扫描过程。 import android.Manifest; import android.content.pm.PackageManager; i…...

[flink 实时流基础] 输出算子(Sink)

学习笔记 Flink作为数据处理框架,最终还是要把计算处理的结果写入外部存储,为外部应用提供支持。 文章目录 **连接到外部系统****输出到文件**输出到 Kafka输出到 mysql自定义 sink 连接到外部系统 Flink的DataStream API专门提供了向外部写入数据的方…...

case语句

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 CASE 语句的执行方式与 IF...THEN...ELSIF 语句的执行方式类似,但是它是通过一个表达式的值来决定执行哪个分支 CASE 选择器表达式 WHEN 条件 1 THEN 语句序列 …...

全国加油站分布数据/停车场分布/公园分布/景区分布/保护区分布/poi感兴趣点

加油站是指为汽车和其它机动车辆服务的、零售汽油和机油的补充站,一般为添加燃料油、润滑油等。由于加油站所销售的石油商品具有易燃爆、易挥发、易渗漏、易集聚静电荷的特性,故加油站以“安全”为第一准则。在加油站内严禁烟火,严禁从事可能…...

单片机简介(一)

51单片机 一台能够运行的计算机需要CPU做运算和控制,RAM做数据存储,ROM做程序存储,还有输入/输出设备(串行口、并行输出口等),这些被分为若干块芯片,安装在主板(印刷线路板&#xf…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子&#xff08…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

【Oracle APEX开发小技巧12】

有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...

Bean 作用域有哪些?如何答出技术深度?

导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答&#xff0c…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...