1. 程式人生 > >Activiti 實戰篇 小試牛刀

Activiti 實戰篇 小試牛刀

1:工作流的概念

這裡寫圖片描述 
這裡寫圖片描述

說明:

1) 假設:這兩張圖就是華誼兄弟的請假流程圖 
2) 圖的組成部分: 
A. 人物:范冰冰 馮小剛 王中軍 
B. 事件(動作):請假、批准、不批准

這裡寫圖片描述 
這裡寫圖片描述 
工作流(Workflow),就是“業務過程的部分或整體在計算機應用環境下的自動化”,它主要解決的是“使在多個參與者之間按照某種預定義的規則傳遞文件、資訊或任務的過程自動進行,從而實現某個預期的業務目標,或者促使此目標的實現”。 
工作流管理系統(Workflow Management System, WfMS)是一個軟體系統,它完成工作量的定義和管理,並按照在系統中預先定義好的工作流規則進行工作流例項的執行。工作流管理系統不是企業的業務系統,而是為企業的業務系統的執行提供了一個軟體的支撐環境。 
工作流管理聯盟(WfMC,Workflow Management Coalition)給出的關於工作流管理系統的定義是:工作流管理系統是一個軟體系統,它通過執行經過計算的流程定義去支援一批專門設定的業務流程。工作流管理系統被用來定義、管理、和執行工作流程。 
工作流管理系統的目標:管理工作的流程以確保工作在正確的時間被期望的人員所執行——在自動化進行的業務過程中插入人工的執行和干預。 
3:Activiti介紹 
Activiti5是由Alfresco軟體在2010年5月17日釋出的業務流程管理(BPM)框架,它是覆蓋了業務流程管理、工作流、服務協作等領域的一個開源的、靈活的、易擴充套件的可執行流程語言框架。Activiti基於Apache許可的開源BPM平臺,創始人Tom Baeyens是JBoss jBPM的專案架構師,它特色是提供了eclipse外掛,開發人員可以通過外掛直接繪畫出業務 
流程圖。 
這裡寫圖片描述

3.1:工作流引擎 
ProcessEngine物件,這是Activiti工作的核心。負責生成流程執行時的各種例項及資料、監控和管理流程的執行。 
3.2:BPMN 
業務流程建模與標註(Business Process Model and Notation,BPMN) ,描述流程的基本符號,包括這些圖元如何組合成一個業務流程圖(Business Process Diagram)

3.3:資料庫(先了解後看) 
Activiti資料庫支援: 
Activiti的後臺是有資料庫的支援,所有的表都以ACT_開頭。 第二部分是表示表的用途的兩個字母標識。 用途也和服務的API對應。 
ACT_RE_*: ‘RE’表示repository。 這個字首的表包含了流程定義和流程靜態資源 (圖片,規則,等等)。 
ACT_RU_*: ‘RU’表示runtime。 這些執行時的表,包含流程例項,任務,變數,非同步任務,等執行中的資料。 Activiti只在流程例項執行過程中儲存這些資料, 在流程結束時就會刪除這些記錄。 這樣執行時表可以一直很小速度很快。 
ACT_ID_*: ‘ID’表示identity。 這些表包含身份資訊,比如使用者,組等等。 
ACT_HI_*: ‘HI’表示history。 這些表包含歷史資料,比如歷史流程例項, 變數,任務等等。 
ACT_GE_*: 通用資料, 用於不同場景下,如存放資原始檔。

