当前位置: 首页 > 网络应用技术

基于Gorm的插头 - 原理分析和开发实际战斗

时间:2023-03-06 01:50:31 网络应用技术

  重大的历史和技术债务通常会引起头痛。无论是业务的业务模型是否可以有效地抽象,以及系统的基础是否合理。可扩展的插件系统可以帮助我们确定许多不必要的依赖性并支持更多功能以低成本。

  业务模型的抽象在很大程度上是。这取决于做事的人(包括PM,RD相关所有者)是否对业务有足够的了解,应由区分所支持的,何时拒绝以及理想的需求解决方案。这并不容易。不仅很难清楚地思考,而且很难达成共识。

  假设对业务模型的理解就足够了。作为研究和开发,我们如何设计整个系统以保持敏捷且易于扩展。每个更改都可以在基本上与需求规模相匹配的范围内控制,而不是每次移动。[基础],这非常重要。

  在个人经验方面,要设计理想的基础,最好的方法是查看出色的框架和出色的开源代码。

  因为有必要在开源项目的领域中,大兄弟不会编写非常限于某个业务的逻辑,并且还将更加体贴扩展功能。学习更多的开源项目和插件-in设计,这对于个人成长非常有用。

  今天,让我们看一下Gorm的插件设计是如何的,以及如何为业务开发有用的插件。

  代码仓库:https://github.com/go-gorm/gorm/gorm

  在中间,我们可以找到插头-in的接口定义:

  让我们看一下插头如何通过源代码生效。

  首先,在gorm.config中,我们可以找到插件类型字段,定义一个插件字段,与插件的映射相对应。配置对象支持次要的后术语。根据注释,可以知道,这是在db链接后调用插件的初始化方法以初始化每个插头-in。

  当我们通过OPEN获得Gorm.db对象时,我们将初始化一个空的映射[String]插件{},并将相应的配置分配给DB对象。

  DB对象可以接受插件。目前,将完成注册,并将初始化方法初始化以执行通过插件。

  注意:实际上,在阅读了源代码后,似乎没有地方wayInitialize方法调用config.at在目前,它仍然需要依靠此db.use方法将插件注册到db对象中并初始化它。(如果您理解错误的话,请评论并更正)

  

  看到这一点,我们会发现,实际上,Gorm本质上是诸如Inzeries之类的初始化方法。这里非常有趣。作为使用Gorm的业务团队,我需要以初始化的方法表达插件逻辑。因此,当我执行CRUD操作时,Gorm如何看待?

  这实际上是Gorm Design中的经典回调能力。LET来看看官方文档的描述:

  Gorm Itset全部由供电,它的回调为、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、r

  回调已注册到全局,而不是会话级,如果您使用不同的背面进行研究,则需要初始化另一个。

  那么什么是回调?

  让我们回顾一下。在最后一部分中,当我看到Config时,我实际上就有了:

  每个DB对象都对应于一个回调映射,该映射已注册了一堆处理器,每个处理器对应于一组回调对象,包括之前,之后。

  它可能无法在这里看到原则,不用担心。让我们看看,如果我是一个纯粹的new Gorm.db对象,那么默认回调属性是什么?

  您找到了吗?初始化时,实际上是Crud + Row + Raw。有六个说明。注册您自己的处理器,没有各种钩子,但是只需将gorm.db对象传递给。

  我们可以获取相应的处理器(包含在create(),query(),update()和其他方法中实际添加的实际回调对象。此处的实现本质上是从地图中的值。

  在这一点上,只需总结一些涉及的概念的定位即可。

  因此,当我们执行Gorm方法调用(例如任何类型的CRUD)时,我们如何使用回调的机制?

  实际上,这很简单。让我们看一下finisher_api.go中的实现:

  你找到了吗?

  所有调用db对象的回调变量,获取相应操作的处理器,并执行execute方法。没有什么类型,本质是相同的。其他finisher_api仅在中间有一些处理步骤。相同的:

  可以在这里看到Gorm本身取决于回调系统。无论我们期望做什么,我们最终都会称呼处理器的执行方法。

  现在,重点已经聚集在这里,让我们看一下处理器的执行所做的事情。

  上面的代码是简化的版本,我们直接查看键。处理器的执行方法本质上是三件事:

  前两个步骤中的问题不是很大。建议不熟悉Reflexes的学生对它进行查看,而收获绝对不是很小。我们专注于第三个。

  当我们将两个代码放在一起时,问题就会出现。我们可能可以猜测上一个步骤[]*回调应该是我们注册的各种回调函数。然后,FNS看起来非常相似。这个是从哪里来的?

  实际上,两者本质上是一件事情,FN可以被视为最终过程。

  实际上,即使您不谈论开发人员自定义回调和插头-In,GORM也可以单独执行最基本的CRUD操作,这是通过回调机制完成的。与开发人员定义的回调,也会有一个可能需要执行的大量回调功能。

  问题到了。在各种回调之间,可能存在相互依赖性,这在插件设计中也很常见。

  我们看到,当寄存器实际上是回调函数时,它是数组中的直接附加功能,而触发了编译操作。此编译正在遍历整个数组。根据以前的属性,很明显,每个回调的最终执行顺序均给FNS变量。

  如果我们希望以前执行回调,请在此处使用此处和之后声明的接口。如果要删除回调或更换,则可以使用删除并替换。成本非常低。盖尔将在我们注册时通过编译计算最终顺序。在SortCallbacks函数中,计算方法不再进一步。如果您有兴趣,可以直接查看源代码。

  好的,我们意识到回调的底层。那么呼叫方如何使用?是否有示例?Gorm的默认回调是最好的演示。LET看看:

  尽管旅行很多,但您可以一目了然地理解它。这是为了添加6个操作的回调。本质上,使用了暴露于外界的处理器的寄存器方法。

  例如,我现在有一个创建场景,我可以以这种方式注册回调:

  此外,我们还可以发现,我们还可以发现DB的配置实际上包含SkipdeFaultTransaction bool配置。默认情况下将在[Trassaction]中执行gorm,但是如果您通过配置进行配置,Gorm将感觉到它,并且会感觉到它,并且然后请勿注册相应的回调。

  好的,在理解回调之后,逻辑是通过。尽管我们只用一个可以使用的API编写一个插头 - 因为Gorm提供了一个完整的回调系统,如果我们想做我们想做的事情,请注册在相应操作之前和之后自定义回调。

  插件主要是通过依赖回调来实现的,因此请记住查看默认值的回调名称。例如,我希望在查询后进行一些操作。在默认回调中查看这些操作。

  然后,您可以直接注册后期的功能。我们将稍后再详细讨论。

  我们可以建立索引结果的结构体。执行真实SQL后,执行解释以查看

  完整的链接加租户判断有时很麻烦,插件中的代码将令人耳目一新。它是在Gorm:查询回调之前执行的。

  很多时候,我们需要在将数据写入数据库之前检查数据格式。目前,我们可以使用插件来实现:

  参考:https://sementfault.com/a/1190000039070187

  在启动时间戳之前,阅读了它,该需要时间。

  此处使用了Instanceget和Instanceset,该语句中实质上是维护sync.map的映射,以提供链接级别的存储和读取功能。

  原始:https://juejin.cn/post/70979999127300014093