3.2.1 构建第一个Module

所有环境准备就绪,就让我们踏上oinone的奇妙之旅吧。先搞个demo模块【展示名为“oinone的Demo工程”,名称为“demoCore”,编码为“demo_core”】试试看,本节学习目的就是能把它启动起来,有个大概的认知。

一、后端工程脚手架

使用如下命令来利用项目脚手架生成启动工程:

  1. 新建archetype-project-generate.sh脚本,或者直接下载archetype-project-generate.sh
#!/bin/bash

# 项目生成脚手架
# 用于新项目的构建

# 脚手架使用目录
# 本地 local
# 本地脚手架信息存储路径 ~/.m2/repository/archetype-catalog.xml
archetypeCatalog=local

# 以下参数以pamirs-demo为例

# 新项目的groupId
groupId=pro.shushi.pamirs.demo

# 新项目的artifactId
artifactId=pamirs-demo

# 新项目的version
version=1.0.0-SNAPSHOT

# Java包名前缀
packagePrefix=pro.shushi

# Java包名后缀
packageSuffix=pamirs.demo

# 新项目的pamirs platform version
pamirsVersion=4.7.8

# Java类名称前缀
javaClassNamePrefix=Demo

# 项目名称 module.displayName
projectName=OinoneDemo

# 模块 MODULE_MODULE 常量
moduleModule=demo_core

# 模块 MODULE_NAME 常量
moduleName=DemoCore

# spring.application.name
applicationName=pamirs-demo

# tomcat server address
serverAddress=0.0.0.0

# tomcat server port
serverPort=8090

# redis host
redisHost=127.0.0.1

# redis port
redisPort=6379

# 数据库名
db=demo

# zookeeper connect string
zkConnectString=127.0.0.1:2181

# zookeeper rootPath
zkRootPath=/demo

mvn archetype:generate \
  -DinteractiveMode=false \
  -DarchetypeCatalog=${archetypeCatalog} \
  -DarchetypeGroupId=pro.shushi.pamirs.archetype \
  -DarchetypeArtifactId=pamirs-project-archetype \
  -DarchetypeVersion=${pamirsVersion} \
  -DgroupId=${groupId} \
  -DartifactId=${artifactId} \
  -Dversion=${version} \
  -DpamirsVersion=${pamirsVersion} \
  -Dpackage=${packagePrefix}.${packageSuffix} \
  -DpackagePrefix=${packagePrefix} \
  -DpackageSuffix=${packageSuffix} \
  -DjavaClassNamePrefix=${javaClassNamePrefix} \
  -DprojectName="${projectName}" \
  -DmoduleModule=${moduleModule} \
  -DmoduleName=${moduleName} \
  -DapplicationName=${applicationName} \
  -DserverAddress=${serverAddress} \
  -DserverPort=${serverPort} \
  -DredisHost=${redisHost} \
  -DredisPort=${redisPort} \
  -Ddb=${db} \
  -DzkConnectString=${zkConnectString} \
  -DzkRootPath=${zkRootPath}

图3-2-1-1 新建archetype-project-generate.sh脚本

  1. Linux/Unix/Mac 需要执行以下命令添加执行权限
chmod +x archetype-project-generate.sh

图3-2-1-2 添加执行权限

  1. 根据脚本中的注释修改项目变量(demo工程可无需编辑)
  2. 执行脚本
./archetype-project-generate.sh

二、后端工程结构介绍

通过脚手架生成的demo工程是我们2.4.1【oinone独特性之单体与分布式的灵活切换】一文中介绍的单模块工程结构,属于入门级的一种,麻雀虽小五脏俱全,特别适合新手学习。

  1. 结构示意图(如下图3-2-4所示)

3.2.1 构建第一个Module

图3-2-1-4 结构示意图

  1. 工程结构说明
