模型类型
模型类型
本文会介绍不同类型模型以及其简单的应用场景,方便大家理解不同类型模型的用途 模型分为元模型和业务模型。元数据是指描述应用程序运行所必需的数据、规则和逻辑的数据集;元模型是指用于描述内核元数据的一套模式集合;业务模型是指用于描述业务应用元数据的一套模式集合。 元模型分为模块域、模型域和函数域三个域。域的划分规则是根据元模型定义数据关联关系的离散性来判断,离散程度越小越聚集到一个域。而我们在开发中涉及的就是业务模型
模型类型
- 抽象模型:往往是提供公共能力和字段的模型,它本身不会直接用于构建协议和基础设施(如表结构等)。
- 传输模型:用于表现层和应用层之间的数据交互,本身不会存储,没有默认的数据管理器,只有数据构造器
- 存储模型:存储模型用于定义数据表结构和数据的增删改查(数据管理器)功能,是直接与连接器进行交互的数据容器。
- 代理模型:用于代理存储模型的数据管理器能力的同时,扩展出非存储数据信息的交互功能的模型。
模型定义种类
模型定义就是模型描述,不同定义类型,代表计算描述模型的元数据的规则不同
- 静态模型定义:模型元数据不持久化、不进行模型定义的计算(默认值、主键、继承、关联关系)
- 静态计算模型定义:模型元数据不持久化但初始化时进行模型定义计算获得最终的模型定义
- 动态模型定义:模型元数据持久化且初始化时进行模型定义计算获得最终的模型定义
静态模型定义需要使用@Model.Static
进行注解;静态计算模型定义使用@Model.Static(compute=true)
进行注解;动态模型定义不注解@Model.Static
注解。
安装与更新
使用@Model.model
来配置模型的不可变更编码。模型一旦安装,无法在对该模型编码值进行修改,之后的模型配置更新会依据该编码进行查找并更新;如果仍然修改该注解的配置值,则系统会将该模型识别为新模型,存储模型会创建新的数据库表,而原表将会rename为废弃表。 如果模型配置了@Base
注解,表明在设计器中该模型配置不可变更;如果字段配置了@Base
注解,表明在设计器中该字段配置不可变更。
基础配置
模型基类
所有的模型都需要继承以下模型中的一种,来表明模型的类型,同时继承以下模型的默认数据管理器(详见模型的数据管理器一节)。
- 继承
BaseModel
,构建存储模型,默认无id属性。 - 继承
BaseRelation
,构建多对多关系模型,默认无id属性。 - 继承
TransientModel
,构建临时模型(传输模型),临时模型没有数据管理器,也没有id属性。 - 继承
EnhanceModel
,构建数据源为ElasticSearch
的增强模型。
快捷继承
- 继承
IdModel
,构建主键为id的模型。继承IdModel的模型会数据管理器会增加queryById方法(根据id查询单条记录) - 继承
CodeModel
,构建带有唯一编码code的主键为id的模型。可以使用@Model.Code
注解配置编码生成规则。也可以直接覆盖CodeModel
的generateCode
方法或者自定义新增的前置扩展点自定义编码生成逻辑。继承CodeModel的模型会数据管理器会增加queryByCode方法(根据唯一编码查询单条记录) - 继承
VersionModel
,构建带有乐观锁,唯一编码code且主键为id的模型。 - 继承
IdRelation
,构建主键为id的多对多关系模型。
模型继承关系
AbstractModel
抽象基类是包含createDate创建时间、writeDate更新时间、createUid创建用户ID、writeUid更新用户ID、aggs聚合结果和activePks批量主键列表等基础字段的抽象模型。TransientModel
传输模型抽象基类是所有传输模型的基类,传输模型不存储,没有数据管理器。TransientRelation
传输关系模型是所有传输关系模型的基类,传输关系模型不存储,用于承载多对多关系,没有数据管理器。BaseModel
存储模型基类提供数据管理器功能,数据模型主键可以不是ID。IdModel
带id模型抽象基类,在BaseModel数据管理器基础之上提供根据ID查询、更新、删除数据的功能。BaseRelation
关系模型抽象基类用于承载多对多关系,是多对多关系的中间模型,数据模型主键可以不是ID。IdRelation
带id关系模型抽象基类,在BaseRelation数据管理器基础之上提供根据ID查询、更新、删除数据的功能。CodeModel
带code模型抽象基类,提供按配置生成业务唯一编码功能,根据code查询、更新、删除数据的功能。EnhanceModel
增强模型,提供全文检索能力。
抽象模型
应用场景
抽象模型本身不会直接用于构建协议和基础设施(如表结构等),而是通过继承的机制供子模型复用其字段和函数。子模型可以是所有类型的模型。比如demo模块要管理的一些公共模型字段,我们可以建一个AbstractDemoIdModel,demo模块中的实体模型就可以继承它。
使用示例
@Base
@Model.model(AbstractDemoIdModel.MODEL_MODEL)
@Model.Advanced(type = ModelTypeEnum.ABSTRACT)
@Model(displayName = "AbstractDemoIdModel")
public abstract class AbstractDemoIdModel extends IdModel implements IDataStatus {
public static final String MODEL_MODEL="demo.AbstractDemoIdModel";
@Base
@Field(displayName = "公共字段")
private String abstractString;
}
AbstractModel
概述
AbstractModel 是一个超级抽象基类,用于实现模型基本操作。提供了对数据的增删改查等操作方法。
字段
createDate
- 类型:Date
- 描述:创建时间字段。
writeDate
- 类型:Date
- 描述:更新时间字段。
createUid
- 类型:Long
- 描述:创建人ID字段。
writeUid
- 类型:Long
- 描述:更新人ID字段。
数据操作
create()
- 描述:创建单条数据。
- 入参:无
- 返回值:AbstractModel,模型数据。
createBatch(dataList: List<AbstractModel>)
- 描述:批量创建数据。
- 入参:dataList - 待新增的数据列表。
- 返回值:
List<AbstractModel>
,模型数据列表。
createOrUpdate()
- 描述:创建或更新数据。
- 入参:无
- 返回值:Integer,影响行数。
createOrUpdateWithResult()
- 描述:创建或更新数据,返回详细结果。
- 入参:无
- 返回值:
Result<AbstractModel>
,更新结果。
createOrUpdateBatch(dataList: List<AbstractModel>)
- 描述:批量创建或更新数据。
- 入参:dataList - 待新增的数据列表。
- 返回值:Integer,影响行数。
count(): Long
- 描述:按实体条件查询数据数量。
- 返回值:满足查询条件的记录数量。
count(queryWrapper: IWrapper<T>): Long
- 描述:按条件查询数据数量。
- 入参:queryWrapper - 查询条件。
- 返回值:满足查询条件的记录数量
更新操作
updateBatch(dataList: List<AbstractModel>)
- 描述:批量更新数据。
- 入参:dataList - 待更新的数据列表。
- 返回值:Integer,影响行数。
updateByPk()
- 描述:根据主键更新数据。
- 入参:无
- 返回值:Integer,影响行数。
updateByUnique()
- 描述:根据主键与唯一索引更新数据。
- 入参:无
- 返回值:Integer,影响行数。
updateByEntity(entity: AbstractModel, query: AbstractModel)
- 描述:条件更新。
- 入参:entity - 更新实体,query - 更新条件。
- 返回值:Integer,影响行数。
updateByWrapper(entity: AbstractModel, updateWrapper: IWrapper<AbstractModel>)
- 描述:条件更新。
- 入参:entity - 更新实体,updateWrapper - 更新条件。
- 返回值:Integer,影响行数。
删除操作
deleteByPk()
- 描述:根据主键删除单条记录。
- 入参:无
- 返回值:Boolean,删除结果。
deleteByPks(dataList: List<AbstractModel>)
- 描述:根据主键批量删除记录。
- 入参:dataList - 待删除的数据列表。
- 返回值:Boolean,删除结果。
deleteByUnique()
- 描述:根据主键或唯一索引删除单条记录。
- 入参:无
- 返回值:Boolean,删除结果。
deleteByUniques(dataList: List<AbstractModel>)
- 描述:根据主键或唯一索引批量删除记录。
- 入参:dataList - 待删除的数据列表。
- 返回值:Boolean,删除结果。
deleteByEntity()
- 描述:根据实体删除记录。
- 入参:无
- 返回值:Integer,删除结果。
deleteByWrapper(queryWrapper: IWrapper<AbstractModel>)
- 描述:条件删除。
- 入参:queryWrapper - 删除条件。
- 返回值:Integer,删除结果。
查询操作
queryByPk()
- 描述:根据主键查询单条记录。
- 入参:无
- 返回值:AbstractModel,模型数据。
queryOne()
- 描述:根据主键或唯一索引查询单条记录。
- 入参:无
- 返回值:AbstractModel,模型数据。
queryOneByWrapper(queryWrapper: IWrapper<AbstractModel>)
- 描述:根据条件查询单条记录。
- 入参:queryWrapper - 查询条件。
- 返回值:AbstractModel,模型数据。
queryList()
- 描述:按实体条件查询数据列表。
- 入参:无
- 返回值:
List<AbstractModel>
,模型数据列表。
queryList(int batchSize)
- 描述:按实体条件查询数据列表,可以设置batchSize。
- 入参:batchSize - 批次查询大小。
- 返回值:
List<AbstractModel>
,模型数据列表。
queryList(IWrapper<AbstractModel> queryWrapper)
- 描述:按条件查询数据列表。
- 入参:queryWrapper - 查询条件。
- 返回值:
List<AbstractModel>
,模型数据列表。
queryList(Pagination<AbstractModel> page, AbstractModel query)
- 描述:按分页和实体条件查询数据列表。
- 入参:page - 分页信息,query - 查询实体。
- 返回值:
List<AbstractModel>
,模型数据列表。
queryListByWrapper(Pagination<AbstractModel> page, IWrapper<AbstractModel> queryWrapper)
- 描述:按分页条件查询数据列表。
- 入参:page - 分页信息,queryWrapper - 查询条件。
- 返回值:
List<AbstractModel>
,模型数据列表。
queryPage(Pagination<AbstractModel> page, IWrapper<AbstractModel> queryWrapper)
- 描述:按分页条件查询数据列表。
- 入参:page - 分页信息,queryWrapper - 查询条件。
- 返回值:
Pagination<AbstractModel>
,查询分页结果。
queryMaps(queryWrapper: IWrapper<AbstractModel>)
- 描述:按条件查询数据,返回 Map 列表。
- 入参:queryWrapper - 查询条件。
- 返回值:
List<Map<String, Object>>
,Map 列表。
关联关系操作
fieldQuery(getter: Getter<T, ?>): T
- 描述:关联关系字段查询。
- 入参:
- getter - 关联关关系字段的 getter 方法。
- 返回值:包含查询字段值的模型数据。
fieldQuery(fieldName: String): T
- 描述:关联关系字段查询。
- 入参:
- fieldName - Java 字段名称。
- 返回值:包含查询字段值的模型数据。
增量更新关联关系字段
fieldSave(getter: Getter<T, ?>): T
- 描述:新增或更新关联关系字段(增量)。
- 入参:
- getter - 关联关关系字段的 getter 方法。
- 返回值:包含更新字段值的模型数据。
fieldSave(fieldName: String): T
- 描述:新增或更新关联关系字段(增量)。
- 入参:
- fieldName - Java 字段名称。
- 返回值:包含更新字段值的模型数据。
删除关联关系(增量)
relationDelete(getter: Getter<T, ?>): T
- 描述:删除关联关系(增量)。
- 入参:
- getter - 关联关关系字段的 getter 方法。
- 返回值:模型数据。
relationDelete(fieldName: String): T
- 描述:删除关联关系(增量)。
- 入参:
- fieldName - Java 字段名称。
- 返回值:模型数据。
批量操作
listFieldQuery(dataList: List<T>, getter: Getter<T, ?>): List<T>
- 描述:批量关联关系字段查询。
- 入参:
- dataList - 当前模型数据列表。
- getter - 关联关关系字段的 getter 方法。
- 返回值:包含查询字段值的模型数据列表。
listFieldQuery(dataList: List<T>, fieldName: String): List<T>
- 描述:批量关联关系字段查询。
- 入参:
- dataList - 当前模型数据列表。
- fieldName - Java 字段名称。
- 返回值:包含查询字段值的模型数据列表。
listFieldSave(dataList: List<T>, getter: Getter<T, ?>): List<T>
- 描述:批量新增或更新关联关系字段记录。
- 入参:
- dataList - 当前模型数据列表。
- getter - 关联关关系字段的 getter 方法。
- 返回值:包含更新字段值的模型数据列表。
listFieldSave(dataList: List<T>, fieldName: String): List<T>
- 描述:批量新增或更新关联关系字段记录。
- 入参:
- dataList - 当前模型数据列表。
- fieldName - Java 字段名称。
- 返回值:包含更新字段值的模型数据列表。
listRelationDelete(dataList: List<T>, getter: Getter<T, ?>): List<T>
- 描述:批量删除关联关系(增量)。
- 入参:
- dataList - 当前模型数据列表。
- getter - 关联关关系字段的 getter 方法。
- 返回值:包含更新字段值的模型数据列表。
listRelationDelete(dataList: List<T>, fieldName: String): List<T>
- 描述:批量删除关联关系(增量)。
- 入参:
- dataList - 当前模型数据列表。
- fieldName - Java 字段名称。
- 返回值:包含更新字段值的模型数据列表。
注意事项
- 方法执行涉及数据库操作,请谨慎使用。
刷新控制
enableRefreshWriteDate()
- 描述:刷新更新时间的方法。
enableRefreshWriteUid()
- 描述:刷新更新人的方法。
disableRefreshWriteDate()
- 描述:不刷新更新时间的方法。
disableRefreshWriteUid()
- 描述:不刷新更新人的方法。
传输模型
应用场景
由于传输模型没有默认的数据管理器,只有数据构造器,所以在不自定义动作的情况下,传输模型可以打开详情页、新增表单和修改表单和列表页,但是所有的动作全部为窗口动作。传输模型本身不会存储,如果是关联关系字段关联传输模型,可以将传输模型序列化存储在模型的关联关系字段上。因为没有数据管理器,所以传输模型的列表页没有分页能力。 传输模型可以承载批量修改页面、数据以及操作的载体模型。
使用示例
@Model.model(PetShopBatchUpdate.MODEL_MODEL)
@Model(displayName = "批量修改宠物商店数据状态",summary = "批量修改宠物商店数据状态")
public class PetShopBatchUpdate extends TransientModel {
public static final String MODEL_MODEL="demo.PetShopBatchUpdate";
@Field(displayName = "数据状态",required = true)
private DataStatusEnum dataStatus;
@Field(displayName = "宠物商店列表",required = true)
@Field.many2many
private List<PetShopProxy> petShopList;
}
TransientModel
概述
TransientModel 是传输模型的抽象基类。提供了初始化数据等操作方法。
数据操作
construct(data: T): T
- 描述:初始化数据的方法。
- 入参:data - 待初始化的数据。
- 返回值:T,初始化后的数据。
存储模型
应用场景
存储模型用于定义数据表结构和数据的增删改查(数据管理器)功能,是直接与连接器进行交互的数据容器。
使用示例
@Model.model(PetShop.MODEL_MODEL)
@Model(displayName = "宠物店铺")
public class PetShop extends IdModel {
public static final String MODEL_MODEL = "demo.PetShop";
@Field(displayName = "店铺名称", required = true, immutable = true)
private String shopName;
@Field(displayName = "开店时间", required = true)
private Time openTime;
@Field(displayName = "闭店时间", required = true)
private Time closeTime;
}
代理模型
应用场景
代理模型是用于代理存储模型的数据管理器能力,同时又可以扩展出非存储数据信息的交互功能的模型。
使用示例
@Model.model(PetShopProxy.MODEL_MODEL)
@Model.Advanced(type = ModelTypeEnum.PROXY)
@Model(displayName = "宠物店铺代理模型",summary="宠物店铺代理模型")
public class PetShopProxy extends PetShop {
public static final String MODEL_MODEL="demo.PetShopProxy";
@Field(displayName = "代理字段",required = true)
private String creater;
}