跳转到内容

模型

重要

模型及模型间关系的定义既是对具体业务的设计和抽象,也是驱动由 Trantor 构建的中后台系统的约定。

类别

定义

定义模型注解

Trantor 通过注解(不同类型注解不同)声明模型。用户在声明模型时,Trantor 提供了两个基类 BaseModel<ID>(继承 RootModel) 和 RootModel<ID> 供用户继承。其中的泛型 ID 用于指定模型主键类型,可选 Long 和 String 。两者的最大区别是 RootModel 中只包含 id 字段,BaseModel 还包含了 createdBy 、updatedBy 、createdAt 、updatedAt 、isDeleted 等一系列内置字段。当声明持久化模型时,建议使用 BaseModel ,当然也可以使用 RootModel 。

@Data
@Model(name = "Item category", mainField = ItemCategoryBO.name_field)
public class ItemCategoryBO extends BaseModel<Long> {
@Field(name = "category code", nullable = false)
private String code;
@Field(name = "category name", nullable = false)
private String name;
}

@Model

package io.terminus.trantorframework.api.annotation;
import io.terminus.trantorframework.api.RootModel;
import java.lang.annotation.*;
/**
* 用于注解模型声明
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Model {
/**
* 模型名称,选填
*/
String name() default "";
/**
* 模型主字段,主字段是在部分内建场景中,需要展示模型记录时展示的字段(例如在下拉搜索框中搜索到的记录)
*/
String mainField() default RootModel.id_field;
/**
* 描述信息
*/
String desc() default "";
/**
* id 生成策略
* 当 BaseModel 的 ID 泛型为 Long 时,支持自定义或自增;
* 当 BaseModel 的 ID 泛型为 String 时,支持自定义或自增模板或 UUID
*
* @see IDRule
*/
IDRule idRule() default @IDRule();
/**
* 索引
*
* @see Index
*/
Index[] indexes() default {};
/**
* 字段组配置
*
* @see FieldGroup
*/
FieldGroup[] fieldGroups() default {};
/**
* 删除策略, 默认规则为逻辑删除
*/
DeleteStrategy deleteStrategy() default DeleteStrategy.Logical;
/**
* 分表策略
*/
Partition partition() default @Partition(enabled = false);
/**
* 模型配置
*/
ModelConfig config() default @ModelConfig();
/**
* 快照配置
*/
Snapshot snapshot() default @Snapshot(enabled = false);
/**
* 树配置
*/
Tree tree() default @Tree(enabled = false, parentField = "");
/**
* 如果为True, 则表示该类不是一个完整的实体, 只是一个模型基类
*/
boolean superClass() default false;
}

@IDRule

public @interface IDRule {
String UUID = "UUID";
String AUTO_INCREMENT = "AUTO_INCREMENT";
String CUSTOM = "CUSTOM";
/**
* 除了 UUID 、AUTO_INCREMENT 、CUSTOM 三个静态项外,还支持模板格式化
* 当 ID type 为 Long 时,支持 CUSTOM 和 AUTO_INCREMENT,默认为 AUTO_INCREMENT
* 当 ID type 为 String 时,支持 CUSTOM 、UUID 和模板格式化,默认为 UUID
* 模板格式化可以是 "A" 或 "A[00123]" 这样的类似格式
* "A" 意思是从将 "A" 作为前缀连上从 1 开始的自增数字
* "A[00123]" 意思是将 [00123] 部分替换为从 123 开始的自增数字,并补 0 到指定位数
*
* 当设为 CUSTOM 时,Trantor 和 DS 不会再为业务生成 ID ,需要业务方自己 set ID 到模型实例中
*/
String rule() default "";
}

@Index

public @interface Index {
/**
* 索引 key ,不填时会自动按 columns 生成;
* 例如 columns = {"id", "name"} ,那么就会变成 idx_id_name(或者 uk_id_name ,如果 unique = true);
* 建议不填
*/
String name() default "";
/**
* 被索引的列,值为模型字段名
*/
String[] columns();
/**
* 是否惟一索引
*/
boolean unique() default false;
}

@FieldGroup

Trantor 中部分页面和机制是内置的,并不能通过编辑视图 DSL 文件来改变。例如模型对象 hover 时弹出的浮层;全局搜索时展示的数据列表;模型选择器的弹出框等。字段组便是用来在这些场景下指定模型应该展示哪些字段的。