工程名 包名 说明
pamirs-demo-api 对外api包,如果有其他模块需要依赖demo模块,则可以在其pom中引入pamirs-demo-api包
constant 常量的包路径
enumeration 枚举类的包路径
model 该领域核心模型的包路径
service 该领域对外暴露接口api的包路径
tmodel 存放该领域的非存储模型如:用于传输的临时模型
DemoModule 该类是Demo模块的定义
pamirs-demo-boot demo模块的启动类
boot 启动类的包路径
DemoApplication Demo模块的应用启动类,遵循spring boot 规范
resources/config/application-dev.yml 研发环境的yml配置文件,遵循spring boot 规范
resources/bootstrap.yml 启动的yml配置文件,遵循spring boot 规范
pamirs-demo-core
action 模型对外交互的行为的包路径
init 模块初始化工作的包路径
manager manager是 service的一些公共逻辑,不会定义为独立的function的类
service service是对应api工程中service接口的实现类,是模型的function

表3-2-1-1 工程结构说明

三、pom.xml介绍

父pom的依赖管理

  1. 一个是启动包依赖
    a. pamirs-boot里是有我们多种启动模式依赖包。教程只介绍标准启动模式
    b. pamirs-base-standard

3.2.1 构建第一个Module

图3-2-1-5 父pom的依赖管理

pamirs-domo-api

一个标准java工程,可以看出只是依赖了,我们的pamirs-base-standard
3.2.1 构建第一个Module

图3-2-1-6 pamirs-domo-api

pamirs-demo-core

一个标准java工程,可以看出只是依赖了,我们的pamirs-demo-api

3.2.1 构建第一个Module

图3-2-1-7 pamirs-domo-core

pamirs-demo-boot

把启动的时候,需要启动的module(模块)对应的jar,进行依赖引入。这样就可以在我们的yml文件中进行启动module的配置

  1. 所需module(模块)对应的jar(如下图3-2-8所示)

3.2.1 构建第一个Module

图3-2-1-8 所需module(模块)对应的jar包依赖

  1. yml文件基础配置,boot工程的yml配置详见4.1.1【模块之yml文件结构详解】一文

3.2.1 构建第一个Module

图3-2-1-9 yml文件

四、DemoModule的定义

到此我们一个oinone中的一个module对应的工程就介绍完了。到目前为止跟一般的spring boot的工程没有太多区别,就多做了一个DemoModule的定义,oinone的所有Module都继承自PamirsModule。

3.2.1 构建第一个Module

图3-2-1-10 DemoModule的定义

配置注解

通过@Module的name属性配置模块技术名称,前端与后端交互协议使用模块技术名称来定位模块。

通过@Module的displayName属性配置模块展示名称,在产品视觉交互层展现。

通过@Module的version属性配置模块版本,系统会比较版本号来决定模块是否需要进行升级。

通过@Module的priority属性配置模块优先级(数字越小,优先级越高),系统会根据优先级取优先级最高的应用设置的首页来作为整个平台的首页。

通过@Module的dependencies属性和exclusions属性来配置模块间的依赖互斥关系,值为模块编码数组。如果模块继承了另一模块的模型或者与另一模块的模型建立了关联关系,则需要为该模块的依赖模块列表配置另一模块的模块编码。

通过@Module.module配置模块编码,模块编码是模块在系统中的唯一标识。

通过@Module.Advanced的selfBuilt属性配置模块是否为平台自建模块。

通过@Module.Advanced的application属性配置模块是否为应用(具有视觉交互页面的模块)。模块切换组件只能查看到应用。

通过@UxHomepage注解配置首页。@UxHomepage注解的model属性指定跳转页面的模型编码,name属性指定跳转页面的视图动作,默认为列表页。如果配置首页为列表页且未定义ViewAction,系统会根据首页配置自动生成。

更多Module的详细元数据描述,详见4.1.4【模块元数据详解】一文

配置扫描路径

设置扫描模型配置的包路径:

  • 使用packagePrefix方法来配置模块需要扫描模型配置的包路径

  • 使用dependentPackagePrefix方法来配置依赖模块的模型配置的包路径;如果不配置,会默认根据依赖模块的配置扫描模型配置的包路径扫描依赖模型

  • 不同模块包路径包含会导致模型加载模块出问题

命名规范

