简介:这是一份面向Maximo初学者的基本培训文档,以系统化的方式讲解Maximo资产管理与工作流自动化软件的核心概念与实际操作。文档重点涵盖数据库配置与属性配置两大模块,包括对象与主对象、持久性、级别、类,以及属性类型与长度、等同属性、搜索类型、虚拟字段、缺省值、自动编号、字段绑定类等内容;同时涉及关联、索引、configdb配置和章节练习,帮助企业维护管理、设施管理和资产跟踪场景中的用户快速形成整体认知。资源共1个文件,为doc格式文档,压缩包大小5.96MB,正文按章节组织、层次清晰,既有概念讲解也有练习指引。目前已有253人浏览学习,适合想要掌握Maximo基础配置逻辑、理解后台数据模型及属性机制的企业技术人员和运维学习者参考使用。
1. Maximo 数据库配置语义:对象、属性与 configdb 的执行边界
Maximo 这类资产管理与工单系统,真正的门槛不在点按钮,而在「数据库配置」这套配置层逻辑:你在界面里建对象、加字段,只是改了配置元数据,数据库里的表结构并没有变,必须跑一次 configdb 才真正落库。这个「两段式」设计是新手最容易翻车的地方,也是本文要拆的第一层。它适合刚接手 Maximo 实施或二次开发的工程师,也适合想弄明白对象、属性、关联、索引之间关系的运维人员。读完你至少能回答三个问题:对象和表怎么对应、属性类型怎么选、什么时候必须跑 configdb。
2. 对象建模与属性设计:类型、等同属性、搜索类型与脚本化建表
2.1 对象、表与持久性的三角关系
数据库配置里的「对象」,对应数据库里的一张表,但两者不是同步变化的。新建对象时,对象状态是「待添加」,此时你在数据库客户端里查不到这张表;只有跑完 configdb,系统才根据配置生成对应的建表脚本并执行。反过来,修改了字段长度、删掉一个字段,也是同样的套路——配置改了,表结构还是旧的,必须再次触发 configdb 才会同步。
这里有个很容易忽略的概念:持久性。默认新建对象是选中持久性的,说明它需要物理表;如果去掉持久性,这个对象就是虚拟对象,configdb 后数据库里也不会有表,数据自然存不进去。虚拟对象可以在内存里构造数据用于界面展示或临时计算,但关掉页面数据就丢了。我一般只在做报表中间对象、或者承接外部系统传入数据做实时展示时才用虚拟对象。
级别也是建模时要定死的。默认是 SYSTEM,常用还有 ORG 和 SITE。SITE 级别要求属性里必须带 SITEID 和 ORGID 两个字段,ORG 级别要求至少带 ORGID,否则 configdb 会直接报错。这个限制是平台多组织架构的硬性要求,不能绕过。另外,只有主对象才能挂工作流,子表、关联表如果不需要流程驱动,不必设为主对象。
对象绑定类是对象级别的逻辑入口,默认是psdi.mbo.custapp.CustomMboSet。如果你要写对象级的新建、删除、保存逻辑,就自定义一个类写在「类」字段里,这点后面第四章展开。
查对象元数据,我习惯用这段 SQL 确认对象真实状态:
select objectname, description, persistent, mainobject, siteid, orgid from maxobject where objectname in ('TEST', 'TESTLINE') order by objectname;逻辑说明:MAXOBJECT是系统存放对象定义的表,persistent为 1 表示持久化对象,mainobject为 1 表示主对象,siteid和orgid两个字段体现级别要求。参数说明:查询条件里的 TEST 和 TESTLINE 是培训练习用的两个对象名,你可以换成自己项目的对象名;如果查出来persistent = 0,说明这是虚拟对象,别指望它落库。
2.2 属性类型选型与等同属性的联动
属性就是表的字段。在数据库配置里新增一个属性时,类型选错是后期返工的重灾区。常用类型里,ALN 用于汉字、字母、数字混合串;UPPER 会自动把小写转大写,适合单号、资产编号这种需要统一格式的场景;DATE 只有年月日,DATETIME 带时分秒,注意 DATETIME 在底层存的是 UTC 时间,跨时区展示会出现「对不上」的错觉;DECIMAL 默认两位小数,位数不够会造成四舍五入;INTEGER 是整数;YORN 只有 1 或 0,配合界面上的复选框使用。
等同属性是 Maximo 里一个很实用的机制。两个对象的属性配成等同关系后,它们共享同一套类型和长度定义;修改其中一个,所有等同的属性同步改。平台强制要求 ORGID 必须等同于 ORGANIZATION 对象的 ORGID,SITEID 必须等同于 SITE 对象的 SITEID。这个强制设计是为了保证跨对象数据在组织结构维度上能对齐。我自己加字段时,凡是涉及组织或站点的字段,一律先去确认参照对象,避免踩到等同属性的坑。
检查等同属性配置,可以用这段 SQL:
select attributename, sameasobject, sameasattribute, ptype, length from maxattribute where attributename in ('ORGID', 'SITEID');逻辑说明:sameasobject和sameasattribute填了值,才表示当前字段是等同字段;ptype是字段类型,length是长度。参数说明:如果 ORGID 查出来sameasobject为空,你在 configdb 时大概率会碰到外键参照异常,需要先补等同关系再同步。
另一个容易被忽略的是搜索类型。只有勾选了搜索类型的字段,才能出现在界面的搜索对话框里。我见过不少项目,字段建了一堆,用户想按某个编号搜索却搜不了,原因是当初没勾搜索类型。字段绑定类则是给字段挂自定义校验逻辑用的,挂的是MboValueAdapter的子类,开发的时候注意类名要写全限定名。
2.3 新建对象到 configdb 的落地步骤
新建一个可用的持久化对象,完整路径是:数据库配置 → 新建对象 → 填名称和描述 → 确认持久性 → 加属性 → 加索引和关系 → 跑 configdb。实际操作里,把属性、索引、关系都配好后,最后一步才跑 configdb,避免反复同步。
configdb 命令常见做法是在部署目录执行:
cd /opt/maximo/deployment ./configdb.sh -u MAXADMIN -p <password> -d ORACLE逻辑说明:-u是管理员账号,-p是密码,-d指定数据库类型。执行后它会对比配置库和物理库的差异,生成 DDL 并按对象状态标记去执行。参数说明:Oracle 场景用-d ORACLE,SQL Server 场景改成-d SQLSERVER;如果你不想一次性同步所有对象,先查maxobject里对象状态是「待添加」或「待修改」的那些,只勾选它们再跑。
注意,configdb 是不可逆操作。生产环境动表结构之前,我强烈建议先做两件事:导出一份数据库配置定义,再对数据库做一次物理备份。这样即便 DDL 执行到一半报错,也能恢复现场重新来。
2.4 练习:test 与 testline 两张表的搭建
这个练习是模拟业务主表和子表的典型结构。先建主对象 TEST,持久性选中,属性至少包含 TESTID(关键属性,唯一标识)、DESCRIPTION 和一个 SITEID。再建子对象 TESTLINE,TESTID 作为外键指向 TEST,另加 LINENUM 做行号、DESCRIPTION 做描述。之后在数据库配置里把 TESTLINE 的 TESTID 定义成与 TEST 的 TESTID 等同,并建立对象关系,关系方向是从 TEST 到 TESTLINE,外键字段是 TESTID。
跑完 configdb,可以在数据库里确认 TEST 和 TESTLINE 两张表都建出来了,再测试数据的插入和查询。这个练习跑通了,对象、属性、等同关系、外键关系这一条主线就通了。
2.5 几个常见的建模误用
有人在数据库配置里加了字段,立刻去前台界面查这个字段,发现没有——原因是没跑 configdb;有人把虚拟对象当成普通业务对象用,保存时发现数据永远不落库;有人建 SITE 级对象,忘记加 SITEID 和 ORGID,configdb 直接失败;还有人 DECIMAL 精度设得太小,月度数据被四舍五入到个位数,后期对账对不上。这些都属于「配置层没想清楚就往下走」的典型问题,建议每建一个对象都先做一次最小验证,而不是攒一堆配置再统一同步。
3. 域与应用程序设计器:从字段约束到界面布局的落地
3.1 域的作用与添加流程
域,本质是给属性加一层取值约束。员工状态只允许「在职、离职、休假」三种,优先级只有 P1/P2/P3,这类需求在 Maximo 里就是靠域实现的。域的添加入口在域应用程序里:新建域 → 选域类型 → 配取值来源 → 编辑域值列表 → 保存。之后回到数据库配置,把域绑定到具体属性的「域」字段上,界面录入时就会弹出可选值,而不是让用户随便输入。
域有三种常见类型,选型看取值来源:
| 域类型 | 取值来源 | 典型场景 | 注意点 |
|---|---|---|---|
| MBO 域 | 另一个对象的字段值 | 状态关联对象 | 需要先配置对象关系 |
| 表域 | MAXTABLE 里的数据列 | 引用已有基础数据 | 有行数上限,量大慎用 |
| 用户定义域 | 手工录入的静态值列表 | 优先级、类别标签 | 值大小写敏感 |
编辑域值的时候,每条值要做两件事:填实际存储值,再填一个中文描述。不少人只填了值没填描述,界面上下拉框里全是英文代码,用户根本看不懂。另外域值对大小写敏感,'P1' 和 'p1' 会被当作两个值处理,录入时建议统一规范。
3.2 应用程序设计器的控件体系
应用程序设计器是做界面布局的地方。打开设计器后,左侧是控件选用板,中间的「显示」是应用根容器,其他控件都挂在它下面。这套控件体系可以理解成一个树状结构:最外层是显示(Presentation),往下一层是标签页组(Tab Group),再往下是标签页(Tab),标签页里是部分(Section),部分里放具体控件。
常用控件的定位,我用一张表说明:
| 控件 | 用途 | 核心属性 |
|---|---|---|
| 显示(Presentation) | 应用根容器,定义主键 | Maindatasrc |
| 标签页组(Tab Group) | 多页签容器 | 显示名称 |
| 标签页(Tab) | 单页 | 数据源 |
| 部分(Section) | 页内区域 | 数据源、外键条件 |
| 部分行 / 部分列(Section Column) | 区域内网格布局 | 栅格比例 |
| 文本框(Text Box) | 单字段录入 | 属性名 |
| 多部分文本框(Multipart Textbox) | 多字段组合显示 | 主键字段组合 |
| 表(Table) | 子表网格 | 数据源、外键管理 |
| 表列(Table Column) | 子表里的列 | 属性映射 |
| 复选框(Check Box) | YORN 字段 | 属性名 |
| 附件(Attachments) | 附件挂接 | 附件类型 |
| 帮助格(Help Grid) | 带帮助信息的表格 | 数据源 |
| 按钮(Pushbutton) | 触发事件 | 事件指向 BEAN 类方法 |
这些控件里最常用的是显示、标签页组、部分、文本框和表。一个典型的应用布局:显示控件做主容器,标签页组做一级导航,标签页里放部分,部分里放文本框录入头部字段,再放一个表控件展示子表明细。控件之间靠「数据源」串联,数据源指向当前对象和子对象,拉错数据源会导致页面空白或数据加载不对。
3.3 从空白应用到一个可用界面的操作顺序
新建应用程序后,进入设计器,按这个顺序搭界面不容易乱:
- 在显示控件上设置主键字段,一般为对象的关键属性。
- 添加标签页组,命名如「基本信息」「明细」。
- 在标签页里添加部分,设置部分的数据源。
- 在部分里拖入文本框,为每个文本框指定属性名。
- 添加表控件,把子对象的数据源和外键字段配好。
- 保存布局,用预览功能检查页面是否正常展示。
这个顺序是我实际项目里的习惯,核心在于先定主键和数据源,再摆控件。反过来先拖控件再配数据源,经常出现控件属性和数据源对不上,界面加载报错的情况。
3.4 应用的导入导出与升级维护
应用做完了,测试环境验证通过,往生产环境迁移用的是导入导出功能。导出会把应用的布局、签名选项、授权信息打包成一个应用定义文件,导入到目标环境后,再手工把应用授权分配给对应权限组。
这里有两个坑:一是导出前必须保证数据库配置是已同步状态,否则导出的应用里引用了数据库里不存在的表,目标环境导入后界面会挂;二是多人同时改一个应用,后导出的人会覆盖先导出的人的全部改动,所以一般只安排一个人负责某个应用的布局维护。
3.5 控件属性的几个关键参数
控件的属性框里有几个高频参数要认准。显示控件的 Maindatasrc 决定这个应用的主数据源,填错了整个页面白屏;表控件的 datasrc 填子对象名,外键字段要和父子关系对齐;多部分文本框一般用于主键加描述的组合展示,比如把单号和描述拼在一个框里;按钮控件的「事件」里填写 BEAN 类方法名,按钮点击后调用对应方法,这部分逻辑在第 4 章展开。
签名选项控制的是菜单按钮对用户的可见性与可用性,比如「新建」「删除」按钮在什么场景下隐藏或灰掉,跟权限组配合起来用。选型时注意不要把签名选项做成全局放开的,生产环境里误删工单的事故,多数是因为删除按钮对所有人生效。
4. 程序扩展:MBO 类、MboSet 与 BEAN 类的代码骨架
4.1 程序路径与类的三种角色
数据库配置里的「程序」章节,本质是给对象和界面挂 Java 逻辑。程序路径决定这个类归哪个模块管,类名必须用全限定名。开发时最常见的三类类:MBO 类处理表级逻辑,比如保存前校验、删除前拦截;MboSet 类处理集合操作,比如查询过滤、批量更新;BEAN 类处理界面交互,比如按钮事件、工具栏菜单。
| 类类型 | 继承基类 | 挂载位置 | 典型场景 |
|---|---|---|---|
| MBO 字段类 | MboValueAdapter | 属性的字段绑定类 | 字段校验、值自动计算 |
| MBO 类 | CustomMbo 子类 | 对象的绑定程序 | 记录级逻辑、init/save/delete |
| MboSet 类 | CustomMboSet | 对象的绑定程序 | 集合查询、批量处理 |
| BEAN 类 | CustAppBean | 应用程序主类 | 按钮事件、工具栏菜单 |
| 对话框类 | SelectBean 子类 | 选择对话框 | 多选、单选返回记录 |
这个表格基本覆盖了二次开发 80% 的场景。平台自身的扩展点就是这些,理解了每个类的职责,看到代码文件就能判断它挂在哪一层。
4.2 MBO 字段类:字段级校验逻辑怎么挂
字段类是最轻量的扩展点,适合做单个字段的校验或赋值。下面是一个状态字段的校验样例:
package com.demo.asset; import psdi.mbo.MboValue; import psdi.mbo.MboValueAdapter; import psdi.util.MXException; import java.rmi.RemoteException; public class FldTestStatus extends MboValueAdapter { public FldTestStatus(MboValue mbv) { super(mbv); } public void validate() throws MXException, RemoteException { super.validate(); String status = getMboValue().getString(); if ("NEW".equalsIgnoreCase(status) && !getMboValue().getMbo().isNew()) { throw new MXException("已保存记录不允许变更为 NEW 状态"); } } }逻辑说明:validate方法在字段值保存前执行,这里先取出字段当前值status,再判断如果值为 NEW 且当前 Mbo 不是新增记录,就抛出异常拦截。参数说明:getMboValue().getMbo().isNew()是判断当前记录是否新增的标准写法;getMboValue().getString()拿到的是字段当前的字符串值。字段绑定类配置在数据库配置的「字段绑定类」字段里,类名要写全限定名。
4.3 MBO 类与 MboSet 类:记录级与集合级逻辑
MBO 类适合在init、save、delete生命周期里塞逻辑。比如新单默认带一个工作类型,可以这样写:
package com.demo.asset; import java.rmi.RemoteException; import psdi.mbo.MboRemote; import psdi.mbo.custapp.CustomMbo; import psdi.util.MXException; public class CustomAssetMbo extends CustomMbo { public CustomAssetMbo(MboRemote mbv) { super(mbv); } public void init() throws MXException, RemoteException { super.init(); if (isNew()) { setValue("WORKTYPE", "CM", 11L); } } }逻辑说明:init()在 Mbo 实例化之后执行,isNew()判断是新增记录,setValue的第三个参数11L是访问控制标识,表示允许在此阶段赋值。配置对象绑定类时,把这个类写到「类」字段,并同时配置对应的 MboSet 类。
MboSet 类更常用于后台批量处理,比如一次把所有已过期资产的状态改成停用。这类逻辑也常被后台任务程序调用,和第六章的后台任务天然配合。
Mbo 对象的获取和遍历,经常在 BEAN 类或后台程序里写:
MboSetRemote assetSet = mxSession.getMboSet("ASSET", userInfo); assetSet.setWhere("STATUS IN ('ACTIVE','REVIEW')"); assetSet.reset(); MboRemote asset = assetSet.moveFirst(); while (asset != null) { String assetnum = asset.getString("ASSETNUM"); System.out.println("处理资产: " + assetnum); asset = assetSet.moveNext(); } assetSet.save();逻辑说明:setWhere设置查询条件,reset()让条件生效,moveFirst和moveNext遍历集合,save()统一保存。参数说明:setWhere里的 SQL 片段直接拼到查询里,注意值是动态拼接时要防止注入;ASSET是对象名,必须和数据库配置里的对象名一致。
4.4 BEAN 类:按钮事件与工具栏菜单
BEAN 类挂在应用上,处理按钮事件。设计器里按钮的「事件」属性填的就是这个类里的方法名。一个典型的按钮处理方法:
package com.demo.asset; import java.rmi.RemoteException; import psdi.mbo.MboRemote; import psdi.mbo.MboSetRemote; import psdi.util.MXException; import psdi.webclient.beans.custapp.CustAppBean; public class CustAssetAppBean extends CustAppBean { public void generateReport() throws MXException, RemoteException { MboRemote current = getMbo(); String assetnum = current.getString("ASSETNUM"); System.out.println("对当前资产生成报表: " + assetnum); } }逻辑说明:getMbo()返回当前选中行,getMboSet()返回整个应用的数据集。这个方法是按钮事件入口,实际业务里可以在里面再调 MboSet 做批量处理。参数说明:generateReport这个方法是设计器里事件字段用的方法名,方法名要 public,否则按钮点击后会报找不到方法。
4.5 选择对话框类:多选与单选
对话框类用于弹窗选记录。多选对话框继承 SelectBean,返回一个 MboSet,适合从查询结果里勾选多行批量加入;单选对话框返回单条记录,适合选一个主表记录然后带出它的子表数据。两者的差异很小,核心是看页面交互需要多选还是单选。配好对话框类后,在设计器的「选择操作」里把对话框添加进应用的查询按钮组,用户点查询时弹出的就是你的对话框。
5. 权限与后台任务:三组高频踩坑与排查手册
5.1 权限组配好了,登录还是看不到应用
现象:在权限组里给某个应用勾选了授权,用户登录后菜单里根本没有这个应用。
原因:常见的两种情况。一是用户没有被加到对应的权限组;二是应用本身有签名选项限制,菜单按钮对某些用户不可见。
解决:先到安全组维护里确认用户所属权限组,再到应用程序授权里确认权限组对该应用有「菜单」和「显示」授权。签名选项里如果有「未授权用户隐藏」之类的勾选,检查当前用户的权限情况。曾有项目把权限组配到了一口数据库里,另一套环境没同步,导致生产环境时好时坏,这种环境差异问题建议直接用配置导出对比。
5.2 数据限制不生效:对象限制与属性限制的叠加逻辑
现象:给权限组设置了对象限制,比如 WHERE 条件ORGID = 'CN',但用户依然能查到其他组织的数据。
原因:数据限制里「启用」开关没打开;或者是对象限制和属性限制叠加时,属性限制放得比对象限制宽,导致限制被绕过。
解决:打开数据限制,确认对象限制处于启用状态,应用列表里勾选上该应用。对象限制里写 WHERE 条件时,字段名必须是对象上真实存在的属性名,比如ORGID,别写数据库物理字段名。属性限制会让用户在界面上只看到指定字段,但它管的是列而不是行,别用它来替代对象限制做行级隔离。
5.3 后台任务没跑:定义、实例、启用三个开关
现象:后台任务按培训文档创建了,第二天去看,任务根本没执行。
原因:后台任务分「后台任务定义」和「后台任务实例」两层。只建了定义,没建实例,任务不会自动跑;或者建了实例但实例没启用。
解决:先确认后台任务定义存在,再创建一个后台任务实例,实例里配置调度的频率和时间窗,最后把实例状态启用。启用的实例在后台任务列表里应该显示为「已启用」。另外,实例的「服务器组」参数留空或选错了组,任务也不会被调度器拾取。我一般会选具体的服务器组而不是留空,避免跨环境调度错乱。
5.4 后台任务程序报错:日志在哪看
现象:后台任务实例显示失败,程序状态变成 FAILED。
原因:大多数是脚本运行时异常,比如查了一个不存在的对象名、字段类型不匹配、SQL 权限不足。还有一类是任务程序里写了死循环,导致任务跑超时。
解决:先看系统日志和任务实例的日志跟踪,找到具体异常堆栈。再手动执行一次任务程序里的逻辑,把问题定位在数据还是 SQL 上。后台任务程序尽量在任务开头就打印入参和当前用户信息,排错时能少绕很大一圈。
5.5 configdb 跑挂了:先备份还是先恢复
现象:configdb 执行到一半报外键冲突或字段类型转换失败,物理表状态和配置元数据不一致,后续所有操作都异常。
原因:configdb 是一次执行大量 DDL 的过程,中途任何一条 DDL 失败,前面成功的部分不会自动回滚,表结构和元数据就对不上了。
解决:生产环境跑 configdb 之前,先做配置导出和数据库物理备份。失败之后不要直接在当前状态下继续跑第二遍,先把数据库恢复到备份点,重新核对配置差异,再执行同步。追求效率而跳过备份,几乎是我见过所有 configdb 事故的共同起因。
6. 验证与进阶:一套四步验收法与 configdb 边界
配置做完不一定算做完,我用一套四步验收法确认新对象真的可用。第一步,查元数据状态:maxobject和maxattribute里对象状态是「已同步」,而不是「待添加」。第二步,直接连数据库确认物理表存在,字段名、类型、长度和配置一致,索引和关系也都建出来了。第三步,在前台创建一个测试记录,走一遍新建、编辑、保存、删除的完整链路。第四步,用一个只分配了受限权限组的测试账号,验证数据限制是否真的生效。四步全过,这个配置才能说上线。
进阶技巧是盯住 configdb 的边界。configdb 只负责表结构的增删改,不负责数据迁移。你把字段长度从 10 改成 30,没问题;你把一个字段类型从 ALN 改成 DECIMAL,里面全是汉字的老数据,configdb 会直接报转换错误。凡涉及类型变更,先清理或转换数据再同步。后台任务排错时也是一样的道理:任务程序只是 Java 逻辑的包装,真正查问题要看异常堆栈和数据库日志,别只盯着任务状态猜。
我从那以后每次改对象定义之前都强制走一遍配置导出、建表脚本备份、最小数据验证三步,这个习惯帮我挡住了至少三次生产事故:一次是漏配等同属性导致外键参照失败,一次是字段类型改窄导致老数据被截断,还有一次是后台任务实例没启用导致日报三天没生成。每一条都是配置层的小问题,后果却都够喝一壶。希望帮到你。
本文还有配套的精品资源,点击获取