在 Grails 中对域实例进行版本控制以供批准
Posted
技术标签:
【中文标题】在 Grails 中对域实例进行版本控制以供批准【英文标题】:Versioning domain instances for approval in Grails 【发布时间】:2014-02-01 06:23:00 【问题描述】:我正在寻找扩展 Grails CRUD 生成功能的最佳方法。它应该是一个 Grails 插件,为以下功能提供额外的生成器:
应保存扩展域实例的任何更改(作为版本 它)的历史 一个实例只能激活一个版本 用户应该能够激活实例的一个版本( 当前活动的实例应该被停用),它没有被创建 由他(四眼原则) 有差异视图很不错对 Grails 开箱即用脚本的干预应尽可能少。 到目前为止,我确定了 3 种实施设计策略:
-
具有相同架构的镜像表,其中包含版本(双精度
域/表的计数)。激活的版本将被复制
到本机域,反之亦然。
在域类中使用鉴别器。一些新的列将被添加到域中(如状态 [active,notActive]、lastUpdatedBy、
最后更新日期…)
(反)使用 BLOB 将实例序列化到特殊域(例如,作为 JSON 的 domain.properties)
任何解决方案都有利有弊。实施它的最佳方法是什么?或许还有更简单的方法。
【问题讨论】:
从未尝试过,但您可能会觉得refaktor.blogspot.co.uk/2012/08/… 有趣? @tim_yates 请将其发布为答案,以便我接受。在你的建议中使用了一个名为 Envers 的休眠插件。它实现了我的问题中描述的第一个策略。它工作正常。唯一的缺点是,数据库更改必须在事务中,而控制器则不是这样。 独立于策略,利用 Grails 中的动态脚手架来实现它们是个好主意。对于每个需要特殊功能的域,创建一个空的控制器,脚手架 = true。然后安装模板并修改它们。例如。更改列表操作以过滤掉非活动对象。 【参考方案1】:我一直在 Grails 中开发一个系统,该系统充分利用了版本概念(正如您在上面提到的)。我的方法是您问题中列出的第二个方法。
我创建了两个字段:internalVersion e disabled。每个需要是 Versionable 的类都必须实现一个名为 Versionable 的接口。
我将尝试在此处解释使用版本功能所必需的场景之一(请原谅我的英语)。
使用这个概念的系统是一个商业系统,其中有一个名为 Quote 的类。
每个报价都可以有一个或多个版本,其中只有最后一个版本有效。每个报价及其版本都是根据与特定客户的协商生成的。这样,客户向我们询问报价,如果由于某种原因他不喜欢价格(例如),我们可以生成带有一些折扣的新版本。每个报价都有一个唯一的代码,跟在当前版本之后,例如:QT-000022/0(第一版)、QT-000022/1(第二版)。
为了生成一个新版本,我使用了一种克隆当前对象的方法(使用一种完整且深度的另存为)。我将所有内容(属性和集合)复制到一个新对象中。
clone 方法标识该类实现了 Versionable 接口并执行以下操作:
oldQuote.disabled = true
newQuote.internalVersion = oldQuote.internalVersion + 1
这样可以确保只启用一个版本。
希望你能理解我的做法。
【讨论】:
覆盖克隆方法是个好主意。如果在列上创建索引,它不会有任何性能问题。您仍然有 2.nd 选项的缺点,即它对应用程序不透明。每个查询都应该知道至少“禁用”列。以上是关于在 Grails 中对域实例进行版本控制以供批准的主要内容,如果未能解决你的问题,请参考以下文章