属性 默认取值规则 命名规范
module 无默认值
开发人员定义规范示例:
{项目名称}_{模块功能示意名称}
使用下划线命名法
仅支持数字、大写或小写字母、下划线
必须以字母开头
不能以下划线结尾
长度必须小于等于128个字符
name 无默认值 使用大驼峰命名法
仅支持数字、字母
必须以字母开头
长度必须小于等于128个字符

表3-2-1-2 命名规范

五、DemoModule的启动

  1. 修改yml文件中数据源配置,数据库地址与密码修改为自己本地

  2. 配置license,否则启动会报错,获取授权文件请找官方客户

3.2.1 构建第一个Module

图3-2-1-11 license未配置

  1. 需要为启动或依赖模块配置扫描路径,配置扫描路径:pmairs是我们的oinone的基础包(必选),himalaya,tanggula是我们的业务模型基础包(可选),pro.shushi.pamirs.demo是我们测试项目包路径(必选,只不过它也在pamirs路径下,不填也不错)

3.2.1 构建第一个Module

图3-2-1-12 扫描逻辑配置

  1. 启动应用,我们会发现会报错。这个错误主要因为Oinone默认的是RELOAD(重启)模式,这种模式下只会从数据库中读取已安装模块并与yml文件中配置需要加载的模块对比。如果数据库中没有则会报没有安装过**模块,而我们是第一次启动,前面必然没有安装过模块,所以我们要把模式变为INSTALL,启动参数详见4.1.2【模块之启动指令】一文。如果整个平台第一次启动则回报 'base_sequence_config' doesn't exist

3.2.1 构建第一个Module

图3-2-1-13 启动应用的报错提示

  1. 把模式变为INSTALL再次启动

3.2.1 构建第一个Module

3.2.1 构建第一个Module

图3-2-1-14 把模式变为INSTALL再次启动

  1. 查看日志,看到对应启动字样才代表启动完成,而非Spring Boot的启动完成日志。我们的oinone的启动是在Spring Boot 启动完以后异步启动的

3.2.1 构建第一个Module

图3-2-1-15 启动成功日志

  1. 打开GraphQL客户端Insomnia看对应服务是否暴露

    a. 创建一个demo项目

3.2.1 构建第一个Module

图3-2-1-16 Insomnia操作示意-创建一个新项目

3.2.1 构建第一个Module

图3-2-1-17 Insomnia操作示意-命名为demo

b. 为demo项目创建一个请求集合

3.2.1 构建第一个Module

图3-2-1-18 Insomnia操作示意-创建一个请求集合(第一步)

3.2.1 构建第一个Module

图3-2-1-19 Insomnia操作示意-创建一个请求集合(第二步)

3.2.1 构建第一个Module

图3-2-1-20 Insomnia操作示意-创建一个请求集合(第三步)

c. 创建一个请求 command+N

3.2.1 构建第一个Module

图3-2-1-21 Insomnia操作示意-创建一个请求

3.2.1 构建第一个Module

图3-2-1-22 Insomnia操作示意-选POST模式

3.2.1 构建第一个Module

图3-2-1-23 Insomnia操作示意-输入服务地址

3.2.1 构建第一个Module

图3-2-1-24 Insomnia操作示意-切换body结构为GQL

d. 检验结果,对应后端提供的服务已经有提示了

3.2.1 构建第一个Module

图3-2-1-25 Insomnia操作示意-检验结果

e. 查看schema 文档

3.2.1 构建第一个Module

图3-2-1-26 Insomnia操作示意-查看API文档

3.2.1 构建第一个Module

图3-2-1-27 Insomnia操作示意-查看API文档

3.2.1 构建第一个Module

图3-2-1-28 Insomnia操作示意-查看API文档

恭喜第一个oinone的模块已经启动完成,在下一文中我们通过页面来看看oinone的系统的庐山真面目。

Oinone社区 作者:史, 昂原创文章,如若转载,请注明出处:https://doc.oinone.top/oio4/9228.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

(0)
史, 昂的头像史, 昂数式管理员
上一篇 2024年5月23日 am9:54
下一篇 2024年5月23日