表結構操作: 
3.3.1:資源庫流程規則表 
1) act_re_deployment 部署資訊表 
2) act_re_model 流程設計模型部署表 
3) act_re_procdef 流程定義資料表 
3.3.2:執行時資料庫表 
1) act_ru_execution 執行時流程執行例項表 
2) act_ru_identitylink 執行時流程人員表,主要儲存任務節點與參與者的相關資訊 
3) act_ru_task 執行時任務節點表 
4) act_ru_variable 執行時流程變數資料表 
3.3.3:歷史資料庫表 
1) act_hi_actinst 歷史節點表 
2) act_hi_attachment 歷史附件表 
3) act_ih_comment 歷史意見表 
4) act_hi_identitylink 歷史流程人員表 
5) act_hi_detail 歷史詳情表,提供歷史變數的查詢 
6) act_hi_procinst 歷史流程例項表 
7) act_hi_taskinst 歷史任務例項表 
8) act_hi_varinst 歷史變量表 
3.3.4:組織機構表 
1) act_id_group 使用者組資訊表 
2) act_id_info 使用者擴充套件資訊表 
3) act_id_membership 使用者與使用者組對應資訊表 
4) act_id_user 使用者資訊表 
這四張表很常見,基本的組織機構管理,關於使用者認證方面建議還是自己開發一套,元件自帶的功能太簡單,使用中有很多需求難以滿足 
3.3.5:通用資料表 
1) act_ge_bytearray 二進位制資料表 
2) act_ge_property 屬性資料表儲存整個流程引擎級別的資料,初始化表結構時,會預設插入三條記錄, 
3.4:activiti.cfg.xml(activiti的配置檔案) 
Activiti核心配置檔案,配置流程引擎建立工具的基本引數和資料庫連線池引數。 
定義資料庫配置引數: 
 jdbcUrl: 資料庫的JDBC URL。 
 jdbcDriver: 對應不同資料庫型別的驅動。 
 jdbcUsername: 連線資料庫的使用者名稱。 
 jdbcPassword: 連線資料庫的密碼。 
基於JDBC引數配置的資料庫連線 會使用預設的MyBatis連線池。 下面的引數可以用來配置連線池(來自MyBatis引數): 
 jdbcMaxActiveConnections: 連線池中處於被使用狀態的連線的最大值。預設為10。 
 jdbcMaxIdleConnections: 連線池中處於空閒狀態的連線的最大值。 
 jdbcMaxCheckoutTime: 連線被取出使用的最長時間,超過時間會被強制回收。 預設為20000(20秒)。 
 jdbcMaxWaitTime: 這是一個底層配置,讓連線池可以在長時間無法獲得連線時, 列印一條日誌,並重新嘗試獲取一個連線。(避免因為錯誤配置導致沉默的操作失敗)。 預設為20000(20秒)。 
示例資料庫配置: 
這裡寫圖片描述

也可以使用javax.sql.DataSource。 (比如,Apache Commons的DBCP): 
這裡寫圖片描述 
3.5:logging.properties(日誌處理) 
日誌的配置檔案,Activiti操作資料庫的時候,整合的日誌檔案 
4:準備環境 
4.1:activiti5 軟體環境 
1) JDK1.6或者更高版本 
2) 支援的資料庫有:h2, mysql, oracle, postgres, mssql, db2等。 
3) 支援activiti5執行的jar包 
4) 開發環境為Eclipse3.7或者以上版本,myeclipse為8.6版本 
4.2:相關資源下載 
1) JDK可以到sun的官網下載 
http://www.oracle.com/technetwork/java/javase/downloads/index.html 
2) 資料庫,例如:mysql可以在官網上下載。 
http://www.mysql.com 
3) activiti也可以到Activiti官方網站下載得到。 
http://activiti.org/download.html 
4) Eclipse3.7或者MyEclipse8.6也可以到相應的網站上獲得下載。 
4.3:安裝流程設計器(eclipse外掛) 
4.3.1:安裝方式一 
在有網路的情況下,安裝流程設計器步驟如下: 
1) 開啟 Help -> Install New Software. 在如下面板中: 
這裡寫圖片描述
2) 在如下Install介面板中,點選Add按鈕: 
這裡寫圖片描述 
配置新裝外掛的地址和名稱

3) 然後填入下列欄位 
Name: Activiti BPMN 2.0 designer 
Location: http://activiti.org/designer/update/ 
這裡寫圖片描述 
4) 回到Install介面,在面板正中列表中把所有展示出來的專案都勾上: 
這裡寫圖片描述 
5) 點選複選框 
在Detail部分記得選中 “Contact all updates sites..” , 因為它會檢查所有當前安裝所需要的外掛並可以被Eclipse下載.

