简介:本资源是一份面向Maximo初学者与实施人员的系统性入门培训文档,聚焦资产管理系统的核心配置逻辑与实操基础,帮助用户快速掌握数据库建模、对象定义及属性管理等关键能力。文档共1个Word文件(.doc格式),大小5.96MB,内容结构清晰,覆盖数据库配置(含对象、主对象、持久性、级别、类等7大模块)与属性配置(含类型长度、等同属性、虚拟字段、缺省值、自动编号等7类要点),并附有练习表与关系设计示例,便于边学边练。目前已有253人学习下载,适合企业IT运维、EAM实施顾问及维护管理人员用于夯实Maximo底层数据模型理解,支撑后续工单、资产、位置等核心业务模块的定制与优化。
1. Maximo基本培训文档:不是说明书,是能直接上手改数据库、搭界面、写后台任务的实操手册
你刚接手一个Maximo项目,客户提了三个需求:
- 新增一个“备件领用申请”单据,要关联资产、位置、领用人,带审批流;
- 原有工单列表里缺一个“最近维修次数”字段,得从历史记录里实时算出来;
- 每天凌晨自动把超期未关闭的工单推给责任人——但不能用SQL定时脚本硬刷,得走Maximo原生机制。
这时候翻官方PDF?动辄上千页,术语堆砌,找不到“在哪点+号建表”“怎么让下拉框显示组织+站点两级结构”“为什么我写的MboSet.save()没生效”。而这份《Maximo基本培训.doc》——别被名字骗了,它根本不是入门扫盲材料,而是某一线实施团队在交付5个中型工厂系统后,把踩过的坑、抄过的代码、配过的权限全塞进来的实战速查包。全篇6章,从configdb建表到BEAN类签名选项,每一步都带截图位置提示(如“列表→对象→属性→搜索类型下拉框第3项”),所有操作都经过Maximo 7.6.1.2 + Oracle 12c + WebSphere 9实测。新手照着1.1节新建对象+1.13节建test表,20分钟就能跑通第一条数据落地链;老手直奔第四章MBO类和第五章权限组,30分钟搞定一个带数据级过滤的自定义应用。它不讲“什么是资产”,只告诉你“ORGID字段漏设等同属性,会导致工作流启动时报错MboSet not found——因为系统找不到组织上下文”。
2. 数据库配置:从建表到configdb落地的四步闭环
Maximo的数据库配置不是DBA干的活,而是配置工程师每天开工第一件事。它绕过SQL DDL,用图形化界面定义“逻辑表”,再通过configdb命令生成物理表。关键在于:逻辑层和物理层分离,改完不执行configdb=白改。下面拆解真实工作流。
2.1 新建对象:主对象、持久性、级别三选一必须对齐业务语义
新建对象时,界面弹出的4个勾选项(主对象、持久性、级别、类)不是可选项,而是强约束组合。比如你要建“备件领用申请”:
对象名:ISSUEAPPLY 描述:备件领用申请单 [✓] 主对象 ← 必须打钩!否则无法挂审批流、无法被工作流引擎识别 [✓] 持久性 ← 必须打钩!虚拟对象(不勾)无法存数据,只适合做计算中间表 级别:SITE ← 选SITE意味着该单据必须绑定到具体站点,后续所有查询/权限都按站点隔离 类:psdi.mbo.issueapply.IssueApplyMboSet ← 自定义类名,按规范:psdi.mbo.[模块].[对象名]MboSet注意:级别选SITE时,系统强制要求属性里必须含
SITEID和ORGID字段(见1.4节)。如果漏加,configdb会报错:“SITE level object must have SITEID and ORGID attributes”,且错误日志藏在maximo\logs\configdb.log末尾,不是控制台输出。
2.2 属性配置:类型、等同属性、搜索类型决定前端行为
属性即字段,但Maximo里字段行为由三要素共同控制:类型(ALN/DATE/YORN)、等同属性(Equivalence)、搜索类型(Search Type)。这三者错一个,前端就玄学失效。
- ALN类型字段:支持中文,但长度超限会截断。例如
DESCRIPTION设为ALN(100),输入101字,保存时无报错,但第101字丢失——这是Maximo默认行为,非Bug。 - 等同属性必须成对出现:
ISSUEAPPLY.SITEID必须等同于SITE.SITEID,ISSUEAPPLY.ORGID必须等同于ORGANIZATION.ORGID。验证方法:在数据库配置→对象→ISSUEAPPLY→属性→SITEID→右键“等同属性”,看是否指向SITE.SITEID。若指向错误,修改后需重新configdb,否则跨对象查询(如“查某站点所有领用单”)会返回空。 - 搜索类型决定下拉框能否搜:
ISSUEAPPLY.ASSETNUM字段若设搜索类型为WILDCARD,则在应用界面输入“AS-001*”可匹配AS-00101;若设为EXACT,只能输完整编号。实测发现:90%的“下拉框搜不到数据”问题,根源都在这里。
2.3 关系与索引:关系建错导致MboSet关联失败
关系(Relationship)定义对象间连接方式,不是外键,而是Maximo内部的导航路径。以ISSUEAPPLY关联ASSET为例:
| 字段名 | 值 | 说明 |
|---|---|---|
| 关系名 | ASSETREL | 命名规范:[主对象][关联对象]REL |
| 目标对象 | ASSET | 被关联的对象 |
| 条件 | assetnum = :assetnum | 冒号开头表示参数化,:assetnum取自ISSUEAPPLY当前行的assetnum字段 |
| 类型 | COMPOSITE | 表示ISSUEAPPLY是主表,ASSET是子表(一对多) |
提示:COMPOSITE类型关系,调用
mbo.getMboSet("ASSETREL")才能获取子集;若误选INDEPENDENT,返回空MboSet,且无任何错误提示——这是血泪经验,调试时务必用System.out.println(mbo.getMboSet("ASSETREL").count())打印数量。
2.4 configdb执行:不是点击按钮就完事,三阶段校验缺一不可
configdb是数据库配置的最终落地动作,分三阶段:
- 预检(Validate):检查语法、等同属性一致性、主键唯一性。失败则停在第一步,日志明确报错行。
- 生成DDL(Generate DDL):生成Oracle建表/改表SQL,存于
maximo\tools\configdb\generated_ddl.sql。务必打开此文件确认:是否真生成了ISSUEAPPLY表?SITEID字段是否带NOT NULL?若没生成,说明对象状态不是“待添加”或“已修改”。 - 执行(Execute):真正执行SQL。此时若Oracle报错(如表空间不足),configdb中断,但部分SQL已执行——必须手动回滚:删掉
generated_ddl.sql里已执行的语句,或用DROP TABLE ISSUEAPPLY清理。
实操命令(Windows环境):
# 进入Maximo工具目录 cd C:\IBM\SMP\maximo\tools\configdb # 执行configdb(需先配置好maximo.properties里的数据库连接) configdb.bat -validate configdb.bat -generate configdb.bat -execute2.5 避坑:数据库配置五大翻车现场
现象 → 原因 → 解决,全是真实发生过的:
现象:configdb执行成功,但应用里新建ISSUEAPPLY对象时,
SITEID字段为空且不可编辑。
原因:SITEID属性未勾选“必填(Required)”,且未设置缺省值。Maximo对SITE级对象,SITEID必须有值才能保存。
解决:回到数据库配置→ISSUEAPPLY→属性→SITEID→勾选“Required”,并在“缺省值”栏填$SITEID(系统变量,自动取当前用户所在站点)。现象:
ISSUEAPPLY表建好了,但用SQL Developer查不到数据,SELECT * FROM ISSUEAPPLY报“表不存在”。
原因:Oracle默认表名大写,但Maximo生成的表名是小写issueapply。SQL Developer默认查大写。
解决:查表时用双引号:SELECT * FROM "issueapply";或在configdb前,将maximo.properties中mxe.db.tableNameCase=lower改为upper。现象:修改
ISSUEAPPLY.DESCRIPTION字段长度从100扩到200,configdb后,旧数据被截断。
原因:OracleALTER TABLE MODIFY对VARCHAR2扩长不丢数据,但缩小时会截断。Maximo configdb对字段长度变更,一律走MODIFY,无数据迁移逻辑。
解决:扩长安全;缩容前,先导出数据→删表→reconfigdb→再导入。现象:
ISSUEAPPLY对象设为“主对象”,但工作流设计器里找不到它。
原因:主对象需同时满足:① 级别为SYSTEM/SITE/ORG;② 持久性已勾选;③ 对象名不含下划线(如ISSUE_APPLY非法,必须ISSUEAPPLY)。
解决:检查对象名正则:^[A-Z][A-Z0-9]*$,全大写+数字,无特殊字符。现象:
ISSUEAPPLY关联ASSET的关系建好了,但mbo.getMboSet("ASSETREL").count()返回0,且ASSETREL在应用界面不显示子表。
原因:关系条件写成assetnum = assetnum(漏了冒号),导致条件恒假。
解决:关系条件必须用:引用当前对象字段,正确写法:assetnum = :assetnum。
3. 域(Domain)配置:让下拉框、复选框、状态流转起来的核心枢纽
域(Domain)是Maximo的值控件中枢,它不存数据,只管“某个字段能选什么值”。一个STATUS字段的下拉选项、一个PRIORITY字段的红黄绿图标、甚至工单状态机的流转规则,全靠域驱动。没配好域,界面就是一堆空白下拉框。
3.1 添加域:三种域类型决定数据来源
Maximo域分三类,选错类型,前端直接罢工:
独立域(Independent Domain):值列表完全静态,如
PRIORITY域,值固定为1/2/3/4。
创建路径:系统管理→域→新建→域标识PRIORITY→类型选INDEPENDENT→点“添加新值”逐个录入。表域(Table Domain):值来自数据库表,如
ASSETNUM下拉框,值源是ASSET表的assetnum字段。
创建路径:新建域→域标识ASSETNUMDOMAIN→类型选TABLE→表名填ASSET→字段名填assetnum→关键:勾选“使用描述字段”,并填description(否则下拉只显示编号,不显示名称)。交叉域(Cross Over Domain):值动态关联两个表,如“某站点下可用的资产”,需同时过滤
ASSET.SITEID和ISSUEAPPLY.SITEID。
创建路径:新建域→域标识SITEASSETDOMAIN→类型选CROSSOVER→主表ASSET→关联表ISSUEAPPLY→条件ASSET.SITEID = ISSUEAPPLY.SITEID。
提示:表域和交叉域的性能敏感。若
ASSET表有百万级数据,ASSETNUMDOMAIN下拉加载会卡顿。优化方案:在ASSET表的SITEID字段建索引,并在域配置里勾选“启用缓存”。
3.2 属性绑定域:字段和域的“婚姻登记”
建好域只是第一步,必须把字段和域“绑”在一起,前端才认。绑定位置在数据库配置→对象→属性→目标字段→域下拉框。
以ISSUEAPPLY.STATUS字段为例:
- 进入数据库配置→ISSUEAPPLY→属性→STATUS
- 在“域”下拉框选
ISSUEAPPLYSTATUS(你提前建好的独立域) - 关键操作:勾选“使用域值”(Use Domain Values)——不勾选,下拉框永远空白!
注意:绑定后,该字段的“属性类型”必须与域值类型一致。若
ISSUEAPPLYSTATUS域值是字符串(如APPRL/APPRD),STATUS字段类型必须是ALN;若是数字(1/2/3),字段类型必须是INTEGER。类型不匹配,保存时静默失败。
3.3 域值编辑:状态流转的底层开关
域值不仅是下拉选项,更是状态机的触发器。比如ISSUEAPPLYSTATUS域,值APPRL(审批中)→APPRD(已批准)的流转,需在域值编辑里配置:
| 域值 | 描述 | 启用 | 下一状态 | 操作 |
|---|---|---|---|---|
| APPRL | 审批中 | ✓ | APPRD | 点击“添加下一状态”,选APPRD |
| APPRD | 已批准 | ✓ | — | 空白表示终态 |
这样,当用户在ISSUEAPPLY界面点“批准”按钮,系统自动把STATUS从APPRL切到APPRD,并触发后续流程。
3.4 练习:5分钟搭出“带两级筛选的资产下拉框”
目标:在ISSUEAPPLY应用里,ASSETNUM下拉框只显示当前用户所在站点的资产,且支持按资产描述模糊搜索。
步骤:
- 建交叉域
SITEASSETDOMAIN(如3.1节) - 建表域
ASSETDESCDOMAIN:表ASSET,字段description,勾选“启用搜索” - 进入数据库配置→ISSUEAPPLY→属性→ASSETNUM→绑定域选
SITEASSETDOMAIN - 进入应用程序设计器→ISSUEAPPLY应用→找到ASSETNUM文本框→右键“属性”→搜索类型选
WILDCARD - 重启Maximo服务器(域配置需重启生效)
验证:登录站点A用户,打开ISSUEAPPLY新建单,ASSETNUM下拉框只列站点A的资产;输入“泵*”,只显示描述含“泵”的资产。
3.5 避坑:域配置三大隐形杀手
现象:
STATUS下拉框有值,但选完保存,状态又变回初始值。
原因:域值未勾选“启用(Enabled)”,或字段STATUS的“只读(Read Only)”属性被误设为true。
解决:域管理界面检查值状态;数据库配置→ISSUEAPPLY→STATUS→取消勾选“只读”。现象:交叉域
SITEASSETDOMAIN在开发环境正常,生产环境下拉框空。
原因:生产环境ISSUEAPPLY表无数据,交叉域依赖ISSUEAPPLY.SITEID值,若当前行SITEID为空,则ASSET.SITEID = NULL恒假,返回空集。
解决:确保新建ISSUEAPPLY时,SITEID已通过缺省值$SITEID赋值。现象:表域
ASSETNUMDOMAIN下拉框加载极慢,F12看Network卡在domainvalues?domainname=ASSETNUMDOMAIN。
原因:ASSET表数据量大,且ASSETNUMDOMAIN未启用缓存,每次下拉都查全表。
解决:域配置里勾选“启用缓存”,并设置“缓存刷新间隔”为3600秒(1小时)。
4. 应用程序设计器:拖控件、绑数据、写代码的全流程实战
应用程序设计器(Application Designer)是Maximo的前端组装车间。它不写HTML/JS,而是用XML定义界面结构,用Java BEAN类注入业务逻辑。本章带你从零搭出一个可运行的ISSUEAPPLY应用,并打通后端MBO。
4.1 新建应用程序:模板选错,后面全白干
新建应用时,模板决定骨架:
- 标准模板(Standard Application):带完整CRUD(创建/读取/更新/删除)功能,含工具栏、搜索、列表、详细页。选它!
- 简单模板(Simple Application):只有列表页,无新建/编辑页,适合只读报表。
- 自定义模板(Custom Application):纯空白,所有控件手动拖,新手慎用。
创建步骤:
- 系统管理→应用程序设计器→新建
- 应用标识:
ISSUEAPPLY(必须与数据库对象名一致) - 应用描述:备件领用申请
- 模板:选
Standard Application - 对象:选
ISSUEAPPLY(自动绑定MBO)
注意:应用标识必须全大写、无下划线、与对象名严格一致。若填
issueapply或ISSUE_APPLY,保存后应用列表不显示,且无报错。
4.2 控件选用板:不是所有控件都适用,选错就卡死
控件是界面砖块,但Maximo里控件和数据源强绑定:
- 文本框(Text Box):绑定单个字段,如
ISSUEAPPLY.DESCRIPTION。属性“数据源”填ISSUEAPPLY,“属性”填description。 - 表(Table):绑定MboSet,如显示
ISSUEAPPLY的子表ISSUEAPPLYLINE。数据源填ISSUEAPPLYLINE(需先建好关系)。 - 标签页组(Tab Group):放多个标签页,每个标签页放不同控件。必须设“默认标签页”,否则打开应用一片灰。
- 帮助格(Help Grid):实现弹出式选择,如点“资产”按钮弹出资产选择框。需配合BEAN类(见4.5节)。
4.3 控件属性:80%的界面bug源于属性填错
每个控件有数十个属性,但关键就3个:
| 属性名 | 常用值 | 作用 | 错误后果 |
|---|---|---|---|
| 数据源(DataSource) | ISSUEAPPLY | 指定MBO对象 | 填错则控件无数据,显示空白或报错MboSet not found |
| 属性(Attribute) | status | 指定字段名 | 填错则显示/保存错字段,如填statu导致状态存不进库 |
| 只读(ReadOnly) | true/false | 控制可编辑性 | 新建页误设true,用户输不了字 |
实操:给ISSUEAPPLY.STATUS文本框设属性:
- 数据源:
ISSUEAPPLY - 属性:
status - 只读:
false(新建/编辑页需可写) - 搜索类型:
WILDCARD(支持模糊搜)
4.4 导入导出:团队协作的救命稻草
应用配置存在数据库,不能直接传文件。必须导出为XML,再导入:
- 导出:应用程序设计器→选
ISSUEAPPLY→右键“导出应用程序”→保存为ISSUEAPPLY.xml - 导入:右键“导入应用程序”→选
ISSUEAPPLY.xml→勾选“覆盖现有应用”
血泪经验:导出前务必先“保存应用”,否则导出的是旧版本。导入后,必须重启Maximo服务器,否则新界面不生效。
4.5 BEAN类:让按钮有灵魂的Java代码
BEAN类是控件的后台大脑。比如“批准”按钮,点击后要更新状态、发邮件、触发工作流——这些全写在BEAN里。
标准BEAN继承链:
psdi.app.common.CommonBean:通用BEAN,含基础CRUD方法psdi.app.issueapply.IssueApplyBean:你的自定义BEAN,继承CommonBean
关键代码段(IssueApplyBean.java):
public class IssueApplyBean extends CommonBean { // 重写save(),在保存前加校验 public void save() throws MXException, RemoteException { MboRemote mbo = getMbo(); if ("APPRL".equals(mbo.getString("status"))) { // 审批中状态,检查必填字段 if (mbo.isNull("assetnum")) { throw new MXApplicationException("issueapply", "assetnumrequired"); } } super.save(); // 调用父类保存 } // 自定义按钮方法:approve() public void approve() throws MXException, RemoteException { MboRemote mbo = getMbo(); mbo.setValue("status", "APPRD", NOACCESSCHECK); // 强制设状态 mbo.save(); // 立即保存 // 发送邮件逻辑(略) } }绑定到按钮:
- 应用程序设计器→ISSUEAPPLY→找到“批准”按钮→右键“属性”
- “BEAN类”填
psdi.app.issueapply.IssueApplyBean - “方法”填
approve
注意:BEAN类必须编译成
.class,放在maximo\applications\maximo\businessobjects\classes\psdi\app\issueapply\目录,然后重启服务器。
4.6 避坑:应用程序设计四大死亡陷阱
现象:应用导入后,打开一片空白,控制台报
NullPointerException at psdi.app.common.CommonBean.getMbo()。
原因:BEAN类里getMbo()返回null,通常因为控件“数据源”没绑定到ISSUEAPPLY,或应用标识与对象名不一致。
解决:检查应用标识、对象名、数据源三者是否完全一致;用System.out.println(getMbo())调试。现象:点击“批准”按钮无反应,控制台无日志。
原因:按钮的“方法”属性填了approve()(带括号),正确应填approve(无括号)。
解决:按钮属性→“方法”删掉括号。现象:表控件
ISSUEAPPLYLINE显示空,但数据库里有数据。
原因:ISSUEAPPLY和ISSUEAPPLYLINE的关系名没设对。BEAN里调用mbo.getMboSet("ISSUEAPPLYLINE"),但关系名实际是LINE。
解决:数据库配置→ISSUEAPPLY→关系→确认关系名与代码中getMboSet("xxx")的xxx一致。现象:导出的XML在另一环境导入失败,报
Duplicate application identifier ISSUEAPPLY。
原因:目标环境已存在同名应用,但“覆盖现有应用”没勾选。
解决:导入时务必勾选“覆盖现有应用”;或先在目标环境删掉旧应用。
5. 权限与后台任务:让系统既安全又自动化的最后两道锁
权限控制谁能看到什么、能做什么;后台任务让重复操作自动化。二者结合,才是企业级系统的底线。
5.1 权限组:粒度细到字段,不是粗放式授权
Maximo权限分三级:应用级、对象级、字段级。必须逐级配置,漏一级就失效。
- 应用授权:系统管理→安全→应用→选
ISSUEAPPLY→勾选“查看”“添加”“更改”“删除”。 - 数据限制(Object Restrictions):限制用户只能看自己站点的数据。
配置路径:安全→数据限制→新建→对象选ISSUEAPPLY→条件填siteid = :usersiteid(:usersiteid是系统变量,取当前用户站点)。 - 字段限制(Attribute Restrictions):限制敏感字段仅管理员可见。
配置路径:安全→字段限制→新建→对象ISSUEAPPLY→字段totalcost→权限组选ADMIN→勾选“查看”“更改”。
提示:
:usersiteid变量只在SITE级对象有效。若对象级别是SYSTEM,此变量为空,条件恒假,用户查不到任何数据。
5.2 后台任务:不是Linux Cron,是Maximo原生调度
后台任务(Cron Task)是Maximo内置的定时器,比OS级Cron更可靠——它随Maximo启停,任务状态存库,失败可重试。
创建步骤:
- 系统管理→后台任务→新建
- 任务标识:
ISSUEAPPLYCLEANUP - 描述:清理超期未关闭的领用单
- 任务类:
psdi.app.issueapply.CleanupTask(自定义Java类) - cron表达式:
0 0 2 * * ?(每天凌晨2点执行)
自定义任务类(CleanupTask.java):
public class CleanupTask extends CronTask { public void cronAction() throws MXException, RemoteException { MXServer mxServer = getMXServer(); MboSetRemote issueSet = mxServer.getMboSet("ISSUEAPPLY", getOwner()); // 查找超期单:status='APPRL' 且 createdate > 7天前 String where = "status = 'APPRL' and createdate < timestampadd(sql_tsi_day, -7, current_timestamp)"; issueSet.setWhere(where); issueSet.reset(); while (issueSet.moveNext()) { MboRemote mbo = issueSet.getCurrentMbo(); mbo.setValue("status", "EXPIRED", NOACCESSCHECK); } issueSet.save(); } }启用任务:
- 后台任务→选
ISSUEAPPLYCLEANUP→右键“启用” - 关键:任务类必须编译到
maximo\applications\maximo\businessobjects\classes\psdi\app\issueapply\,且重启服务器。
5.3 权限组实战:三步锁定“站点数据隔离”
目标:站点A用户只能看到/操作站点A的ISSUEAPPLY单据,且看不到totalcost字段。
步骤:
- 建权限组:安全→权限组→新建→组标识
SITEAUSER→描述“站点A用户” - 授应用权限:权限组→SITEAUSER→应用→
ISSUEAPPLY→勾选“查看”“添加”“更改” - 设数据限制:权限组→SITEAUSER→数据限制→新建→对象
ISSUEAPPLY→条件siteid = 'SITEA'(硬编码)或siteid = :usersiteid(推荐,自动适配)
验证:用站点A用户登录,
SELECT * FROM ISSUEAPPLY只返回SITEID='SITEA'的记录;用站点B用户登录,查不到任何记录。
5.4 后台任务排错:五招揪出定时任务不执行
- 招1:查任务状态:后台任务列表里,
ISSUEAPPLYCLEANUP状态必须是“启用”,不是“禁用”或“错误”。 - 招2:查cron表达式:
0 0 2 * * ?表示“秒 分 时 日 月 周 年”,若写成0 0 2 * * *(7位),任务直接不注册。 - 招3:查日志:
maximo\logs\cron.log,搜索ISSUEAPPLYCLEANUP,看是否有cronAction started。 - 招4:查MboSet权限:任务类里
mxServer.getMboSet("ISSUEAPPLY", getOwner()),getOwner()返回的MboSet必须有查询权限,否则setWhere无效。 - 招5:查事务:
issueSet.save()必须在while循环外调用一次,若在循环内调用,每条记录都提交事务,性能崩盘。
5.5 避坑:权限与后台任务的致命组合
现象:后台任务
ISSUEAPPLYCLEANUP执行后,totalcost字段被清空。
原因:字段限制里,totalcost设为“不可见”,但任务类用mbo.setValue("totalcost", null),NOACCESSCHECK跳过权限检查,仍可写。
解决:字段限制要勾选“更改”,不仅“查看”;或任务类里加判断:if (!mbo.isFieldReadOnly("totalcost")) { mbo.setValue("totalcost", null); }。现象:站点A用户能查到站点B的
ISSUEAPPLY单据。
原因:数据限制条件写成siteid like 'SITEA%',而SITEB也匹配。
解决:条件必须用=精确匹配:siteid = 'SITEA'或siteid = :usersiteid。现象:后台任务每天执行,但
cron.log里没记录。
原因:maximo.properties中mxe.cron.enable=true没配,或mxe.cron.startdelay=300(5分钟)太长,任务还没启动服务器就停了。
解决:确认mxe.cron.enable=true,mxe.cron.startdelay=60(1分钟)。
6. MBO与BEAN深度联动:从数据加载到事件拦截的七层穿透
MBO(Managed Business Object)是Maximo的数据实体,BEAN是它的控制器。二者不是松耦合,而是深度嵌套:BEAN持有MBO引用,MBO事件可触发BEAN方法。本章带你穿透七层调用链,搞懂“为什么点保存就触发了邮件”。
6.1 MBO生命周期:七个钩子函数,每个都是拦截点
MBO提供标准生命周期方法,重写即可注入逻辑:
| 方法 | 触发时机 | 典型用途 | 注意事项 |
|---|---|---|---|
init() | MBO实例化后,首次访问前 | 初始化默认值,如setValue("createdate", new Date()) | 不要在此查数据库,可能引发死锁 |
canDelete() | 用户点删除前 | 校验能否删,如“有子单据则禁止删除” | 返回false则删除按钮灰显 |
save() | 点保存按钮后,事务提交前 | 数据校验、关联更新,如“更新资产状态” | 必须调用super.save(),否则不入库 |
delete() | canDelete()返回true后 | 执行删除逻辑,如“同步删子表” | super.delete()必须最后调用 |
modify() | 字段值变更时(非保存) | 实时计算,如“单价×数量=金额” | 性能敏感,避免复杂查询 |
add() | 新建记录时 | 设默认值,如setValue("status", "DRAFT") | super.add()必须在最后 |
appValidate() | 保存前最终校验 | 业务规则,如“领用数量不能超库存” | 抛MXApplicationException中断保存 |
实战代码(IssueApplyMbo.java):
public class IssueApplyMbo extends Mbo implements MboRemote { public void save() throws MXException, RemoteException { // 步骤1:校验库存 String assetnum = getString("assetnum"); MboSetRemote invSet = getMboSet("INVENTORY"); invSet.setWhere("assetnum = '" + assetnum + "' and curbal > " + getString("quantity")); if (invSet.count() == 0) { throw new MXApplicationException("issueapply", "insufficientstock"); } // 步骤2:更新资产状态 MboSetRemote assetSet = getMboSet("ASSET"); assetSet.setWhere("assetnum = '" + assetnum + "'"); MboRemote assetMbo = assetSet.getMbo(0); if (assetMbo != null) { assetMbo.setValue("status", "ISSUED", NOACCESSCHECK); assetMbo.save(); } // 步骤3:调用父类保存,入库 super.save(); } }6.2 BEAN-MBO事件绑定:让界面操作自动触发后端
BEAN可通过addMboValueListener()监听MBO字段变化,实现“所见即所得”:
public class IssueApplyBean extends CommonBean { public void initialize() throws MXException, RemoteException { super.initialize(); // 监听assetnum字段变化 getMbo().addMboValueListener(new MboValueAdapter(this) { public void action(MboRemote mbo, String attribute) throws MXException, RemoteException { if ("assetnum".equals(attribute)) { // 资产编号变了,自动带出资产描述 String assetnum = mbo.getString("assetnum"); MboSetRemote assetSet = getMboSet("ASSET"); assetSet.setWhere("assetnum = '" + assetnum + "'"); MboRemote assetMbo = assetSet.getMbo(0); if (assetMbo != null) { setValue("assetdesc", assetMbo.getString("description")); // 自动填描述 } } } }); } }本文还有配套的精品资源,点击获取