目前有三种字段组,每种仅可定义一个,分别为:

  • FieldGroupType.SEARCH_SHOW 搜索展示字段组,用于全局搜索时,模型数据 Table 的展示列。
  • FieldGroupType.DEFAULT_SHOW 默认展示字段组,用于模型对象 hover 浮层,模型选择器弹出 Table 列。
  • FieldGroupType.SEARCHABLE 可搜字段组,用于指定在模糊搜索框(全局搜索、Table)搜索时会检索的字段。
public @interface FieldGroup {
/**
* 字段组类型
*/
FieldGroupType type() default FieldGroupType.DEFAULT_SHOW;
/**
* 字段组包含的字段名称
*/
String[] fieldName();
}

DeleteStrategy

public enum DeleteStrategy {
@Label("逻辑删除")
Logical,
@Label("物理删除")
Physical
}

@Partition

public @interface Partition {
enum Strategy {
Hash, StrHash, MM
}
/**
* 是否开启分表
*/
boolean enabled();
/**
* 分表键
*/
String field() default "";
}

@ModelConfig

@Target({})
@Retention(RUNTIME)
public @interface ModelConfig {
/**
* 是否支持搜索
*/
boolean enableSearch() default false;
/**
* 是否支持导入
*/
boolean enableImport() default false;
/**
* 是否支持导出
*/
boolean enableExport() default false;
}

@Snapshot

  • 可以通过 @Snapshot(enabled = true) 配置是否派生出快照模型

  • generateStrategy:快照的生成策略,指当业务模型产生什么类型的事件时备份当时数据作为快照,目前只有 OnChange 事件会产生快照对象。

public @interface Snapshot {
enum GenerateStrategy {
OnChange
}
/**
* 是否开启快照
*/
boolean enabled() default true;
/**
* 快照的生成策略
*/
GenerateStrategy generateStrategy() default GenerateStrategy.OnChange;
}

内建视图

业务模型、搜索模型、快照模型有 3 个内建页面 :

  • {modelKey}__List__builtIn: 列表页,为模块配置菜单时可选择模型 List 的内建视图
  • {modelKey}__Detail__builtIn:详情页
  • {modelKey}__Form__builtIn: 表单页,用于新增和编辑

配置模型有 2 个内建页面:

  • {modelKey}__SettingDetail__builtIn,详情页
  • {modelKey}__SettingForm__builtIn, 表单页,用于新增和编辑

@BuiltInView

Trantor 目前提供了内建视图,但内建视图过于简单,为了提高内建视图的可玩性,Trantor 提供了内建视图注解@BuiltInVIew,用于渲染内建视图。目前仅支持GroupField渲染

public @interface BuiltInView {
/**
* 字段组,效果为视图DSL的<GroupField></GroupField>
*/
GroupField[] groupFields() default {};
}

GroupField 仅针对 Detail 和 Form 类型的内建视图生效

public @interface GroupField {
/**
* 标题
*/
String title() default "";
/**
* 当前分组下的field是否单行展示
*/
boolean singleColumn() default false;
/**
* 组里面的字段,即用DSL中<GroupField></GroupField>包裹的字段
*/
String[] fieldNames();
}

示例:

@Model(name = "商品")
@BuiltInView(
groupFields = {
@GroupField(title = "基本信息", fieldNames = {ItemBO.itemName_field, ItemBO.itemNumber_field, ItemBO.itemType_field}),
@GroupField(title = "其他信息", singleColumn = true, fieldNames = {ItemBO.desc_field, ItemBO.itemImage_field}
)}
)
public class ItemBO extends BaseModel<Long> {
@Field(name = "商品名称")
private String itemName;
@Field(name = "商品编号")
private String itemNumber;
@Field(name = "商品类型")
@DictionaryMeta(ItemTypeDict.class)
private String itemType;
@Field(name = "商品详细描述")
private String desc;
@ImageMeta
@Field(name = "商品图片")
private String itemImage;
@Field(name = "商品价格")
private BigDecimal itemPrice;
}

视图渲染效果:

image-20210527174918085

模型间关系

Trantor 通过在模型上定义关联关系字段来描述模型间关系,支持所有 OneToOne 、OneToMany 、ManyToOne 和 ManyToMany 四种关系,详情请查看 link-relationship