概念
本节解释动态模型(Dynamic Model)背后的主要理念:涉及的实体类型、模型的定义和版本化方式、如何在运行时应用变更、数据存储位置以及支持的数据库。
静态实体与动态实体
动态模型区分两种实体:
-
静态实体 是应用程序中的常规实体。被编译为 Java 类,在类路径中使用。
-
动态实体 在运行时定义,由框架生成。不存在于应用程序源代码中。
静态实体和动态实体都可以添加动态属性。也就是说,既可以用新属性丰富已有的应用程序实体,也可以独立地引入仅在运行时存在的全新实体。
模型定义
动态模型是枚举、实体、属性和视图的声明性描述。可以在管理 UI 中以图形方式编辑:创建实体、添加带有类型和约束的属性、定义枚举,以及声明视图和菜单项。
在后台,动态模型被序列化为 YAML。在使用图形化编辑器工作时,不直接编辑 YAML,但 YAML 形式便于审查、导出和导入。有关文件中元素、支持的值和默认值的完整列表,请参见 YAML 参考。
版本化与部署
模型定义作为一组版本化配置存储在数据库中。每次部署会保存一个新版本,只能有一个版本处于激活状态。之前的版本都会保留,可以在 模型历史 里查看。若要退回一个早期的版本,可以从历史里复制其 YAML 然后重新部署。
应用程序启动时,框架可以自动使用激活的版本,从而运行中的应用程序能反映最新部署的模型。此行为由 jmix.dynmodel.deploy-on-app-start 属性控制。
应用变更
当模型变更时,框架会从新的模型定义生成 模型元数据 并进行原子化发布。在发布完成之前,运行中的应用程序会继续使用前一个发布的内容,因此,发布失败不会造成仅更新部分模型的问题。
破坏性清理(例如删除不再属于模型的列或表)会延迟执行,直到不再有任何工作使用前一个发布时为止。这可以在模型变更时保持正在运行的工作的一致性。
已打开的视图不会自动切换,需要重新加载后才会获取变更。
框架还会检查在打开模型编辑时,没人发布其他的模型。如果有人在你编辑过程中发布了,则会拒绝你的发布,从而不会静默覆盖别人的改动。此时,需要你重新加载模型配置并重复你个改动。
集群
Jmix 3.1+
动态模型可以在应用程序集群中运行。当启用集群支持时:
-
在一个节点发布的模型会发布至其他节点,无需重新启动。
-
整个集群中,同一时刻只能运行一个发布。如果一个用户尝试发布一个正在其他节点发布的模型,则会拒绝当前的发布,并告知用户此时谁正在发布模型。需要等待对方完成后再尝试。
启用集群支持:
-
将 jmix.dynmodel.cluster.enabled 属性设置为
true。 -
将 悲观锁 扩展组件添加到项目。其中包含集群的发布锁。如果启用了集群支持而缺少该扩展组件,应用程序不会启动。
-
按照 集群通信 中的说明配置节点之间的集群通信。已发布模型和发布锁的消息都需要走这个通道。如果没配置,则在一个节点上发布的模型只有在其他节点重启时才会到达。
jmix.dynmodel.cluster.apply-lock-timeout-sec 属性设置发布期间持有发布锁的节点停止的超时时限。请将其设置为大于应用程序中最长发布耗时的值。