6) 安裝完以後,點選新建工程new->Other…打開面板,如果看到下圖內容: 
這裡寫圖片描述 
說明安裝成功了。 
4.3.2:安裝方式二 
在沒有網路的情況下,安裝流程設計器步驟如下: 
1) 解壓老師發給大家的 壓縮包 
2) 把壓縮包中的內容放入eclipse根目錄的dropins資料夾下 
3) 重啟eclipse,點選新建工程new->Other…打開面板,如果看到下圖內容: 
這裡寫圖片描述 
說明安裝成功了 
4.4:對流程設計器的使用說明 
開啟選單Windows->Preferences->Activiti->Save下流程流程圖片的生成方式: 
這裡寫圖片描述 
雖然流程引擎在單獨部署bpmn檔案時會自動生成圖片,但在實際開發過程中,自動生成的圖片會導致和BPMN中的座標有出入,在實際專案中展示流程當前位置圖會有問題。 
所在完成以上配置後,會由我們自己來管理流程圖片。在釋出流程時把流程規則檔案和流程圖片一起上傳就行了。 
4.5:準備Activiti5開發環境 
4.5.1:新增Activiti5的jar包 
在activiti-5.13->wars目錄下是一些示例專案,解壓activiti-rest專案,匯入activiti-rest目錄中WEB-INF\lib下所有包。新增到classpath中。 
由於我們使用的是Mysql資料庫,Mysql資料庫的連結驅動Activiti官方包中並沒有提供,需要我們自己匯入。手動匯入mysql-connector-java.jar,新增到classpath下。 
4.5.2:初始化資料庫 
這裡寫圖片描述
在Activiti中,在建立核心的流程引擎物件時會自動建表。如果程式正常執行,mysql會自動建庫,然後建立23張表。

4.5.3:新增並制定配置檔案 
在Actiiti5中定製流程必定會操作到資料庫,如果都像上面那樣寫一大段程式碼會非常麻煩,所以我們可以把資料庫連線配置寫入配置檔案。 
在Activiti5的官方示例中並沒有現成的配置檔案,所以先得找到activiti-rest\WEB-INF\classes下有:

4.5.3.1:activiti-context.xml : 
一個類似spring結構的配置檔案,清空內容後改名為activiti.cfg.xml,用來做流程引擎的相關配置。 
按照上面程式碼配置ProcessEngineConfiguration物件,主要定義資料庫的連線配置和建表策略,配置檔案程式碼如下: 
這裡寫圖片描述
Java程式碼如下: 
這裡寫圖片描述
createProcessEngineConfigurationFromResource的引數值為我們新增的配置檔案activiti.cfg.xml的名稱,執行java程式碼,流程引擎物件建立成功執行後資料庫會自動建表。

/**使用程式碼建立工作流需要的23張表*/
    @Test
    public void createTable(){
        ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
        //連線資料庫的配置
        processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver");
        processEngineConfiguration.setJdbcUrl("jdbc:mysql://localhost:3306/shareniu?useUnicode=true&characterEncoding=utf8");
        processEngineConfiguration.setJdbcUsername("root");
        processEngineConfiguration.setJdbcPassword("root");

        /**
            public static final String DB_SCHEMA_UPDATE_FALSE = "false";不能自動建立表,需要表存在
            public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";先刪除表再建立表
            public static final String DB_SCHEMA_UPDATE_TRUE = "true";如果表不存在,自動建立表
         */
        processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        //工作流的核心物件,ProcessEnginee物件
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
        System.out.println("processEngine:"+processEngine);
    }

    /**使用配置檔案建立工作流需要的23張表*/
    @Test
    public void createTable_2(){
//      ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//      //工作流的核心物件,ProcessEnginee物件
//      ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();

        ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")   //
                                    .buildProcessEngine();
        System.out.println("processEngine:"+processEngine);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

4.5.3.2:log4j.properties 日誌配置檔案 
把兩個檔案放入resource目錄下即可。

5:核心API 
5.1:ProcessEngine 
說明: 
1) 在Activiti中最核心的類,其他的類都是由他而來。 
2) 產生方式:

