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步直到