activiti工作流使用其他数据库

时间:2024-04-06 16:15:27

由于工作需要,需要将数据库变为国产数据库。导致activiti工作流不能使用。网上没找到类似解决方案,经过解决,记录总结方法如下。

activiti工作流支持的数据库

根据源码了解activiti工作流支持以下数据库。
activiti工作流使用其他数据库

一、工作流报错

配置好国产数据库,(这头不说如何配置了,百度都有)启动项目!
activiti工作流使用其他数据库
首次启动项目时候报如下错误。找不到名为KingbaseES的数据库
activiti工作流使用其他数据库

二、修改源码

因为activiti是开源的所以可以进行修改(不得不感叹开源真好)
修改的jar包为:acticiti-engin-5.16.4.jar
一共要修改jar包下这2个类。
org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl
org.activiti.engine.impl.cfg.DbSqlSessionFactory

1、找到第一个类

使用Eclipse反编译工具打开这个类。
在src/main/java下创建一个和这个类路径一样的Package。
activiti工作流使用其他数据库
(1)如这个类是org.activiti.engine.impl.cfg。那么创建的Package名字也是这个。(为了修改后可以编译成class文件。因为其中引入了很多包,所以使用JVM的javac会编译失败)

(2)接下来创建一个与class一摸一样的java文件。
activiti工作流使用其他数据库
(3)复制class全文内容到java文件
(4)在public static final String DATABASE_TYPE_DB2 = “db2”;这句话下面新增一个数据库属性。(这里叫做kingbase)如下:

protected static Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();

	public static final String DATABASE_TYPE_H2 = "h2";
	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_KINGBASE = "kingbase";

(5)在protected static Properties getDefaultDatabaseTypeMappings()这个方法体里面加入一个setProperty。如下:
因为前面提醒activiti没有KingbaseES,所以我们创建一个这个。

protected static Properties getDefaultDatabaseTypeMappings() {
		Properties databaseTypeMappings = new Properties();
		databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
		databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
		databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
		databaseTypeMappings.setProperty("PostgreSQL", DATABASE_TYPE_POSTGRES);
		databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
		databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
		databaseTypeMappings.setProperty("KingbaseES", DATABASE_TYPE_KINGBASE);
		return databaseTypeMappings;
	}

2、找到第二个类

(1)与上面处理方法一样,创建一个一样的Package,然后创建一个一摸一样java文件。
(2)在static{}语句块中新增一段(其中注释kingbase下面就是我新增的)。
PS:因为我所使用的国产数据库与oracle类似,所以我将oracle粘贴了一份,将其中oracle修改成了kingbase,这里的kingbase字段,就是修改第一个类时候起的。