在前面看到了兩種建立ProcessEngine(流程引擎)的方式,而這裡要簡化很多,呼叫ProcessEngines的getDefaultProceeEngine方法時會自動載入classpath下名為activiti.cfg.xml檔案。 
3) 可以產生RepositoryService

4) 可以產生RuntimeService

5) 可以產生TaskService

各個Service的作用: 
RepositoryService 管理流程定義 
RuntimeService 執行管理,包括啟動、推進、刪除流程例項等操作 
TaskService 任務管理 
HistoryService 歷史管理(執行完的資料的管理) 
IdentityService 組織機構管理 
FormService 一個可選服務,任務表單管理 
ManagerService

5.2:RepositoryService 
是Activiti的倉庫服務類。所謂的倉庫指流程定義文件的兩個檔案:bpmn檔案和流程圖片。 
1) 產生方式

2) 可以產生DeploymentBuilder,用來定義流程部署的相關引數

3) 刪除流程定義

5.3:RuntimeService 
是activiti的流程執行服務類。可以從這個服務類中獲取很多關於流程執行相關的資訊。 
5.4:TaskService 
是activiti的任務服務類。可以從這個類中獲取任務的資訊。 
5.5:HistoryService 
是activiti的查詢歷史資訊的類。在一個流程執行完成後,這個物件為我們提供查詢歷史資訊。 
5.6:ProcessDefinition 
流程定義類。可以從這裡獲得資原始檔等。 
5.7:ProcessInstance 
代表流程定義的執行例項。如范冰冰請了一天的假,她就必須發出一個流程例項的申請。一個流程例項包括了所有的執行節點。我們可以利用這個物件來了解當前流程例項的進度等資訊。流程例項就表示一個流程從開始到結束的最大的流程分支,即一個流程中流程例項只有一個。 
5.8:Execution 
Activiti用這個物件去描述流程執行的每一個節點。在沒有併發的情況下,Execution就是同ProcessInstance。流程按照流程定義的規則執行一次的過程,就可以表示執行物件Execution。 
如圖為ProcessInstance的原始碼: 
這裡寫圖片描述
從原始碼中可以看出ProcessInstance就是Execution。但在現實意義上有所區別: 
這裡寫圖片描述 
在單線流程中,如上圖的貸款流程,ProcessInstance與Execution是一致的。 
這裡寫圖片描述 
這個例子有一個特點:wire money(匯錢)和archive(存檔)是併發執行的。 這個時候,匯流排路代表ProcessInstance,而分線路中每個活動代表Execution。 
總結: 
* 一個流程中,執行物件可以存在多個,但是流程例項只能有一個。 
* 當流程按照規則只執行一次的時候,那麼流程例項就是執行物件。

6:HelloWorld程式(模擬流程的執行) 
6.1:流程圖:

這裡寫圖片描述 
6.2:部署流程定義 
這裡寫圖片描述 
這裡使用RepositoryService部署流程定義 
addClasspathResource表示從類路徑下載入資原始檔,一次只能載入一個檔案 
6.3:啟動流程例項 
這裡寫圖片描述 
這裡使用RuntimeService啟動流程例項 
6.4:檢視我的個人任務 
這裡寫圖片描述 
這裡使用TaskService完成任務的查詢 
6.5:完成我的個人任務 
這裡寫圖片描述 
這裡使用TaskService完成任務的辦理

7:管理流程定義 
7.1:設計流程定義文件 
7.1.1:流程圖 
這裡寫圖片描述 
7.1.2:bpmn檔案 
BPMN 2.0根節點是definitions節點。 這個元素中,可以定義多個流程定義(不過我們建議每個檔案只包含一個流程定義, 可以簡化開發過程中的維護難度)。 一個空的流程定義看起來像下面這樣。注意,definitions元素 最少也要包含xmlns 和 targetNamespace的宣告。 targetNamespace可以是任意值,它用來對流程例項進行分類。 
這裡寫圖片描述 
說明:流程定義文件有兩部分組成: 
1) bpmn檔案 
流程規則檔案。在部署後,每次系統啟動時都會被解析,把內容封裝成流程定義放入專案快取中。Activiti框架結合這個xml檔案自動管理流程,流程的執行就是按照bpmn檔案定義的規則執行的,bpmn檔案是給計算機執行用的。 
2) 展示流程圖的圖片 
在系統裡需要展示流程的進展圖片,圖片是給使用者看的。

