上篇Activiti只是一個快速入門案例,這篇就講定義、部署、查看任務等等的一些細節【涉及到的數據庫表、對象等等】…php
管理流程定義主要涉及到如下的4張表:java
-- 流程部署相關的表 SELECT * FROM act_ge_bytearray # 通用字節資源表 SELECT * FROM act_ge_property # 通用屬性表,能夠生成部署id SELECT * FROM act_re_deployment #部署表 SELECT * FROM act_re_procdef # 流程定義表
在Eclipse中Activiti插件會自動生成一個BPMN與之對應的PNG圖片,是須要經過加載PNG圖片的數據庫
@Test public void deploy() { //獲取倉庫服務 :管理流程定義 RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deploy = repositoryService.createDeployment()//建立一個部署的構建器 .addClasspathResource("LeaveActiviti.bpmn")//從類路徑中添加資源,一次只能添加一個資源 .name("請求單流程")//設置部署的名稱 .category("辦公類別")//設置部署的類別 .deploy(); System.out.println("部署的id"+deploy.getId()); System.out.println("部署的名稱"+deploy.getName()); }
而咱們的Intellij idea插件不會自動生成PNG圖片,可是咱們在加載BPMN文件的時候,好像會自動插入PNG圖片,數據庫是有對應的記錄的【咱們是沒有手動加載PNG圖片資源的】markdown
咱們查看一下app
//查看bpmn 資源圖片 @Test public void viewImage() throws Exception{ String deploymentId="201"; String imageName=null; //取得某個部署的資源的名稱 deploymentId List<String> resourceNames = processEngine.getRepositoryService().getDeploymentResourceNames(deploymentId); // buybill.bpmn buybill.png if(resourceNames!=null&&resourceNames.size()>0){ for(String temp :resourceNames){ if(temp.indexOf(".png")>0){ imageName=temp; } } } /** * 讀取資源 * deploymentId:部署的id * resourceName:資源的文件名 */ InputStream resourceAsStream = processEngine.getRepositoryService() .getResourceAsStream(deploymentId, imageName); //把文件輸入流寫入到文件中 File file=new File("d:/"+imageName); FileUtils.copyInputStreamToFile(resourceAsStream, file); }
惋惜的是,查看出來的圖片的中文數據會亂碼…ide
咱們當時候查詢流程定義是經過咱們設置流程圖的id來查看的….其實咱們能夠經過其餘的屬性來查詢…而且能夠查詢出更加詳細的數據this
//查看流程定義 @Test public void queryProcessDefination(){ String processDefiKey="buyBill";//流程定義key //獲取流程定義列表 List<ProcessDefinition> list = processEngine.getRepositoryService().createProcessDefinitionQuery() //查詢 ,比如where // .processDefinitionId(proDefiId) //流程定義id // 流程定義id : buyBill:2:704 組成 : proDefikey(流程定義key)+version(版本)+自動生成id .processDefinitionKey(processDefiKey)//流程定義key 由bpmn 的 process 的 id屬性決定 // .processDefinitionName(name)//流程定義名稱 由bpmn 的 process 的 name屬性決定 // .processDefinitionVersion(version)//流程定義的版本 .latestVersion()//最新版本 //排序 .orderByProcessDefinitionVersion().desc()//按版本的降序排序 //結果 // .count()//統計結果 // .listPage(arg0, arg1)//分頁查詢 .list(); //遍歷結果 if(list!=null&&list.size()>0){ for(ProcessDefinition temp:list){ System.out.print("流程定義的id: "+temp.getId()); System.out.print("流程定義的key: "+temp.getKey()); System.out.print("流程定義的版本: "+temp.getVersion()); System.out.print("流程定義部署的id: "+temp.getDeploymentId()); System.out.println("流程定義的名稱: "+temp.getName()); } } }
咱們還能夠加載的是ZIP類型的資源數據idea
//部署流程定義,資源來自zip格式 @Test public void deployProcessDefiByZip(){ InputStream in=getClass().getClassLoader().getResourceAsStream("BuyBill.zip"); Deployment deploy = processEngine.getRepositoryService() .createDeployment() .name("採購流程") .addZipInputStream(new ZipInputStream(in)) .deploy(); System.out.println("部署名稱:"+deploy.getName()); System.out.println("部署id:"+deploy.getId()); }
//刪除流程定義 @Test public void deleteProcessDefi(){ //經過部署id來刪除流程定義 String deploymentId="101"; processEngine.getRepositoryService().deleteDeployment(deploymentId); }
再次查詢的時候,已經沒有101這個流程定義的數據了。spa
流程實例與任務執行的經常使用表有如下幾個:插件
-- 流程實例與任務 SELECT * FROM act_ru_execution # 流程執行對象信息 SELECT * FROM act_ru_task # 正在運行的任務表 SELECT * FROM act_hi_procinst # 歷史流程實例表 SELECT * FROM act_hi_taskinst # 歷史流程任務表
這裏就簡單簡述一下流程實例與流程對象的區別:
@Test public void startProcess(){ String processDefiKey="leaveActiviti";//bpmn 的 process id屬性 ProcessInstance pi = processEngine.getRuntimeService() .startProcessInstanceByKey(processDefiKey); System.out.println("流程執行對象的id:"+pi.getId());//Execution 對象 System.out.println("流程實例的id:"+pi.getProcessInstanceId());//ProcessInstance 對象 System.out.println("流程定義的id:"+pi.getProcessDefinitionId());//默認執行的是最新版本的流程定義 }
//查詢正在運行任務 @Test public void queryTask(){ //取得任務服務 TaskService taskService = processEngine.getTaskService(); //建立一個任務查詢對象 TaskQuery taskQuery = taskService.createTaskQuery(); //辦理人的任務列表 List<Task> list = taskQuery.list(); //遍歷任務列表 if(list!=null&&list.size()>0){ for(Task task:list){ System.out.println("任務的辦理人:"+task.getAssignee()); System.out.println("任務的id:"+task.getId()); System.out.println("任務的名稱:"+task.getName()); } } }
查詢SELECT * FROM act_ru_task 表
有的時候,咱們須要判斷它是在該流程,仍是該流程已經結束了。咱們能夠根據獲取出來的對象是否爲空來進行判斷
//獲取流程實例的狀態 @Test public void getProcessInstanceState(){ String processInstanceId="605"; ProcessInstance pi = processEngine.getRuntimeService() .createProcessInstanceQuery() .processInstanceId(processInstanceId) .singleResult();//返回的數據要麼是單行,要麼是空 ,其餘狀況報錯 //判斷流程實例的狀態 if(pi!=null){ System.out.println("該流程實例"+processInstanceId+"正在運行... "+"當前活動的任務:"+pi.getActivityId()); }else{ System.out.println("當前的流程實例"+processInstanceId+" 已經結束!"); } }
//查看歷史執行流程實例信息 @Test public void queryHistoryProcInst(){ List<HistoricProcessInstance> list = processEngine.getHistoryService() .createHistoricProcessInstanceQuery() .list(); if(list!=null&&list.size()>0){ for(HistoricProcessInstance temp:list){ System.out.println("歷史流程實例id:"+temp.getId()); System.out.println("歷史流程定義的id:"+temp.getProcessDefinitionId()); System.out.println("歷史流程實例開始時間--結束時間:"+temp.getStartTime()+"-->"+temp.getEndTime()); } } }
查詢表:
@Test public void queryHistoryTask(){ String processInstanceId="605"; List<HistoricTaskInstance> list = processEngine.getHistoryService() .createHistoricTaskInstanceQuery() .processInstanceId(processInstanceId) .list(); if(list!=null&&list.size()>0){ for(HistoricTaskInstance temp:list){ System.out.print("歷史流程實例任務id:"+temp.getId()); System.out.print("歷史流程定義的id:"+temp.getProcessDefinitionId()); System.out.print("歷史流程實例任務名稱:"+temp.getName()); System.out.println("歷史流程實例任務處理人:"+temp.getAssignee()); } } }
給予對應的實例id就能夠查詢出執行到哪一個任務了…
根據任務的id,就能夠把該任務執行了。
@Test public void compileTask(){ String taskId="608"; //taskId:任務id processEngine.getTaskService().complete(taskId); System.out.println("當前任務執行完畢"); }
流程變量涉及到的數據庫表:
act_ru_variable:正在執行的流程變量表 act_hi_varinst:流程變量歷史表
流程變量在工做流中扮演着一個很是重要的角色。例如:請假流程中有請假天數、請假緣由等一些參數都爲流程變量的範圍。流程變量的做用域範圍是只對應一個流程實例。也就是說各個流程實例的流程變量是不相互影響的。流程實例結束完成之後流程變量還保存在數據庫中(存放到流程變量的歷史表中)。
咱們有兩種服務能夠設置流程變量,TaskService【任務服務】和RuntimeService【運行時服務】
場景
做用:
若是咱們使用JavaBean來做爲流程的變量,那麼咱們須要將JavaBean實現Serializable接口。
Javabean類型設置獲取流程變量,除了須要這個javabean實現了Serializable接口外,還要求流程變量對象的屬性不能發生變化,不然拋出異常。解決方案,固定序列化ID
//模擬流程變量設置 @Test public void getAndSetProcessVariable(){ //有兩種服務能夠設置流程變量 // TaskService taskService = processEngine.getTaskService(); // RuntimeService runtimeService = processEngine.getRuntimeService(); /**1.經過 runtimeService 來設置流程變量 * executionId: 執行對象 * variableName:變量名 * values:變量值 */ // runtimeService.setVariable(executionId, variableName, values); // runtimeService.setVariableLocal(executionId, variableName, values); //設置本執行對象的變量 ,該變量的做用域只在當前的execution對象 // runtimeService.setVariables(executionId, variables); //能夠設置多個變量 放在 Map<key,value> Map<String,Object> /**2. 經過TaskService來設置流程變量 * taskId:任務id */ // taskService.setVariable(taskId, variableName, values); // taskService.setVariableLocal(taskId, variableName, values); //// 設置本執行對象的變量 ,該變量的做用域只在當前的execution對象 // taskService.setVariables(taskId, variables); //設置的是Map<key,values> /**3. 當流程開始執行的時候,設置變量參數 * processDefiKey: 流程定義的key * variables: 設置多個變量 Map<key,values> */ // processEngine.getRuntimeService() // .startProcessInstanceByKey(processDefiKey, variables) /**4. 當執行任務時候,能夠設置流程變量 * taskId:任務id * variables: 設置多個變量 Map<key,values> */ // processEngine.getTaskService().complete(taskId, variables); /** 5. 經過RuntimeService取變量值 * exxcutionId: 執行對象 * */ // runtimeService.getVariable(executionId, variableName);//取變量 // runtimeService.getVariableLocal(executionId, variableName);//取本執行對象的某個變量 // runtimeService.getVariables(variablesName);//取當前執行對象的全部變量 /** 6. 經過TaskService取變量值 * TaskId: 執行對象 * */ // taskService.getVariable(taskId, variableName);//取變量 // taskService.getVariableLocal(taskId, variableName);//取本執行對象的某個變量 // taskService.getVariables(taskId);//取當前執行對象的全部變量 }
//設置流程變量值 @Test public void setVariable(){ String taskId="1804";//任務id //採用TaskService來設置流程變量 //1. 第一次設置流程變量 // TaskService taskService = processEngine.getTaskService(); // taskService.setVariable(taskId, "cost", 1000);//設置單一的變量,做用域在整個流程實例 // taskService.setVariable(taskId, "申請時間", new Date()); // taskService.setVariableLocal(taskId, "申請人", "何某某");//該變量只有在本任務中是有效的 //2. 在不一樣的任務中設置變量 // TaskService taskService = processEngine.getTaskService(); // taskService.setVariable(taskId, "cost", 5000);//設置單一的變量,做用域在整個流程實例 // taskService.setVariable(taskId, "申請時間", new Date()); // taskService.setVariableLocal(taskId, "申請人", "李某某");//該變量只有在本任務中是有效的 /** * 3. 變量支持的類型 * - 簡單的類型 :String 、boolean、Integer、double、date * - 自定義對象bean */ TaskService taskService = processEngine.getTaskService(); //傳遞的一個自定義bean對象 AppayBillBean appayBillBean=new AppayBillBean(); appayBillBean.setId(1); appayBillBean.setCost(300); appayBillBean.setDate(new Date()); appayBillBean.setAppayPerson("何某某"); taskService.setVariable(taskId, "appayBillBean", appayBillBean); System.out.println("設置成功!"); }
//查詢流程變量 @Test public void getVariable(){ String taskId="1804";//任務id // TaskService taskService = processEngine.getTaskService(); // Integer cost=(Integer) taskService.getVariable(taskId, "cost");//取變量 // Date date=(Date) taskService.getVariable(taskId, "申請時間");//取本任務中的變量 //// Date date=(Date) taskService.getVariableLocal(taskId, "申請時間");//取本任務中的變量 // String appayPerson=(String) taskService.getVariableLocal(taskId, "申請人");//取本任務中的變量 //// String appayPerson=(String) taskService.getVariable(taskId, "申請人");//取本任務中的變量 // // System.out.println("金額:"+cost); // System.out.println("申請時間:"+date); // System.out.println("申請人:"+appayPerson); //讀取實現序列化的對象變量數據 TaskService taskService = processEngine.getTaskService(); AppayBillBean appayBillBean=(AppayBillBean) taskService.getVariable(taskId, "appayBillBean"); System.out.println(appayBillBean.getCost()); System.out.println(appayBillBean.getAppayPerson()); }
public class AppayBillBean implements Serializable{ private Integer id; private Integer cost;//金額 private String appayPerson;//申請人 private Date date;//申請日期 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getCost() { return cost; } public void setCost(Integer cost) { this.cost = cost; } public String getAppayPerson() { return appayPerson; } public void setAppayPerson(String appayPerson) { this.appayPerson = appayPerson; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } }