1. 删除流程实例:
1.1. 删除历史流程实例:
this.historyService.deleteHistoricProcessInstance( "我是流程实例id" );
1.2. 删除运行中的流程实例( 删除运行中的流程实例时候,该实例会变成历史流程实例,所以需要两步删除 ):
this.runtimeService.deleteProcessInstance( "我是流程实例id","强制删除流程实例 " + processInstanceId );
this.historyService.deleteHistoricProcessInstance( "我是流程实例id" );
2. 修改对象类型的流程变量里的属性:
起初开发了一版工作流审批系统,客户已经开始使用了,并且录入了几条真实的数据,后来系统改造了,肯定不能让用户自己重新录入这几条真实的数据,鉴于后台逻辑改动巨大,手动查询数据库修改数据和写程序转换数据都比较麻烦,所以一个最简单且不容易出错的办法就是,把生产环境数据库( product_database ) dump 到一个临时数据库 product_database_temp,然后本地电脑连接 product_database_temp 数据库跑新版本代码,自己充当客户在浏览器手动录入这几条真实数据,但是存在一个问题,就是上传的文件都存储到了本地的 "E://upload" 下,而且流程变量中的文件地址前缀 也是 "E://upload",解决方案就是到时候把本地的 "E://upload" 整个拷贝到 linux 服务器,文件夹名称 改为 "/usr/upload",然后将流程变量中的 文件地址中的 "E://upload" 前缀替换成 "/usr/upload" 前缀,由于复合对象变量在流程实例变量中存储成了二进制,所以下面代码需要使用 java 的对象存取:
import com.alibaba.fastjson.JSONObject;
import com.goldwind.common.CommonConstant;
import java.io.*;
import java.util.*;
import java.sql.*;
public class JdbcTest {
private static final String URL = "jdbc:mysql://127.0.0.1:3306/test?" +
"characterEncoding=UTF-8&" +
"useUnicode=true&" +
"user=zhangsan&" +
"password=123455&" +
"useSSL=false&" +
"tinyInt1isBit=false&" +
"allowPublicKeyRetrieval=true&" +
"serverTimezone=Asia/Shanghai&" +
"allowMultiQueries=true";
private Connection conn = null;
private PreparedStatement pstmt_read = null;
private PreparedStatement pstmt_update = null;
private ResultSet resultSet = null;
public static void main(String[] args) throws IOException {
// JdbcTest jdbcTest = new JdbcTest();
// jdbcTest.doReplace( "E://upload/","/usr/upload/" );
}
public void doReplace( String replaceTargetStr,String replaceWithStr ){
InputStream inputStream_businessData =null;
ByteArrayOutputStream outputStream_businessData=null;
try{
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(URL);
pstmt_read = conn.prepareStatement("SELECT * FROM act_ge_bytearray WHERE NAME_='businessData'");
resultSet = pstmt_read.executeQuery();
while( resultSet.next() ){
String id_ = resultSet.getString("ID_");
inputStream_businessData = resultSet.getBinaryStream("BYTES_");
outputStream_businessData = new ByteArrayOutputStream();
this.translateBusinessDataBytesData( inputStream_businessData,outputStream_businessData,replaceTargetStr,replaceWithStr );
pstmt_update = conn.prepareStatement("UPDATE act_ge_bytearray SET BYTES_=? WHERE ID_=?");
pstmt_update.setBinaryStream( 1,new ByteArrayInputStream( outputStream_businessData.toByteArray() ) );
pstmt_update.setString(2,id_ );
pstmt_update.executeUpdate();
System.out.println( "替换完毕 id_ = " + id_ );
}
}catch(Exception e){
e.printStackTrace();
} finally{
//关闭用到的资源
if( inputStream_businessData != null ){
try {
inputStream_businessData.close();
}catch ( Exception e1 ){
e1.printStackTrace();
}
}
if( outputStream_businessData != null ){
try {
outputStream_businessData.close();
}catch ( Exception e1 ){
e1.printStackTrace();
}
}
if( resultSet != null ){
try {
resultSet.close();
}catch ( Exception e1 ){
e1.printStackTrace();
}
}
if( pstmt_read != null ){
try {
pstmt_read.close();
}catch ( Exception e1 ){
e1.printStackTrace();
}
}
if( pstmt_update != null ){
try {
pstmt_update.close();
}catch ( Exception e1 ){
e1.printStackTrace();
}
}
if( conn != null ){
try {
conn.close();
}catch ( Exception e1 ){
e1.printStackTrace();
}
}
}
}
private void translateBusinessDataBytesData( InputStream businessDataInputStream,
OutputStream outputStream_businessData,
String replaceTargetStr,
String replaceWithStr ) {
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
ois = new ObjectInputStream( businessDataInputStream );
Map<String,Object> businessData = (Map<String, Object>) ois.readObject();
System.out.println( "替换之前:" );
System.out.println( JSONObject.toJSONString( businessData ) );
System.out.println();
// 替换 businessData.registInfo.usccFilePath
Map<String,Object> registInfo = (Map<String, Object>) businessData.get(CommonConstant.varname_registInfo);
if( registInfo != null ){
String usccFilePath = (String) registInfo.get(CommonConstant.varname_usccFilePath);
if( usccFilePath != null ){
usccFilePath = usccFilePath.replace( replaceTargetStr,replaceWithStr );
registInfo.put( CommonConstant.varname_usccFilePath,usccFilePath );
}
}
// 替换 businessData.attachmentFiles[ i ].path
List<Map<String,Object>> attachmentFiles = (List<Map<String, Object>>) businessData.get(CommonConstant.varname_attachmentFiles);
if( attachmentFiles != null && attachmentFiles.size() > 0 ){
for( Map<String,Object> attachmentFile:attachmentFiles ){
String path = (String) attachmentFile.get("path");
if( path == null ){
continue;
}
path = path.replace( replaceTargetStr,replaceWithStr );
attachmentFile.put( "path",path );
}
}
// 替换 businessData.identityInfos[ i ].valueInfo.attachmentFilePath
List<Map<String,Object>> identityInfos = (List<Map<String, Object>>) businessData.get(CommonConstant.varname_identityInfos);
if( identityInfos != null && identityInfos.size() > 0 ){
for( Map<String,Object> identityInfo:identityInfos ){
Map<String,Object> valueInfo = (Map<String, Object>) identityInfo.get("valueInfo");
if( valueInfo == null || valueInfo.size() == 0 ){
continue;
}
String attachmentFilePath = (String) valueInfo.get(CommonConstant.varname_attachmentFilePath);
if( attachmentFilePath == null ){
continue;
}
attachmentFilePath = attachmentFilePath.replace( replaceTargetStr,replaceWithStr );
valueInfo.put( CommonConstant.varname_attachmentFilePath,attachmentFilePath );
}
}
System.out.println( "替换之后:" );
System.out.println( JSONObject.toJSONString( businessData ) );
oos = new ObjectOutputStream( outputStream_businessData );
oos.writeObject( businessData );
}catch ( Exception e ){
e.printStackTrace();
}finally {
if( ois != null ){
try {
ois.close();
}catch ( Exception e1 ){
e1.printStackTrace();
}
}
if( oos != null ){
try {
oos.close();
}catch ( Exception e2 ){
e2.printStackTrace();
}
}
}
}
}
ps:
1. 因为表 act_ge_bytearray 的字段 BYTES_ 是 blob 类型,所以使用 mybatis 时,实体类应该用 byte[] 类型,不能用 String,使用 String 虽然不会报错,但是会存在编码问题,写入时就乱了,用流时不要保存到文件中,因为保存到文件中涉及到存取,同样存在编码问题,使用 ByteArrayInputSteam 和 ByteArrayOutputSteam 在内存中转换即可
2. 使用之前最好把 camunda 的表 act_ge_bytearray 备份一下,如果转换失败了,可以把表 act_ge_bytearray 删除了,重新导入,删除时会提示外键引用,无法删除,可以先关闭 mysql 的外键约束检查,然后删除,导入完毕之后,再开启外键约束检查,具体命令如下:
# 关闭 外键约束检查
SET FOREIGN_KEY_CHECKS = 0;
删除表 act_ge_bytearray
导入表 act_ge_bytearray
# 开启外键约束检查
SET FOREIGN_KEY_CHECKS = 1;