7.2:部署流程定義(classpath路徑載入檔案) 
這裡寫圖片描述 
說明: 
1) 先獲取流程引擎物件:在建立時會自動載入classpath下的activiti.cfg.xml

2) 首先獲得預設的流程引擎,通過流程引擎獲取了一個RepositoryService物件(倉庫物件) 
3) 由倉庫的服務物件產生一個部署物件配置物件,用來封裝部署操作的相關配置。 
4) 這是一個鏈式程式設計,在部署配置物件中設定顯示名,上傳流程定義規則檔案 
5) 向資料庫表中存放流程定義的規則資訊。 
6) 這一步在資料庫中將操作三張表: 
a) act_re_deployment(部署物件表) 
存放流程定義的顯示名和部署時間,每部署一次增加一條記錄。 
這裡寫圖片描述 
這裡寫圖片描述
Deployment deployment = processEngine.getRepositoryService()// 
.createDeployment().name(“入門程式”)// 
.addClasspathResource(“hello/helloworld.bpmn”)// 從classpath的資源中載入,一次只能載入一個檔案 
// .addClasspathResource(“diagrams/helloworld.png”)// 
// 從classpath的資源中載入,一次只能載入一個檔案 
.deploy(); 
b) act_re_procdef(流程定義表) 
存放流程定義的屬性資訊,部署每個新的流程定義都會在這張表中增加一條記錄。 
注意:當流程定義的key相同的情況下,使用的是版本升級 
這裡寫圖片描述 
這裡寫圖片描述
對應的封裝類:

public interface ProcessDefinition {

  String getId();
  String getCategory();
  String getName();
  String getKey();
  String getDescription();
  int getVersion();
  String getResourceName();
  String getDeploymentId();
  String getDiagramResourceName();
  boolean hasStartFormKey();
  boolean isSuspended();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

程式碼的操作: 
/* 查詢流程定義 /

    @Test
    public void findProcessDefinition() {
        List<ProcessDefinition> list = processEngine.getRepositoryService()// 與流程定義和部署物件相關的Service
                .createProcessDefinitionQuery()// 建立一個流程定義的查詢
                /** 指定查詢條件,where條件 */
                // .deploymentId(deploymentId)//使用部署物件ID查詢
                // .processDefinitionId(processDefinitionId)//使用流程定義ID查詢
                // .processDefinitionKey(processDefinitionKey)//使用流程定義的key查詢
                // .processDefinitionNameLike(processDefinitionNameLike)//使用流程定義的名稱模糊查詢

                /** 排序 */
                .orderByProcessDefinitionVersion().asc()// 按照版本的升序排列
                // .orderByProcessDefinitionName().desc()//按照流程定義的名稱降序排列

