1 概述
????????随着信创国产化的推进,要求去 IOE 使用国产的替代方案,数据库方面需要用国产数据库来替换ORACLE、DB2等数据库。基于达梦数据库对Oracle的高度兼容,我们在考虑替代产品的时候可以优先选择使用达梦数据库。
????????Activiti 是一个工作流引擎, Activiti 可以将业务系统中复杂的业务流程抽取出来,使用专门的建模语言(BPMN2.0)进行定义,业务系统按照预先定义的流程进行执行,实现了业务系统的业务流程由 Activiti 进行管理,减少业务系统由于流程变更进行系统升级改造的工作量,从而提高系统的健壮性,同时也减少了系统开发维护成本。
????????由于Activiti不支持达梦数据库,需要下载源码进行修改重新编译打包。
2 修改源码
2.1 源码下载
由于官网不提供activiti6的下载了,需要到github上下载,若guithub下载缓慢,可到百度网盘下载,下载地址如下:
activiti6.0.0:https://github.com/Activiti/Activiti/releases/download/activiti-6.0.0/activiti-6.0.0.zip
2.2 导入源码
????????将源码导入到idea开发工具中,项目结构图如下:
2.3 修改Java类
2.3.1 org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl类,增加成员变量
public static final String DATABASE_TYPE_H2 = "h2";
public static final String DATABASE_TYPE_HSQL = "hsql";
public static final String DATABASE_TYPE_MYSQL = "mysql";
public static final String DATABASE_TYPE_ORACLE = "oracle";
public static final String DATABASE_TYPE_POSTGRES = "postgres";
public static final String DATABASE_TYPE_MSSQL = "mssql";
public static final String DATABASE_TYPE_DB2 = "db2";
public static final String DATABASE_TYPE_DM = "dm";// 适配达梦,增加成员变量
2.3.2 org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl 类getDefaultDatabaseTypeMappings()方法增加达梦适配代码
public static Properties getDefaultDatabaseTypeMappings() {
Properties databaseTypeMappings = new Properties();
databaseTypeMappings.setProperty("DM DBMS", DATABASE_TYPE_DM);// 适配达梦,增加修改
databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL);
databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
......
}
2.2.3 修改org.activiti.engine.impl.db.DbSqlSessionFactory 类的 initBulkInsertEnabledMap(String databaseType)方法
protected void initBulkInsertEnabledMap(String databaseType) {
bulkInsertableMap = new HashMap<Class<? extends Entity>, Boolean>();
for (Class<? extends Entity> clazz : EntityDependencyOrder.INSERT_ORDER) {
bulkInsertableMap.put(clazz, Boolean.TRUE);
}
// Only Oracle is making a fuss in one specific case right now
// 适配达梦,增加修改
if ("oracle".equals(databaseType) || "dm".equals(databaseType)) {
bulkInsertableMap.put(EventLogEntryEntityImpl.class, Boolean.FALSE);
}
}
2.2.4 修改org.activiti.engine.impl.AbstractQuery 类的 addOrder(String column, String sortOrder, NullHandlingOnOrder nullHandlingOnOrder)方法
if (nullHandlingOnOrder.equals(NullHandlingOnOrder.NULLS_FIRST)) {
if (ProcessEngineConfigurationImpl.DATABASE_TYPE_H2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_HSQL.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_POSTGRES.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_ORACLE.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_DM.equals(databaseType)) //适配达梦
{
orderBy = orderBy + defaultOrderByClause + " NULLS FIRST";
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL.equals(databaseType)) {
orderBy = orderBy + "isnull(" + column + ") desc," + defaultOrderByClause;
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_DB2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_MSSQL.equals(databaseType)) {
orderBy = orderBy + "case when " + column + " is null then 0 else 1 end," + defaultOrderByClause;
} else {
orderBy = orderBy + defaultOrderByClause;
}
} else if (nullHandlingOnOrder.equals(NullHandlingOnOrder.NULLS_LAST)) {
if (ProcessEngineConfigurationImpl.DATABASE_TYPE_H2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_HSQL.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_POSTGRES.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_ORACLE.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_DM.equals(databaseType)) //适配达梦 {
orderBy = orderBy + column + " " + sortOrder + " NULLS LAST";
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_MYSQL.equals(databaseType)) {
orderBy = orderBy + "isnull(" + column + ") asc," + defaultOrderByClause;
} else if (ProcessEngineConfigurationImpl.DATABASE_TYPE_DB2.equals(databaseType)
|| ProcessEngineConfigurationImpl.DATABASE_TYPE_MSSQL.equals(databaseType)) {
orderBy = orderBy + "case when " + column + " is null then 1 else 0 end," + defaultOrderByClause;
} else {
orderBy = orderBy + defaultOrderByClause;
}
}
2.4 修改资源文件
????????Activiti在运行期间还会用的一下资源文件,这些文件中包括创建表、删除表等,如下图:
2.4.1 create文件夹下复制activiti.oracle.create.engine.sql改名为activiti.dm.create.engine.sql,复制activiti.oracle.create.history.sql改名为activiti.dm.create.history.sql,复制activiti.oracle.create.identity.sql改名为activiti.dm.create.identity.sql
2.4.2 drop文件夹下复制activiti.oracle.drop.engine.sql改名为activiti.dm.drop.engine.sql,复制activiti.drop.create.history.sql改名为activiti.dm.drop.history.sql,复制activiti.drop.create.identity.sql改名为activiti.dm.drop.identity.sql
?2.4.3 properties文件夹下复制oracle.properties改名为dm.properties
?2.5 打包activiti-engine项目install到本地仓库
3 创建activiti6项目
3.1 创建项目
????????直接在IDEA上File ?->?New ?->?Project ?->?Spring Initializr ?->?Next ?即可创建简单的springboot项目。
3.2 引入依赖
? ? ? ?
使用 mvn install?将 DM7/8 驱动程序打入 Maven 仓库。
<!-- dm -->
<dependency>
<groupId>com.dm</groupId>
<artifactId>DmJdbcDriver</artifactId>
<version>1.8.0</version>
</dependency>
<!-- activiti -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
3.3?配置application.yml文件
????????配置达梦数据库相关的驱动和链接。
server:
port: 8080
tomcat:
uri-encoding: UTF-8
spring:
datasource:
url: jdbc:dm://192.168.85.4:5236
username: SYSDBA
password: SYSDBA
driver-class-name: dm.jdbc.driver.DmDriver
activiti:
check-process-definitions: false
database-schema-update: true
database-schema-update 分为 4 种
flase: 默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常。(生产环境常用) true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建。(开发时常用) create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)。(单元测试常用) drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
?3.4 在resource下面新建一个activiti.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcDriver" value="dm.jdbc.driver.DmDriver"></property>
<property name="jdbcUrl" value="jdbc:dm://192.168.85.4:5236"></property>
<property name="jdbcUsername" value="SYSDBA"></property>
<property name="jdbcPassword" value="SYSDBA"></property>
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
</beans>
3.5 IDEA下载Activiti BPMN visualizer插件
?3.6 新建流程文件
确定之后会自动生成一个xml文件。
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.activiti.org/processdef">
<process id="test" name="test" isExecutable="true">
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_test">
<bpmndi:BPMNPlane bpmnElement="test" id="BPMNPlane_test">
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
?在文件的任意位置点击右键:view bpmn(Activiti)Diagram,然后可以进行流程设计。
?3.7 单元测试
@Test
public void deployProcess() {
ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml").buildProcessEngine();
//ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment().addClasspathResource("bpm/repair.bpmn20.xml").deploy();
System.out.println(deploy.getId());
}
执行后会自动创建activiti6数据表并存入流程信息。
启动流程测试如下:
//启动流程
@Test
public void startProcess(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
runtimeService.startProcessInstanceByKey("repair");//流程的名称,也可以使用ByID来启动流程
}
}
查看下启动流程信息如下:
4 附录
达梦在线服务平台:https://eco.dameng.com/
|