相关推荐

  • 3.3.2 模型的类型

    本文会介绍不同类型模型以及其简单的应用场景,方便大家理解不同类型模型的用途 模型分为元模型和业务模型。元数据是指描述应用程序运行所必需的数据、规则和逻辑的数据集;元模型是指用于描述内核元数据的一套模式集合;业务模型是指用于描述业务应用元数据的一套模式集合。 元模型分为模块域、模型域和函数域三个域。域的划分规则是根据元模型定义数据关联关系的离散性来判断,离散程度越小越聚集到一个域。在4.1.4【模块元数据详解】一文中介绍的ModuleDefinition就是元模型。而我们在开发中涉及的就是业务模型 一、模型类型 抽象模型:往往是提供公共能力和字段的模型,它本身不会直接用于构建协议和基础设施(如表结构等)。 传输模型:用于表现层和应用层之间的数据交互,本身不会存储,没有默认的数据管理器,只有数据构造器。 存储模型:存储模型用于定义数据表结构和数据的增删改查(数据管理器)功能,是直接与连接器进行交互的数据容器。 代理模型:用于代理存储模型的数据管理器能力的同时,扩展出非存储数据信息的交互功能的模型。 二、模型定义种类 模型定义就是模型描述,不同定义类型,代表计算描述模型的元数据的规则不同 静态模型定义:模型元数据不持久化、不进行模型定义的计算(默认值、主键、继承、关联关系) 静态计算模型定义:模型元数据不持久化但初始化时进行模型定义计算获得最终的模型定义 动态模型定义:模型元数据持久化且初始化时进行模型定义计算获得最终的模型定义 静态模型定义需要使用@Model.Static进行注解;静态计算模型定义使用@Model.Static(compute=true)进行注解;动态模型定义不注解@Model.Static注解。 三、安装与更新 使用@Model.model来配置模型的不可变更编码。模型一旦安装,无法在对该模型编码值进行修改,之后的模型配置更新会依据该编码进行查找并更新;如果仍然修改该注解的配置值,则系统会将该模型识别为新模型,存储模型会创建新的数据库表,而原表将会rename为废弃表。 如果模型配置了@Base注解,表明在【oinone的设计器】中该模型配置不可变更;如果字段配置了@Base注解,表明在【oinone的设计器】中该字段配置不可变更。 四、基础配置 模型基类 所有的模型都需要继承以下模型中的一种,来表明模型的类型,同时继承以下模型的默认数据管理器(详见3.3.3模型的数据管理器一节)。 继承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的多对多关系模型。 模型继承关系图 图3-3-2-1 模型继承关系图 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增强模型,提供全文检索能力。此模型会在4.1.25【框架之搜索引擎】一文中展开介绍。 五、抽象模型(举例) 抽象模型本身不会直接用于构建协议和基础设施(如表结构等),而是通过继承的机制供子模型复用其字段和函数。子模型可以是所有类型的模型。 比如demo模块要管理的一些公共模型字段,我们可以建一个AbstractDemoIdModel和AbstractDemoCodeModel,demo模块中的实体模型就可以继承它们。我们来为demo模块的模型统一增加一个数据状态这么一个字段,用做数据的生效与失效管理。 Step1 引入DataStatusEnum类 pamirs-demo-api的pom.xml包增加依赖,便于引入DataStatusEnum类,当然也可以自己建,这里只是oinone提供了统一的数据记录状态的枚举,以及相应的通用方法,这边就直接引入 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-core-common</artifactId> </dependency> 图3-3-2-2 引入通用类库 Step2 修改DemoModule DataStatusEnum枚举类本身也会做为数据字典,以元数据的方式被管理起来,当一个模块依赖另一个模块的元数据相关对象,则需要改模块的模块依赖定义。为DemoModule增加CommonModule的依赖注解 package pro.shushi.pamirs.demo.api; import org.springframework.stereotype.Component; import pro.shushi.pamirs.boot.base.ux.annotation.action.UxRoute; import pro.shushi.pamirs.boot.base.ux.annotation.navigator.UxHomepage; import pro.shushi.pamirs.core.common.CommonModule; import pro.shushi.pamirs.demo.api.model.PetShop; import pro.shushi.pamirs.meta.annotation.Module; import pro.shushi.pamirs.meta.base.PamirsModule; import pro.shushi.pamirs.meta.common.constants.ModuleConstants; @Component @Module( name = DemoModule.MODULE_NAME, displayName = "oinoneDemo工程", version = "1.0.0", dependencies = {ModuleConstants.MODULE_BASE, CommonModule.MODULE_MODULE} ) @Module.module(DemoModule.MODULE_MODULE) @Module.Advanced(selfBuilt = true, application = true) @UxHomepage(@UxRoute(PetShop.MODEL_MODEL)) public class DemoModule implements PamirsModule { public static final String MODULE_MODULE = "demo_core"; public static final String MODULE_NAME = "DemoCore"; @Override public String[] packagePrefix() { return new String[]{ "pro.shushi.pamirs.demo"}; } } 图3-3-2-3 定义模块依赖 Step3 新建AbstractDemoCodeModel和AbstractDemoIdModel 并新增AbstractDemoIdModel和AbstractDemoCodeModel分别继承IdModel和CodeModel,实现IDataStatus接口不是必须的,刚好DataStatus有配套的通用逻辑,暂时也先加进去,具体使用会在本文的【代理模型】这段介绍 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.core.common.behavior.IDataStatus; import pro.shushi.pamirs.core.common.enmu.DataStatusEnum; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.annotation.sys.Base; import pro.shushi.pamirs.meta.base.common.CodeModel; import pro.shushi.pamirs.meta.enmu.ModelTypeEnum; @Base @Model.model(AbstractDemoCodeModel.MODEL_MODEL) @Model.Advanced(type = ModelTypeEnum.ABSTRACT) @Model(displayName = "AbstractDemoCodeModel") public abstract class AbstractDemoCodeModel extends CodeModel implements IDataStatus { public static final String MODEL_MODEL="demo.AbstractDemoCodeModel"; @Base @Field.Enum @Field(displayName = "数据状态",defaultValue = "DISABLED",required =…

    2024年5月23日
    1.7K00
  • 接口日志

    记录每个PAPI接口执行日志,接口的响应结果、执行时间、执行时长等信息,可查看接口详情。 接口详情

    2023年5月23日
    1.3K00
  • 6.2 集成平台(改)

    企业在数字化转型过程中内外部集成是一个必然需求、也是趋势 集成的诉求主要来自两个方面:1.企业的数字化改造是由外而内逐步进行的(内部异构集成)、2.企业数字化方向是朝越来越开放的方向发展(外部平台、工具集成)。总的来说企业在数字化转型过程中内外部集成是一个必然需求、也是趋势。所以我们不能简单地去理解做个API对接就结束了,而是要统一规划构建成企业的集成门户对API定义,安全、控制、记录等做全方位管理。oinone在下个版本规则中也纳入了基于集成平台之上做产品化配置的需求 概述 pamirs-eip为平台提供企业集成门户的相关功能,如请求外部接口使用的【集成接口】和对外开放被其他系统请求调用的【开放接口】功能。在请求外部接口时,还支持了多个接口调用(路由定义)、分页控制(paging)、增量控制(incremental)等功能。 准备工作 Step1 POM与模块依赖 pamirs-demo-api 和 pamirs-second-api 的pom文件中引入pamirs-eip2-api包依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-eip2-api</artifactId> </dependency> DemoModule和SecondModule 增加对EipModule的依赖 @Module(dependencies = {EipModule.MODULE_MODULE}) pamirs-demo-boot和pamirs-second-boot工程的pom文件中引入pamirs-eip2-core包依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-eip2-core</artifactId> </dependency> Step2 yaml配置文件参考 pamirs-demo-boot和pamirs-second-boot工程的application-dev.yml文件中增加配置pamirs.boot.modules增加eip,即在启动模块中增加eip模块 pamirs: boot: modules: – eip pamirs-demo-boot和pamirs-second-boot工程的application-dev.yml文件中增加eip模块的数据源与路由配置 pamirs: framework: data: ds-map: eip: eip datasource: eip: driverClassName: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://127.0.0.1:3306/eip_v3?useSSL=false&allowPublicKeyRetrieval=true&useServerPrepStmts=true&cachePrepStmts=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true username: root password: oinone initialSize: 5 maxActive: 200 minIdle: 5 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true asyncInit: true pamirs-demo-boot工程的application-dev.yml文件中修改eip的配置 pamirs: eip: open-api: enabled: false pamirs-second-boot工程的application-dev.yml文件中修改eip的配置 pamirs: eip: enabled: true open-api: enabled: true route: host: 127.0.0.1 port: 8094 aes-key: Nj5Thnxz4rV8Yy1FLGA2hUym3RepB8MKgafEaYC4GKo= 注: hosts配置在远程调用时不能使用127.0.0.1,可配置为0.0.0.0进行自动识别。若自动识别仍无法访问,请准确配置其他已知的可访问IP地址。 aes-key:用下面代码生成 附录:AES Key生成 pro.shushi.pamirs.core.common.EncryptHelper加解密帮助类,默认支持AES、RSA类型的数据加解密方法,也可自定义其他类型的加解密方法。 System.out.println(EncryptHelper.getKey(EncryptHelper.getAESKey())); Step3 在pamirs-second-api新建一个SessionTenantApi实现类 只要在我们公共的jar包中构建类似DemoSessionTenant类就可以了,之所以要构建SessionTenantApi实现类是因为EIP是以租户信息做路由的。所以这里我们写死返回一个“pamirs”租户就好了。 记得要重新mvn install second工程,再刷新demo工程 package pro.shushi.pamirs.second.api.tenant; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import pro.shushi.pamirs.framework.session.tenant.api.SessionTenantApi; import pro.shushi.pamirs.meta.api.core.session.SessionClearApi; import pro.shushi.pamirs.meta.common.spi.SPI; @Order(99) @Component @SPI.Service public class DemoSessionTenant implements SessionTenantApi, SessionClearApi { public String getTenant() { return "pamirs"; } public void setTenant(String tenant) { } public void clear() { } } 开放接口(举例) Step1 用于演示的模型定义 package pro.shushi.pamirs.second.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.base.IdModel; @Model.model(TestOpenApiModel.MODEL_MODEL) @Model(displayName = "演示开放接口模型") public class TestOpenApiModel extends IdModel { public static final String MODEL_MODEL = "demo.second.TestOpenApiModel"; @Field.String @Field(displayName = "名称") private…

    2024年5月23日
    1.6K00
  • 3.5.6 DSL配置大全(略)

    因为默认视图很难满足客户的个性化需求,所以日常开发中view的配置是避免不了的。本系列篇是比较全面地介绍View配置的各个方面涉及:视图、字段、动作、布局等

    Oinone 7天入门到精通 2024年5月23日
    1.3K00
  • 5.4 基础支撑之商业关系域

    PamirsPartner作为商业关系与商业行为的主体,那么PamirsPartner间的关系如何描述,本文将介绍两种常见的设计思路,从思维和实现两方面进行对比,给出oinone为啥选择关系设计模式的原因。 一、两种设计模式对比 设计模式思路介绍 角色设计模式思路介绍 从产品角度枚举所有商业角色,每个商业角色对应一个派生的商业主体,并把主体间的关系类型进行整理。 图5-4-1 角色设计模式 关系设计模式思路介绍 从产品角度枚举所有商业角色,每个商业角色对应一个派生的主体间商业关系 图5-4-2 关系设计模式 设计模式对应实现介绍 角色设计模式实现介绍 不单商业主体需要扩展,关系也要额外维护,可以是字段或是关系表。一般M2O和O2M字段维护,M2M关系表维护。 创建合同场景中甲方选择【商业主体A】,乙方必须是【商业主体A】有关联的经销商、分销商、零售商、供应商等,则在角色设计模式下就非常麻烦,因为关系都是独立维护的 图5-4-3 角色设计模式实现介绍 关系设计模式实现介绍 只需维护商业关系扩展 同时在设计上收敛了商业关系,统一管理应对不同场景都比较从容 图5-4-4 关系设计模式实现介绍 二、oinone商业关系的默认实现 首先oinone的商业关系选择关系设计模式 其次模型上采用多表继承模式,父模型上维护核心字段,子模型维护个性化字段。

    2024年5月23日
    1.5K00

Leave a Reply

登录后才能评论