                /** 返回的結果集 */
                .list();// 返回一個集合列表,封裝流程定義
        // .singleResult();//返回惟一結果集
        // .count();//返回結果集數量
        // .listPage(firstResult, maxResults);//分頁查詢
        if (list != null && list.size() > 0) {
            for (ProcessDefinition pd : list) {
                System.out.println("流程定義ID:" + pd.getId());// 流程定義的key+版本+隨機生成數
                System.out.println("流程定義的名稱:" + pd.getName());// 對應helloworld.bpmn檔案中的name屬性值
                System.out.println("流程定義的key:" + pd.getKey());// 對應helloworld.bpmn檔案中的id屬性值
                System.out.println("流程定義的版本:" + pd.getVersion());// 當流程定義的key值相同的相同下,版本升級,預設1
                System.out.println("資源名稱bpmn檔案:" + pd.getResourceName());
                System.out.println("資源名稱png檔案:" + pd.getDiagramResourceName());
                System.out.println("部署物件ID:" + pd.getDeploymentId());
                System.out
                        .println("#########################################################");
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

程式的輸出: 
流程定義ID:helloworld:1:4 
流程定義的名稱:helloworldProcess 
流程定義的key:helloworld 
流程定義的版本:1 
資源名稱bpmn檔案:hello/helloworld.bpmn 
資源名稱png檔案:hello/helloworld.helloworld.png 
部署物件ID:1 
c) act_ge_bytearray(資原始檔表) 
儲存流程定義相關的部署資訊。即流程定義文件的存放地。每部署一次就會增加兩條記錄,一條是關於bpmn規則檔案的,一條是圖片的(如果部署時只指定了bpmn一個檔案,activiti會在部署時解析bpmn檔案內容自動生成流程圖)。兩個檔案不是很大,都是以二進位制形式儲存在資料庫中。 
這裡寫圖片描述
7.3:部署流程定義(zip格式檔案) 
這裡寫圖片描述 
這裡寫圖片描述 
將 
壓縮成zip格式的檔案,使用zip的輸入流用作部署流程定義

7.4:檢視流程定義 
查詢流程定義的資訊 
這裡寫圖片描述 
結果: 
這裡寫圖片描述 
再部署一次執行結果為: 
這裡寫圖片描述 
可以看到流程定義的key值相同的情況下,版本是從1開始逐次升級的 
流程定義的Id是【key:版本:生成ID】 
說明: 
1) 流程定義和部署物件相關的Service都是RepositoryService。 
2) 建立流程定義查詢物件,可以在ProcessDefinitionQuery上設定查詢的相關引數 
3) 呼叫ProcessDefinitionQuery物件的list方法,執行查詢,獲得符合條件的流程定義列表 
4) 由執行結果可以看出: 
Key和Name的值為:bpmn檔案process節點的id和name的屬性值 
這裡寫圖片描述 
5) key屬性被用來區別不同的流程定義。 
6) 帶有特定key的流程定義第一次部署時,version為1。之後每次部署都會在當前最高版本號上加1 
7) Id的值的生成規則為:{processDefinitionKey}:{processDefinitionVersion}:{generated-id}, 這裡的generated-id是一個自動生成的唯一的數字 
8) 重複部署一次,deploymentId的值以一定的形式變化 
規則act_ge_property表生成 
這裡寫圖片描述 
7.5:刪除流程定義 
刪除部署到activiti中的流程定義。 
這裡寫圖片描述 
說明: 
1) 因為刪除的是流程定義,而流程定義的部署是屬於倉庫服務的,所以應該先得到RepositoryService 
2) 如果該流程定義下沒有正在執行的流程,則可以用普通刪除。如果是有關聯的資訊,用級聯刪除。專案開發中使用級聯刪除的情況比較多,刪除操作一般只開放給超級管理員使用。 
7.6:獲取流程定義文件的資源(檢視流程圖附件) 
查詢出流程定義文件。主要查的是圖片,用於顯示流程用。 
這裡寫圖片描述 
說明: 
1) deploymentId為流程部署ID 
2) resourceName為act_ge_bytearray表中NAME_列的值 
3) 使用repositoryService的getDeploymentResourceNames方法可以獲取指定部署下得所有檔案的名稱 
4) 使用repositoryService的getResourceAsStream方法傳入部署ID和資源圖片名稱可以獲取部署下指定名稱檔案的輸入流 
5) 最後的有關IO流的操作,使用FileUtils工具的copyInputStreamToFile方法完成流程流程到檔案的拷貝,將資原始檔以流的形式輸出到指定資料夾下 
7.7:附加功能:查詢最新版本的流程定義 
這裡寫圖片描述 
Key value儲存 key 為key value為流程定義 
程式碼: 
/*附加功能:查詢最新版本的流程定義*/

