# 总体概述
版本: 1.1 | 发布日期: 07/12/2020
# 警告
- 不允许重写任何M18的存储过程。
- 不允许修改或移除已经存在的M18表格栏位。
- 所有的SQL栏位名和存储过程名称应该使用App编号作为前缀。
- 在表格名称和栏位名称中不允许使用
_
# 注意事项
M18平台仅授权给Multiable的客户和经过认证的第三方开发人员。开发应用程序的前提是你要有一套经过授权的M18平台软件。
如果你有任何疑问,请联系我们的实施人员或者在我们的论坛 (opens new window) 上进行提问。
# M18 架构
M18平台基于J2EE技术架构进行开发,部署于Wildfly(Java EE Server)上面。前端使用JSF,后端应用使用EJB进行编写。数据库使用MySql。
Wildfly(原Jboss)是应用程序服务器,属于企业级Java中间件。请熟悉Wildfly的相关配置和功能,由于M18运行的环境主要受到中间件的控制,了解对于开发/测试将有很大的帮助。
EJB是用于应用程序业务逻辑的服务器组件。你可以理解为一个个搭建业务功能实现的小模块。它给企业及开发人员提供了一个标准方式,从而解决一些之前总是作业操作总是重复发生的问题。M18之中,EJB会接收JSF发出的请求,并且在有需要的情况下和数据库继续必要的交互。
# M18 应用程序概念
M18是一个预置了若干应用程序
的低代码快速开发平台,第三方开发者可以通过开发自己的应用程序
来达到扩展/修改/已有功能或者添加新功能的目的。
在M18中,我们将特定的功能的集合称为应用程序
,并要求每一个应用程序
的代码是独立管理和维护的,我们使用app.xml来描述一个应用程序
是怎样的。
在M18里面,应将应用程序
理解为最小的程序可分割的单元。
# M18 应用程序开发指南
为了开发M18应用程序,你需要一整套的M18运行环境,包括WildFly、MySQL数据库和M18程序包。
如果有多名开发人员在同一套M18平台上进行开发,数据库通常是可以共用的,但WildFly通常是每一位开发者都有自己的一份拷贝。
如果你有开发应用程序
的需求,可以使用UAT(用户测试环境)或者额外再独立一个开发环境进行开发,切忌在生产环境上直接进行开发。
你最好先读一下设置开发环境 再继续往下阅读,这样子你对下面的内容会有更好的理解。
# 关于 app.xml
每一个应用程序
使用一个名为app.xml
的文件对它的各个属性进行定义。 你可以看一下 Github上的例子 (opens new window)
名字 | 必填 | 说明 |
---|---|---|
name | 是 | App 的名字,是App 的唯一标识符 |
version | 是 | 格式为d.d.d_*** d部分必须要为数字,而且我们要求版本是单向递增的 |
description | 否 | 当前App 的描述 |
mess | 是 | 用于界面显示的MessCode |
ear | 是 | 用于描述App 存在的ear名称,目前一定是caw_ear |
ejb | 是 | 当前App使用的ejb jar的名字 |
appLogoName | 是 | App在界面显示的logo的名字 |
appLogoLib | 是 | App在界面显示的logo的的位置 |
developer | 是 | App在界面显示的开发者名称 |
developerLogoName | 是 | App在界面显示的开发者Logo的名字 |
developerLogoLib | 是 | App在界面显示的开发者Logo的位置 |
dependences | 否 | 用于描述当前的App依赖的App |
*** | 其他内容将在之后的章节具体介绍 |
例子:
<?xml version="1.0"?>
<app xmlns="http://www.multiable.com/app">
<name>m18 test</name>
<version>1.0</version>
<description>test</description>
<ear>caw_ear</ear>
<ejb>core_ejb</ejb>
<dependences>
<dependence id="caw" version="1.0">
</dependences>
</app>
# 词汇表
名字 | 描述 |
---|---|
Module | M18 Module 类似于 领域驱动设计 中领域模型的概念, 在M18 中用于表示一个逻辑实体, 请看下面的详细描述 |
Menu | View 是Module 的界面视图, Module 可以有多个不同界面布局和权限控制的视图. 在M18中,用户可以通过拖拉的方式定义自己的界面视图 |
SqlEntity | 有时也简称为Entity , 是Module 数据的装载实体,通常,Module 中的一张单据与一个Entity 对应. |
SqlTable | Module 的一张单据,后台通常对应的是多张表,每张表对应一个SqlTable . 所以多个SqlTable 组成一个SqlEntity |
Lookup | M18中定义查询 的地方, 包括查询的条件、显示的栏位、关键字查询的范围等等 |
Mess | Message 的简写, 定义多语言界面的文件,请参照多语言实现 |
# M18 Module
Module
类似于 领域驱动设计
中领域模型的概念, 在M18 中用于表示一个逻辑实体.
例如,“客户”,“销售订单”,“员工”,“仓库”,“部门”
M18用一个名为module.xml
的XML文件去描述Module
, 详细格式请参照module.xml.
<?xml version="1.0"?>
<module name="virDept" mess="virDept" extend="false" mainTable="virdept" useChangenote="true" genCode_Type="VO" recType="" useAccess="true" useAttach="true" useApv="true">
<table name="virdept" key="code" initRow="1" hpk="" fKey="" hfName="" hfKey="" order=""/>
<table name="virdeptpic" key="id" initRow="0" hpk="hId" fKey="picTypeId;userId;startDate" hfName="" hfKey="" order="" cpnType="table"/>
<table name="virdeptmember" key="id" initRow="0" hpk="hId" fKey="" hfName="" hfKey="" order="" cpnType="table"/>
<checker class="com.multiable.core.ejb.checker.VirDeptChecker"/>
</module>
# M18 Menu
M18用一个名为navmenu.xml
的XML文件去描述Menu
, 详细格式请参照navmenu.xml.
<folder code="language" messCode="core.lang">
<menu code="langSetting" messCode="langSetting" src="view/module/langSetting" mType="SETTING">
<function name="Save" />
</menu>
<menu code="udfMess" messCode="udfMess" src="view/module/udfMess">
<function name="Save" />
<function name="DataImport;DataExport" />
</menu>
<menu code="i18nFieldSetting" messCode="i18nFieldSetting" src="view/module/i18nFieldSetting" module="i18nFieldSetting" mType="SETTING">
<function name="Save" />
</menu>
</folder>
# M18 SqlTable
SqlTable是M18通用的数据存储结构。这个结构的生成的主要原因在于M18整个设计都是基于可扩展的方式的。
他包括以下几个部分:table名字(注:不是数据库table的名字,这里是一个虚拟的名字一般情况下可以不进行赋值),栏位信息(说明有哪些栏位,栏位的属性是什么 方便开发者进行遍历栏位的操作),数据。
M18用一个名为datadict.xml
的XML文件去描述SqlTable
,详细格式请参照datadict.xml.
<table name="useremailsender" mess="emailSender" pk="id">
<inherit name="id_irev" />
<column name="hId" type="int_unsigned" mess="user" defValue="0" defPattern="user" />
<column name="mailUser" type="varchar" mess="core.mailUser" length="100" defPattern="char100" />
<column name="mailPwd" type="varchar" mess="core.mailPwd" length="2000" defPattern="char2000" skipLookup="true" dataExport="false"/>
<column name="mailAccount" type="varchar" mess="core.mailAccount" length="100" defPattern="char100" />
</table>
注意事项:
1. 由于系统会将数据转换为json,请确保存放到SqlTable的数据均可以转换为JSON。
2. 虽然支持SqlTable里面存放SqlTable,但是系统不推荐这样处理,甚至系统不推荐将非基本类型存入SqlTable。
# M18 SqlEntity
SqlEntity是M18模块最常见的模块数据存储结构,他由系统表module.xml 进行定义和描述。
在SqlEntity里面会说明: 当前Entity属于那个Module
,当前Entity
的所有信息。通常来说一个SqlEntity会包含若干个SqlTable
。
注意事项:
1. 请注意SqlEntity里面一定是有一个主表的,而且系统认为主表的id栏位就是entity的id属性。
SqlTable的常用操作
从数据库读取数据
SqlTable data = CawDs.getSqlResult("select * from test where code like 'B%';");
新建table
SqlTable data = new SqlTable();
data.setName("test");
data.addField(new SqlTableField("info", String.class));
data.addField(new SqlTableField("check", Boolean.class));
// or
SqlTable data_new = data.genEmptyTable();
增加行,并赋值
int row = data.addRow();
data.setString(row,"info","test");
表循环
for(int row : data){
String info = data.getString(row,"info");
}
两个表数据合并
SqlTableLib.append(src, inc);
创建表索引
Integer[] indexs = SqlTableLib.getIndex(sortFields, data);
- 对于SqlTable的绝大部分操作均存在SqlTable和SqlTableLib里面,请使用前仔细进行阅读。
# M18 Lookup
每一个Module
的Menu
默认会有一个Lookup
,用户可以定义自己的Lookup
当你在一个Module
的界面引用另外一个Module
的数据时,所用到的查询也是由Lookup
定义的
关于Lookup
的实现,请看stInfo.xml 和 stSearch.xml.
CheckMsg
系统绝大部分的错误提示使用CheckMsg进行反馈。
这里说明一下主要一些重要的点。
info_desc:用于界面显示的信息,不应该包含messcode
trace:用于定位checkmsg生成的位置
子元素MsgLocator用于定位错误信息发生在Entity那些相关的栏位上面。推荐需要填写。
- 请参考CheckMsgLib获取关于Msg操作的更新信息。