static {

		String defaultOrderBy = " order by ${orderBy} ";

		// h2
		databaseSpecificLimitBeforeStatements.put("h2", "");
		databaseSpecificLimitAfterStatements.put("h2", "LIMIT #{maxResults} OFFSET #{firstResult}");
		databaseSpecificLimitBetweenStatements.put("h2", "");
		databaseOuterJoinLimitBetweenStatements.put("h2", "");
		databaseSpecificOrderByStatements.put("h2", defaultOrderBy);

		// mysql specific
		databaseSpecificLimitBeforeStatements.put("mysql", "");
		databaseSpecificLimitAfterStatements.put("mysql", "LIMIT #{maxResults} OFFSET #{firstResult}");
		databaseSpecificLimitBetweenStatements.put("mysql", "");
		databaseOuterJoinLimitBetweenStatements.put("mysql", "");
		databaseSpecificOrderByStatements.put("mysql", defaultOrderBy);
		addDatabaseSpecificStatement("mysql", "selectProcessDefinitionsByQueryCriteria",
				"selectProcessDefinitionsByQueryCriteria_mysql");
		addDatabaseSpecificStatement("mysql", "selectProcessDefinitionCountByQueryCriteria",
				"selectProcessDefinitionCountByQueryCriteria_mysql");
		addDatabaseSpecificStatement("mysql", "selectDeploymentsByQueryCriteria",
				"selectDeploymentsByQueryCriteria_mysql");
		addDatabaseSpecificStatement("mysql", "selectDeploymentCountByQueryCriteria",
				"selectDeploymentCountByQueryCriteria_mysql");
		addDatabaseSpecificStatement("mysql", "selectModelCountByQueryCriteria",
				"selectModelCountByQueryCriteria_mysql");
		addDatabaseSpecificStatement("mysql", "updateExecutionTenantIdForDeployment",
				"updateExecutionTenantIdForDeployment_mysql");
		addDatabaseSpecificStatement("mysql", "updateTaskTenantIdForDeployment",
				"updateTaskTenantIdForDeployment_mysql");
		addDatabaseSpecificStatement("mysql", "updateJobTenantIdForDeployment", "updateJobTenantIdForDeployment_mysql");

		// postgres specific
		databaseSpecificLimitBeforeStatements.put("postgres", "");
		databaseSpecificLimitAfterStatements.put("postgres", "LIMIT #{maxResults} OFFSET #{firstResult}");
		databaseSpecificLimitBetweenStatements.put("postgres", "");
		databaseOuterJoinLimitBetweenStatements.put("postgres", "");
		databaseSpecificOrderByStatements.put("postgres", defaultOrderBy);
		addDatabaseSpecificStatement("postgres", "insertByteArray", "insertByteArray_postgres");
		addDatabaseSpecificStatement("postgres", "updateByteArray", "updateByteArray_postgres");
		addDatabaseSpecificStatement("postgres", "selectByteArray", "selectByteArray_postgres");
		addDatabaseSpecificStatement("postgres", "selectResourceByDeploymentIdAndResourceName",
				"selectResourceByDeploymentIdAndResourceName_postgres");
		addDatabaseSpecificStatement("postgres", "selectResourcesByDeploymentId",
				"selectResourcesByDeploymentId_postgres");
		addDatabaseSpecificStatement("postgres", "insertIdentityInfo", "insertIdentityInfo_postgres");
		addDatabaseSpecificStatement("postgres", "updateIdentityInfo", "updateIdentityInfo_postgres");
		addDatabaseSpecificStatement("postgres", "selectIdentityInfoById", "selectIdentityInfoById_postgres");
		addDatabaseSpecificStatement("postgres", "selectIdentityInfoByUserIdAndKey",
				"selectIdentityInfoByUserIdAndKey_postgres");
		addDatabaseSpecificStatement("postgres", "selectIdentityInfoByUserId", "selectIdentityInfoByUserId_postgres");
		addDatabaseSpecificStatement("postgres", "selectIdentityInfoDetails", "selectIdentityInfoDetails_postgres");
		addDatabaseSpecificStatement("postgres", "insertComment", "insertComment_postgres");
		addDatabaseSpecificStatement("postgres", "selectComment", "selectComment_postgres");
		addDatabaseSpecificStatement("postgres", "selectCommentsByTaskId", "selectCommentsByTaskId_postgres");
		addDatabaseSpecificStatement("postgres", "selectCommentsByProcessInstanceId",
				"selectCommentsByProcessInstanceId_postgres");
		addDatabaseSpecificStatement("postgres", "selectCommentsByProcessInstanceIdAndType",
				"selectCommentsByProcessInstanceIdAndType_postgres");
		addDatabaseSpecificStatement("postgres", "selectCommentsByType", "selectCommentsByType_postgres");
		addDatabaseSpecificStatement("postgres", "selectCommentsByTaskIdAndType",
				"selectCommentsByTaskIdAndType_postgres");
		addDatabaseSpecificStatement("postgres", "selectEventsByTaskId", "selectEventsByTaskId_postgres");
		addDatabaseSpecificStatement("postgres", "insertEventLogEntry", "insertEventLogEntry_postgres");
		addDatabaseSpecificStatement("postgres", "selectAllEventLogEntries", "selectAllEventLogEntries_postgres");
		addDatabaseSpecificStatement("postgres", "selectEventLogEntries", "selectEventLogEntries_postgres");
		addDatabaseSpecificStatement("postgres", "selectEventLogEntriesByProcessInstanceId",
				"selectEventLogEntriesByProcessInstanceId_postgres");

		// oracle
		databaseSpecificLimitBeforeStatements.put("oracle", "select * from ( select a.*, ROWNUM rnum from (");
		databaseSpecificLimitAfterStatements.put("oracle",
				"  ) a where ROWNUM < #{lastRow}) where rnum  >= #{firstRow}");
		databaseSpecificLimitBetweenStatements.put("oracle", "");
		databaseOuterJoinLimitBetweenStatements.put("oracle", "");
		databaseSpecificOrderByStatements.put("oracle", defaultOrderBy);
		addDatabaseSpecificStatement("oracle", "selectExclusiveJobsToExecute",
				"selectExclusiveJobsToExecute_integerBoolean");
		addDatabaseSpecificStatement("oracle", "selectUnlockedTimersByDuedate", "selectUnlockedTimersByDuedate_oracle");
		addDatabaseSpecificStatement("oracle", "insertEventLogEntry", "insertEventLogEntry_oracle");

		// kingbase
		databaseSpecificLimitBeforeStatements.put("kingbase", "select * from ( select a.*, ROWNUM rnum from (");
		databaseSpecificLimitAfterStatements.put("kingbase",
				"  ) a where ROWNUM < #{lastRow}) where rnum  >= #{firstRow}");
		databaseSpecificLimitBetweenStatements.put("kingbase", "");
		databaseOuterJoinLimitBetweenStatements.put("kingbase", "");
		databaseSpecificOrderByStatements.put("kingbase", defaultOrderBy);
		addDatabaseSpecificStatement("kingbase", "selectExclusiveJobsToExecute",
				"selectExclusiveJobsToExecute_integerBoolean");
		addDatabaseSpecificStatement("kingbase", "selectUnlockedTimersByDuedate",
				"selectUnlockedTimersByDuedate_oracle");
		addDatabaseSpecificStatement("kingbase", "insertEventLogEntry", "insertEventLogEntry_oracle");

		// db2
		databaseSpecificLimitBeforeStatements.put("db2", "SELECT SUB.* FROM (");
		databaseSpecificLimitAfterStatements.put("db2",
				")RES ) SUB WHERE SUB.rnk >= #{firstRow} AND SUB.rnk < #{lastRow}");
		databaseSpecificLimitBetweenStatements.put("db2",
				", row_number() over (ORDER BY ${orderBy}) rnk FROM ( select distinct RES.* ");
		databaseOuterJoinLimitBetweenStatements.put("db2",
				", row_number() over (ORDER BY ${mssqlOrDB2OrderBy}) rnk FROM ( select distinct ");
		databaseSpecificOrderByStatements.put("db2", "");
		databaseSpecificLimitBeforeNativeQueryStatements.put("db2",
				"SELECT SUB.* FROM ( select RES.* , row_number() over (ORDER BY ${orderBy}) rnk FROM (");
		addDatabaseSpecificStatement("db2", "selectExclusiveJobsToExecute",
				"selectExclusiveJobsToExecute_integerBoolean");
		addDatabaseSpecificStatement("db2", "selectExecutionByNativeQuery",
				"selectExecutionByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectHistoricActivityInstanceByNativeQuery",
				"selectHistoricActivityInstanceByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectHistoricProcessInstanceByNativeQuery",
				"selectHistoricProcessInstanceByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectHistoricTaskInstanceByNativeQuery",
				"selectHistoricTaskInstanceByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectTaskByNativeQuery", "selectTaskByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectProcessDefinitionByNativeQuery",
				"selectProcessDefinitionByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectDeploymentByNativeQuery",
				"selectDeploymentByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectGroupByNativeQuery", "selectGroupByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectUserByNativeQuery", "selectUserByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectModelByNativeQuery", "selectModelByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectHistoricDetailByNativeQuery",
				"selectHistoricDetailByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectHistoricVariableInstanceByNativeQuery",
				"selectHistoricVariableInstanceByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectTaskWithVariablesByQueryCriteria",
				"selectTaskWithVariablesByQueryCriteria_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectProcessInstanceWithVariablesByQueryCriteria",
				"selectProcessInstanceWithVariablesByQueryCriteria_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectHistoricProcessInstancesWithVariablesByQueryCriteria",
				"selectHistoricProcessInstancesWithVariablesByQueryCriteria_mssql_or_db2");
		addDatabaseSpecificStatement("db2", "selectHistoricTaskInstancesWithVariablesByQueryCriteria",
				"selectHistoricTaskInstancesWithVariablesByQueryCriteria_mssql_or_db2");

		// mssql
		databaseSpecificLimitBeforeStatements.put("mssql", "SELECT SUB.* FROM (");
		databaseSpecificLimitAfterStatements.put("mssql",
				")RES ) SUB WHERE SUB.rnk >= #{firstRow} AND SUB.rnk < #{lastRow}");
		databaseSpecificLimitBetweenStatements.put("mssql",
				", row_number() over (ORDER BY ${orderBy}) rnk FROM ( select distinct RES.* ");
		databaseOuterJoinLimitBetweenStatements.put("mssql",
				", row_number() over (ORDER BY ${mssqlOrDB2OrderBy}) rnk FROM ( select distinct ");
		databaseSpecificOrderByStatements.put("mssql", "");
		databaseSpecificLimitBeforeNativeQueryStatements.put("mssql",
				"SELECT SUB.* FROM ( select RES.* , row_number() over (ORDER BY ${orderBy}) rnk FROM (");
		addDatabaseSpecificStatement("mssql", "selectExclusiveJobsToExecute",
				"selectExclusiveJobsToExecute_integerBoolean");
		addDatabaseSpecificStatement("mssql", "selectExecutionByNativeQuery",
				"selectExecutionByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectHistoricActivityInstanceByNativeQuery",
				"selectHistoricActivityInstanceByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectHistoricProcessInstanceByNativeQuery",
				"selectHistoricProcessInstanceByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectHistoricTaskInstanceByNativeQuery",
				"selectHistoricTaskInstanceByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectTaskByNativeQuery", "selectTaskByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectProcessDefinitionByNativeQuery",
				"selectProcessDefinitionByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectDeploymentByNativeQuery",
				"selectDeploymentByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectGroupByNativeQuery", "selectGroupByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectUserByNativeQuery", "selectUserByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectModelByNativeQuery", "selectModelByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectHistoricDetailByNativeQuery",
				"selectHistoricDetailByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectHistoricVariableInstanceByNativeQuery",
				"selectHistoricVariableInstanceByNativeQuery_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectTaskWithVariablesByQueryCriteria",
				"selectTaskWithVariablesByQueryCriteria_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectProcessInstanceWithVariablesByQueryCriteria",
				"selectProcessInstanceWithVariablesByQueryCriteria_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectHistoricProcessInstancesWithVariablesByQueryCriteria",
				"selectHistoricProcessInstancesWithVariablesByQueryCriteria_mssql_or_db2");
		addDatabaseSpecificStatement("mssql", "selectHistoricTaskInstancesWithVariablesByQueryCriteria",
				"selectHistoricTaskInstancesWithVariablesByQueryCriteria_mssql_or_db2");
	}