@Test
    public void findLastVersionProcessDefinition(){
        List<ProcessDefinition> list = processEngine.getRepositoryService()//
                        .createProcessDefinitionQuery()//
                        .orderByProcessDefinitionVersion().asc()//使用流程定義的版本升序排列
                        .list();
        /**
         * Map<String,ProcessDefinition>
  map集合的key:流程定義的key
  map集合的value:流程定義的物件
  map集合的特點:當map集合key值相同的情況下,後一次的值將替換前一次的值
         */
        Map<String, ProcessDefinition> map = new LinkedHashMap<String, ProcessDefinition>();
        if(list!=null && list.size()>0){
            for(ProcessDefinition pd:list){
                map.put(pd.getKey(), pd);
            }
        }
        List<ProcessDefinition> pdList = new ArrayList<ProcessDefinition>(map.values());
        if(pdList!=null && pdList.size()>0){
            for(ProcessDefinition pd:pdList){
                System.out.println("流程定義ID:"+pd.getId());//流程定義的key+版本+隨機生成數
                System.out.println("流程定義的名稱:"+pd.getName());//對應helloworld.bpmn檔案中的name屬性值
                System.out.println("流程定義的key:"+pd.getKey());//對應helloworld.bpmn檔案中的id屬性值
                System.out.println("流程定義的版本:"+pd.getVersion());//當流程定義的key值相同的相同下,版本升級,預設1
                System.out.println("資源名稱bpmn檔案:"+pd.getResourceName());
                System.out.println("資源名稱png檔案:"+pd.getDiagramResourceName());
                System.out.println("部署物件ID:"+pd.getDeploymentId());
                System.out.println("#########################################################");
            }
        }   
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

7.8:附加功能:刪除流程定義(刪除key相同的所有不同版本的流程定義) 
這裡寫圖片描述

@Test
    public void deleteProcessDefinitionByKey() {
        // 流程定義的key
        String processDefinitionKey = "helloworld";
        // 先使用流程定義的key查詢流程定義,查詢出所有的版本
        List<ProcessDefinition> list = processEngine.getRepositoryService()//
                .createProcessDefinitionQuery()//
                .processDefinitionKey(processDefinitionKey).list();//
        // 遍歷,獲取每個流程定義的部署ID
        if (list != null && list.size() > 0) {
            for(ProcessDefinition pd:list){
                //獲取部署ID
                String deploymentId = pd.getDeploymentId();
                processEngine.getRepositoryService()//
                            .deleteDeployment(deploymentId, true); 
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

7.9:總結 
Deployment 部署物件 
1、一次部署的多個檔案的資訊。對於不需要的流程可以刪除和修改。 
2、對應的表: 
act_re_deployment:部署物件表 
act_re_procdef:流程定義表 
act_ge_bytearray:資原始檔表 
act_ge_property:主鍵生成策略表

ProcessDefinition 流程定義 
1、解析.bpmn後得到的流程定義規則的資訊,工作流系統就是按照流程定義的規則執行的。

8:流程例項、任務的執行 
8.1:流程圖 
這裡寫圖片描述 
8.2:部署流程定義 
這裡寫圖片描述 
8.3:啟動流程例項 
這裡寫圖片描述
說明: 
1) 操作資料庫的act_ru_execution表,如果是使用者任務節點,同時也會在act_ru_task新增一條記錄 
act_ru_execution表,#正在執行的執行物件表 任務結束的之前只有 一個 變化的欄位是act_id 
這裡寫圖片描述
這裡寫圖片描述

8.4:查詢我的個人任務 
這裡寫圖片描述

@Test
    public void findMyPersonalTask(){
        String assignee = "王五";
        List<Task> list = processEngine.getTaskService()//與正在執行的任務管理相關的Service
                        .createTaskQuery()//建立任務查詢物件
                        /**查詢條件(where部分)*/
                        .taskAssignee(assignee)//指定個人任務查詢,指定辦理人
//                      .taskCandidateUser(candidateUser)//組任務的辦理人查詢
//                      .processDefinitionId(processDefinitionId)//使用流程定義ID查詢
//                      .processInstanceId(processInstanceId)//使用流程例項ID查詢
//                      .executionId(executionId)//使用執行物件ID查詢
                        /**排序*/
                        .orderByTaskCreateTime().asc()//使用建立時間的升序排列
                        /**返回結果集*/
//                      .singleResult()//返回惟一結果集
//                      .count()//返回結果集的數量
//                      .listPage(firstResult, maxResults);//分頁查詢
                        .list();//返回列表
        if(list!=null && list.size()>0){
            for(Task task:list){
                System.out.println("任務ID:"+task.getId());
                System.out.println("任務名稱:"+task.getName());
                System.out.println("任務的建立時間:"+task.getCreateTime());
                System.out.println("任務的辦理人:"+task.getAssignee());
                System.out.println("流程例項ID:"+task.getProcessInstanceId());
                System.out.println("執行物件ID:"+task.getExecutionId());
                System.out.println("流程定義ID:"+task.getProcessDefinitionId());
                System.out.println("########################################################");
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

輸出: 
任務ID:504 
任務名稱:提交申請 
任務的建立時間:Sat Aug 09 08:50:20 CST 2014 
任務的辦理人:張三 
流程例項ID:501 
執行物件ID:501 
流程定義ID:helloworld:1:404 
介面:

public interface Task {
  int DEFAULT_PRIORITY = 50;
    String getId(); String getName();
    void setName(String name);
    String getDescription();
    void setDescription(String description);
    int getPriority();
    void setPriority(int priority);
  String getOwner();
  void setOwner(String owner);
    String getAssignee();
    void setAssignee(String assignee);  DelegationState getDelegationState();
  void setDelegationState(DelegationState delegationState);
    String getProcessInstanceId();
    String getExecutionId();
    String getProcessDefinitionId();
    Date getCreateTime();
    String getTaskDefinitionKey();
    Date getDueDate();
    void setDueDate(Date dueDate);
  void delegate(String userId);
  void setParentTaskId(String parentTaskId);
  String getParentTaskId();
  boolean isSuspended();
  Map<String, Object> getTaskLocalVariables();
  Map<String, Object> getProcessVariables();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

說明: 
1) 因為是任務查詢,所以從processEngine中應該得到TaskService 
2) 使用TaskService獲取到任務查詢物件TaskQuery 
3) 為查詢物件新增查詢過濾條件,使用taskAssignee指定任務的辦理者(即查詢指定使用者的代辦任務),同時可以新增分頁排序等過濾條件 
4) 呼叫list方法執行查詢,返回辦理者為指定使用者的任務列表 
5) 任務ID、名稱、辦理人、建立時間可以從act_ru_task表中查到。 
6) Execution與ProcessInstance見5.6和5.7章節的介紹。在這種情況下,ProcessInstance相當於Execution 
7) 如果assignee屬性為部門經理,結果為空。因為現在流程只到了”填寫請假申請”階段,後面的任務還沒有執行,即在資料庫中沒有部門經理可以辦理的任務,所以查詢不到。 
8) 一個Task節點和Execution節點是1對1的情況,在task物件中使用Execution_來表示他們之間的關係 
9) 任務ID在資料庫表act_ru_task中對應“ID_”列

附加: 
在activiti任務中,主要分為兩大類查詢任務(個人任務和組任務): 
1.確切指定了辦理者的任務,這個任務將成為指定者的私有任務,即個人任務。 
2.無法指定具體的某一個人來辦理的任務,可以把任務分配給幾個人或者一到 多個小組,讓這個範圍內的使用者可以選擇性(如有空餘時間時)來辦理這類任務,即組任務。 
先知道個人任務的查詢和辦理,組任務的操作後面講

8.5:辦理任務 
這裡寫圖片描述

說明: 
1) 是辦理任務,所以從ProcessEngine得到的是TaskService。 
2) 當執行完這段程式碼,再以員工的身份去執行查詢的時候,會發現這個時候已經沒有資料了,因為正在執行的任務中沒有資料。 
3) 對於執行完的任務,activiti將從act_ru_task表中刪除該任務,下一個任務會被插入進來。 
4) 以”部門經理”的身份進行查詢,可以查到結果。因為流程執行到部門經理審批這個節點了。 
5) 再執行辦理任務程式碼,執行完以後以”部門經理”身份進行查詢,沒有結果。 
6) 重複第3和4步直到