Activiti第二篇【管理流程定義、執行任務和流程實例、流程變量】

上篇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    # 流程定義表

PNG資源

在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

咱們還能夠加載的是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  # 歷史流程任務表

這裏就簡單簡述一下流程實例與流程對象的區別:

  • (1)若是是單例流程,執行對象ID就是流程實例ID
  • (2)若是一個流程有分支和聚合,那麼執行對象ID和流程實例ID就不相同
  • (3)一個流程中,流程實例只有1個,執行對象能夠存在多個。

開始流程

@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【運行時服務】

場景

  • 在流程開始的時候設置流程變量
  • 在完成某個任務的時候設置流程變量
  • 使用TaskService設置服務
  • 使用RuntimeService設置服務

做用:

  • 傳遞業務參數
  • 動指定代理人【咱們快速入門的例子是固定在流程定義圖上寫上代理人的】態
  • 指定鏈接【決定流程往哪邊走】

流程變量支持類型

若是咱們使用JavaBean來做爲流程的變量,那麼咱們須要將JavaBean實現Serializable接口

Javabean類型設置獲取流程變量,除了須要這個javabean實現了Serializable接口外,還要求流程變量對象的屬性不能發生變化,不然拋出異常。解決方案,固定序列化ID

這裏寫圖片描述

setVariable和setVariableLocal的區別

這裏寫圖片描述

例子

//模擬流程變量設置
    @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;
    }


}
相關文章
相關標籤/搜索