三、重新生成jar包。

(1)找到项目路径下存放class文件的位置。我这里是/target/classes/下。
(2)将之前修改的两个类class文件取出。
(3)我是使用maven引入的工作流jar包,所以去maven的本地仓库找到这个jar包。
activiti工作流使用其他数据库
路径可以在jar包后面查看。

(4)找到路径打开后是这样的
activiti工作流使用其他数据库
activiti-engine-5.16.4.jar(JVM所使用的包,其中都是class文件)
activiti-engine-5.16.4-sources.jar(里面是源码,其中都是java文件,也是Eclipse查看的)
其中activiti-engine-5.16.4.jar必须修改,不然没法用。

(5)将activiti-engine-5.16.4.jar复制一份后解压
根据前面两个类的路径找到原有class文件,将之前修改好取出的class文件用来替换。
这两个类
org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl
org.activiti.engine.impl.cfg.DbSqlSessionFactory

(6)在下面这个位置将两个文件夹压缩
activiti工作流使用其他数据库
(7)修改名字及后缀为activiti-engine-5.16.4.jar

(8)这个activiti-engine-5.16.4-sources.jar包与上面的修改方法一样,不过里面是java文件。可以使用之前Eclipse项目中java文件进行替换。

四、替换jar包。

(1)与maven仓库中的jar包进行替换。
(2)项目点击右键->Maven->Update Project。重新加载jar包。
(3)启动项目成功。或者修复好之前错误。