Activiti最新全入门教程(以请假为例讲解)
1:工作流的概念
?
1) 假設(shè):這兩張圖就是華誼兄弟的請(qǐng)假流程圖?
2) 圖的組成部分:?
A. 人物:范冰冰 馮小剛 王中軍?
B. 事件(動(dòng)作):請(qǐng)假、批準(zhǔn)、不批準(zhǔn)
?
?
工作流(Workflow),就是“業(yè)務(wù)過程的部分或整體在計(jì)算機(jī)應(yīng)用環(huán)境下的自動(dòng)化”,它主要解決的是“使在多個(gè)參與者之間按照某種預(yù)定義的規(guī)則傳遞文檔、信息或任務(wù)的過程自動(dòng)進(jìn)行,從而實(shí)現(xiàn)某個(gè)預(yù)期的業(yè)務(wù)目標(biāo),或者促使此目標(biāo)的實(shí)現(xiàn)”。?
工作流管理系統(tǒng)(Workflow Management System, WfMS)是一個(gè)軟件系統(tǒng),它完成工作量的定義和管理,并按照在系統(tǒng)中預(yù)先定義好的工作流規(guī)則進(jìn)行工作流實(shí)例的執(zhí)行。工作流管理系統(tǒng)不是企業(yè)的業(yè)務(wù)系統(tǒng),而是為企業(yè)的業(yè)務(wù)系統(tǒng)的運(yùn)行提供了一個(gè)軟件的支撐環(huán)境。?
工作流管理聯(lián)盟(WfMC,Workflow Management Coalition)給出的關(guān)于工作流管理系統(tǒng)的定義是:工作流管理系統(tǒng)是一個(gè)軟件系統(tǒng),它通過執(zhí)行經(jīng)過計(jì)算的流程定義去支持一批專門設(shè)定的業(yè)務(wù)流程。工作流管理系統(tǒng)被用來定義、管理、和執(zhí)行工作流程。?
工作流管理系統(tǒng)的目標(biāo):管理工作的流程以確保工作在正確的時(shí)間被期望的人員所執(zhí)行——在自動(dòng)化進(jìn)行的業(yè)務(wù)過程中插入人工的執(zhí)行和干預(yù)。?
3:Activiti介紹?
Activiti5是由Alfresco軟件在2010年5月17日發(fā)布的業(yè)務(wù)流程管理(BPM)框架,它是覆蓋了業(yè)務(wù)流程管理、工作流、服務(wù)協(xié)作等領(lǐng)域的一個(gè)開源的、靈活的、易擴(kuò)展的可執(zhí)行流程語言框架。Activiti基于Apache許可的開源BPM平臺(tái),創(chuàng)始人Tom Baeyens是JBoss jBPM的項(xiàng)目架構(gòu)師,它特色是提供了eclipse插件,開發(fā)人員可以通過插件直接繪畫出業(yè)務(wù)?
流程圖。?
3.1:工作流引擎?
ProcessEngine對(duì)象,這是Activiti工作的核心。負(fù)責(zé)生成流程運(yùn)行時(shí)的各種實(shí)例及數(shù)據(jù)、監(jiān)控和管理流程的運(yùn)行。?
3.2:BPMN?
業(yè)務(wù)流程建模與標(biāo)注(Business Process Model and Notation,BPMN) ,描述流程的基本符號(hào),包括這些圖元如何組合成一個(gè)業(yè)務(wù)流程圖(Business Process Diagram)
3.3:數(shù)據(jù)庫(先了解后看)?
Activiti數(shù)據(jù)庫支持:?
Activiti的后臺(tái)是有數(shù)據(jù)庫的支持,所有的表都以ACT_開頭。 第二部分是表示表的用途的兩個(gè)字母標(biāo)識(shí)。 用途也和服務(wù)的API對(duì)應(yīng)。?
ACT_RE_*: ‘RE’表示repository。 這個(gè)前綴的表包含了流程定義和流程靜態(tài)資源 (圖片,規(guī)則,等等)。?
ACT_RU_*: ‘RU’表示runtime。 這些運(yùn)行時(shí)的表,包含流程實(shí)例,任務(wù),變量,異步任務(wù),等運(yùn)行中的數(shù)據(jù)。 Activiti只在流程實(shí)例執(zhí)行過程中保存這些數(shù)據(jù), 在流程結(jié)束時(shí)就會(huì)刪除這些記錄。 這樣運(yùn)行時(shí)表可以一直很小速度很快。?
ACT_ID_*: ‘ID’表示identity。 這些表包含身份信息,比如用戶,組等等。?
ACT_HI_*: ‘HI’表示history。 這些表包含歷史數(shù)據(jù),比如歷史流程實(shí)例, 變量,任務(wù)等等。?
ACT_GE_*: 通用數(shù)據(jù), 用于不同場景下,如存放資源文件。
表結(jié)構(gòu)操作:?
3.3.1:資源庫流程規(guī)則表?
1) act_re_deployment 部署信息表?
2) act_re_model 流程設(shè)計(jì)模型部署表?
3) act_re_procdef 流程定義數(shù)據(jù)表?
3.3.2:運(yùn)行時(shí)數(shù)據(jù)庫表?
1) act_ru_execution 運(yùn)行時(shí)流程執(zhí)行實(shí)例表?
2) act_ru_identitylink 運(yùn)行時(shí)流程人員表,主要存儲(chǔ)任務(wù)節(jié)點(diǎn)與參與者的相關(guān)信息?
3) act_ru_task 運(yùn)行時(shí)任務(wù)節(jié)點(diǎn)表?
4) act_ru_variable 運(yùn)行時(shí)流程變量數(shù)據(jù)表?
3.3.3:歷史數(shù)據(jù)庫表?
1) act_hi_actinst 歷史節(jié)點(diǎn)表?
2) act_hi_attachment 歷史附件表?
3) act_ih_comment 歷史意見表?
4) act_hi_identitylink 歷史流程人員表?
5) act_hi_detail 歷史詳情表,提供歷史變量的查詢?
6) act_hi_procinst 歷史流程實(shí)例表?
7) act_hi_taskinst 歷史任務(wù)實(shí)例表?
8) act_hi_varinst 歷史變量表?
3.3.4:組織機(jī)構(gòu)表?
1) act_id_group 用戶組信息表?
2) act_id_info 用戶擴(kuò)展信息表?
3) act_id_membership 用戶與用戶組對(duì)應(yīng)信息表?
4) act_id_user 用戶信息表?
這四張表很常見,基本的組織機(jī)構(gòu)管理,關(guān)于用戶認(rèn)證方面建議還是自己開發(fā)一套,組件自帶的功能太簡單,使用中有很多需求難以滿足?
3.3.5:通用數(shù)據(jù)表?
1) act_ge_bytearray 二進(jìn)制數(shù)據(jù)表?
2) act_ge_property 屬性數(shù)據(jù)表存儲(chǔ)整個(gè)流程引擎級(jí)別的數(shù)據(jù),初始化表結(jié)構(gòu)時(shí),會(huì)默認(rèn)插入三條記錄,?
3.4:activiti.cfg.xml(activiti的配置文件)?
Activiti核心配置文件,配置流程引擎創(chuàng)建工具的基本參數(shù)和數(shù)據(jù)庫連接池參數(shù)。?
定義數(shù)據(jù)庫配置參數(shù):?
? jdbcUrl: 數(shù)據(jù)庫的JDBC URL。?
? jdbcDriver: 對(duì)應(yīng)不同數(shù)據(jù)庫類型的驅(qū)動(dòng)。?
? jdbcUsername: 連接數(shù)據(jù)庫的用戶名。?
? jdbcPassword: 連接數(shù)據(jù)庫的密碼。?
基于JDBC參數(shù)配置的數(shù)據(jù)庫連接 會(huì)使用默認(rèn)的MyBatis連接池。 下面的參數(shù)可以用來配置連接池(來自MyBatis參數(shù)):?
? jdbcMaxActiveConnections: 連接池中處于被使用狀態(tài)的連接的最大值。默認(rèn)為10。?
? jdbcMaxIdleConnections: 連接池中處于空閑狀態(tài)的連接的最大值。?
? jdbcMaxCheckoutTime: 連接被取出使用的最長時(shí)間,超過時(shí)間會(huì)被強(qiáng)制回收。 默認(rèn)為20000(20秒)。?
? jdbcMaxWaitTime: 這是一個(gè)底層配置,讓連接池可以在長時(shí)間無法獲得連接時(shí), 打印一條日志,并重新嘗試獲取一個(gè)連接。(避免因?yàn)殄e(cuò)誤配置導(dǎo)致沉默的操作失敗)。 默認(rèn)為20000(20秒)。?
示例數(shù)據(jù)庫配置:?
也可以使用javax.sql.DataSource。 (比如,Apache Commons的DBCP):?
?
3.5:logging.properties(日志處理)?
日志的配置文件,Activiti操作數(shù)據(jù)庫的時(shí)候,整合的日志文件?
4:準(zhǔn)備環(huán)境?
4.1:activiti5 軟件環(huán)境?
1) JDK1.6或者更高版本?
2) 支持的數(shù)據(jù)庫有:h2, mysql, oracle, postgres, mssql, db2等。?
3) 支持activiti5運(yùn)行的jar包?
4) 開發(fā)環(huán)境為Eclipse3.7或者以上版本,myeclipse為8.6版本?
4.2:相關(guān)資源下載?
1) JDK可以到sun的官網(wǎng)下載?
http://www.oracle.com/technetwork/java/javase/downloads/index.html?
2) 數(shù)據(jù)庫,例如:mysql可以在官網(wǎng)上下載。?
http://www.mysql.com?
3) activiti也可以到Activiti官方網(wǎng)站下載得到。?
http://activiti.org/download.html?
4) Eclipse3.7或者M(jìn)yEclipse8.6也可以到相應(yīng)的網(wǎng)站上獲得下載。?
4.3:安裝流程設(shè)計(jì)器(eclipse插件)?
4.3.1:安裝方式一?
在有網(wǎng)絡(luò)的情況下,安裝流程設(shè)計(jì)器步驟如下:?
1) 打開 Help -> Install New Software. 在如下面板中:?
2) 在如下Install界面板中,點(diǎn)擊Add按鈕:?
?
配置新裝插件的地址和名稱
3) 然后填入下列字段?
Name: Activiti BPMN 2.0 designer?
Location:?http://activiti.org/designer/update/?
?
4) 回到Install界面,在面板正中列表中把所有展示出來的項(xiàng)目都勾上:?
?
5) 點(diǎn)擊復(fù)選框?
在Detail部分記得選中 “Contact all updates sites..” , 因?yàn)樗鼤?huì)檢查所有當(dāng)前安裝所需要的插件并可以被Eclipse下載.
6) 安裝完以后,點(diǎn)擊新建工程new->Other…打開面板,如果看到下圖內(nèi)容:?
?
說明安裝成功了。?
4.3.2:安裝方式二?
在沒有網(wǎng)絡(luò)的情況下,安裝流程設(shè)計(jì)器步驟如下:?
1) 解壓老師發(fā)給大家的 壓縮包?
2) 把壓縮包中的內(nèi)容放入eclipse根目錄的dropins文件夾下?
3) 重啟eclipse,點(diǎn)擊新建工程new->Other…打開面板,如果看到下圖內(nèi)容:?
?
說明安裝成功了?
4.4:對(duì)流程設(shè)計(jì)器的使用說明?
打開菜單Windows->Preferences->Activiti->Save下流程流程圖片的生成方式:?
?
雖然流程引擎在單獨(dú)部署bpmn文件時(shí)會(huì)自動(dòng)生成圖片,但在實(shí)際開發(fā)過程中,自動(dòng)生成的圖片會(huì)導(dǎo)致和BPMN中的坐標(biāo)有出入,在實(shí)際項(xiàng)目中展示流程當(dāng)前位置圖會(huì)有問題。?
所在完成以上配置后,會(huì)由我們自己來管理流程圖片。在發(fā)布流程時(shí)把流程規(guī)則文件和流程圖片一起上傳就行了。?
4.5:準(zhǔn)備Activiti5開發(fā)環(huán)境?
4.5.1:添加Activiti5的jar包?
在activiti-5.13->wars目錄下是一些示例項(xiàng)目,解壓activiti-rest項(xiàng)目,導(dǎo)入activiti-rest目錄中WEB-INF\lib下所有包。添加到classpath中。?
由于我們使用的是Mysql數(shù)據(jù)庫,Mysql數(shù)據(jù)庫的鏈接驅(qū)動(dòng)Activiti官方包中并沒有提供,需要我們自己導(dǎo)入。手動(dòng)導(dǎo)入mysql-connector-java.jar,添加到classpath下。?
4.5.2:初始化數(shù)據(jù)庫?
在Activiti中,在創(chuàng)建核心的流程引擎對(duì)象時(shí)會(huì)自動(dòng)建表。如果程序正常執(zhí)行,mysql會(huì)自動(dòng)建庫,然后創(chuàng)建23張表。
4.5.3:添加并制定配置文件?
在Actiiti5中定制流程必定會(huì)操作到數(shù)據(jù)庫,如果都像上面那樣寫一大段代碼會(huì)非常麻煩,所以我們可以把數(shù)據(jù)庫連接配置寫入配置文件。?
在Activiti5的官方示例中并沒有現(xiàn)成的配置文件,所以先得找到activiti-rest\WEB-INF\classes下有:
4.5.3.1:activiti-context.xml :?
一個(gè)類似spring結(jié)構(gòu)的配置文件,清空內(nèi)容后改名為activiti.cfg.xml,用來做流程引擎的相關(guān)配置。?
按照上面代碼配置ProcessEngineConfiguration對(duì)象,主要定義數(shù)據(jù)庫的連接配置和建表策略,配置文件代碼如下:?
Java代碼如下:?
createProcessEngineConfigurationFromResource的參數(shù)值為我們添加的配置文件activiti.cfg.xml的名稱,執(zhí)行java代碼,流程引擎對(duì)象創(chuàng)建成功運(yùn)行后數(shù)據(jù)庫會(huì)自動(dòng)建表。
/**使用代碼創(chuàng)建工作流需要的23張表*/
@Test
public void createTable(){
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
//連接數(shù)據(jù)庫的配置
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";不能自動(dòng)創(chuàng)建表,需要表存在
public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";先刪除表再創(chuàng)建表
public static final String DB_SCHEMA_UPDATE_TRUE = "true";如果表不存在,自動(dòng)創(chuàng)建表
*/
processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
//工作流的核心對(duì)象,ProcessEnginee對(duì)象
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
System.out.println("processEngine:"+processEngine);
}
/**使用配置文件創(chuàng)建工作流需要的23張表*/
@Test
public void createTable_2(){
// ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
// //工作流的核心對(duì)象,ProcessEnginee對(duì)象
// 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 日志配置文件?
把兩個(gè)文件放入resource目錄下即可。
5:核心API?
5.1:ProcessEngine?
說明:?
1) 在Activiti中最核心的類,其他的類都是由他而來。?
2) 產(chǎn)生方式:
在前面看到了兩種創(chuàng)建ProcessEngine(流程引擎)的方式,而這里要簡化很多,調(diào)用ProcessEngines的getDefaultProceeEngine方法時(shí)會(huì)自動(dòng)加載classpath下名為activiti.cfg.xml文件。?
3) 可以產(chǎn)生RepositoryService
4) 可以產(chǎn)生RuntimeService
5) 可以產(chǎn)生TaskService
各個(gè)Service的作用:?
RepositoryService 管理流程定義?
RuntimeService 執(zhí)行管理,包括啟動(dòng)、推進(jìn)、刪除流程實(shí)例等操作?
TaskService 任務(wù)管理?
HistoryService 歷史管理(執(zhí)行完的數(shù)據(jù)的管理)?
IdentityService 組織機(jī)構(gòu)管理?
FormService 一個(gè)可選服務(wù),任務(wù)表單管理?
ManagerService
5.2:RepositoryService?
是Activiti的倉庫服務(wù)類。所謂的倉庫指流程定義文檔的兩個(gè)文件:bpmn文件和流程圖片。?
1) 產(chǎn)生方式
2) 可以產(chǎn)生DeploymentBuilder,用來定義流程部署的相關(guān)參數(shù)
3) 刪除流程定義
5.3:RuntimeService?
是activiti的流程執(zhí)行服務(wù)類。可以從這個(gè)服務(wù)類中獲取很多關(guān)于流程執(zhí)行相關(guān)的信息。?
5.4:TaskService?
是activiti的任務(wù)服務(wù)類。可以從這個(gè)類中獲取任務(wù)的信息。?
5.5:HistoryService?
是activiti的查詢歷史信息的類。在一個(gè)流程執(zhí)行完成后,這個(gè)對(duì)象為我們提供查詢歷史信息。?
5.6:ProcessDefinition?
流程定義類。可以從這里獲得資源文件等。?
5.7:ProcessInstance?
代表流程定義的執(zhí)行實(shí)例。如范冰冰請(qǐng)了一天的假,她就必須發(fā)出一個(gè)流程實(shí)例的申請(qǐng)。一個(gè)流程實(shí)例包括了所有的運(yùn)行節(jié)點(diǎn)。我們可以利用這個(gè)對(duì)象來了解當(dāng)前流程實(shí)例的進(jìn)度等信息。流程實(shí)例就表示一個(gè)流程從開始到結(jié)束的最大的流程分支,即一個(gè)流程中流程實(shí)例只有一個(gè)。?
5.8:Execution?
Activiti用這個(gè)對(duì)象去描述流程執(zhí)行的每一個(gè)節(jié)點(diǎn)。在沒有并發(fā)的情況下,Execution就是同ProcessInstance。流程按照流程定義的規(guī)則執(zhí)行一次的過程,就可以表示執(zhí)行對(duì)象Execution。?
如圖為ProcessInstance的源代碼:?
從源代碼中可以看出ProcessInstance就是Execution。但在現(xiàn)實(shí)意義上有所區(qū)別:?
?
在單線流程中,如上圖的貸款流程,ProcessInstance與Execution是一致的。?
?
這個(gè)例子有一個(gè)特點(diǎn):wire money(匯錢)和archive(存檔)是并發(fā)執(zhí)行的。 這個(gè)時(shí)候,總線路代表ProcessInstance,而分線路中每個(gè)活動(dòng)代表Execution。?
總結(jié):?
* 一個(gè)流程中,執(zhí)行對(duì)象可以存在多個(gè),但是流程實(shí)例只能有一個(gè)。?
* 當(dāng)流程按照規(guī)則只執(zhí)行一次的時(shí)候,那么流程實(shí)例就是執(zhí)行對(duì)象。
6:HelloWorld程序(模擬流程的執(zhí)行)?
6.1:流程圖:
?
6.2:部署流程定義?
?
這里使用RepositoryService部署流程定義?
addClasspathResource表示從類路徑下加載資源文件,一次只能加載一個(gè)文件?
6.3:啟動(dòng)流程實(shí)例?
?
這里使用RuntimeService啟動(dòng)流程實(shí)例?
6.4:查看我的個(gè)人任務(wù)?
?
這里使用TaskService完成任務(wù)的查詢?
6.5:完成我的個(gè)人任務(wù)?
?
這里使用TaskService完成任務(wù)的辦理
7:管理流程定義?
7.1:設(shè)計(jì)流程定義文檔?
7.1.1:流程圖?
?
7.1.2:bpmn文件?
BPMN 2.0根節(jié)點(diǎn)是definitions節(jié)點(diǎn)。 這個(gè)元素中,可以定義多個(gè)流程定義(不過我們建議每個(gè)文件只包含一個(gè)流程定義, 可以簡化開發(fā)過程中的維護(hù)難度)。 一個(gè)空的流程定義看起來像下面這樣。注意,definitions元素 最少也要包含xmlns 和 targetNamespace的聲明。 targetNamespace可以是任意值,它用來對(duì)流程實(shí)例進(jìn)行分類。?
?
說明:流程定義文檔有兩部分組成:?
1) bpmn文件?
流程規(guī)則文件。在部署后,每次系統(tǒng)啟動(dòng)時(shí)都會(huì)被解析,把內(nèi)容封裝成流程定義放入項(xiàng)目緩存中。Activiti框架結(jié)合這個(gè)xml文件自動(dòng)管理流程,流程的執(zhí)行就是按照bpmn文件定義的規(guī)則執(zhí)行的,bpmn文件是給計(jì)算機(jī)執(zhí)行用的。?
2) 展示流程圖的圖片?
在系統(tǒng)里需要展示流程的進(jìn)展圖片,圖片是給用戶看的。
7.2:部署流程定義(classpath路徑加載文件)?
?
說明:?
1) 先獲取流程引擎對(duì)象:在創(chuàng)建時(shí)會(huì)自動(dòng)加載classpath下的activiti.cfg.xml
2) 首先獲得默認(rèn)的流程引擎,通過流程引擎獲取了一個(gè)RepositoryService對(duì)象(倉庫對(duì)象)?
3) 由倉庫的服務(wù)對(duì)象產(chǎn)生一個(gè)部署對(duì)象配置對(duì)象,用來封裝部署操作的相關(guān)配置。?
4) 這是一個(gè)鏈?zhǔn)骄幊?#xff0c;在部署配置對(duì)象中設(shè)置顯示名,上傳流程定義規(guī)則文件?
5) 向數(shù)據(jù)庫表中存放流程定義的規(guī)則信息。?
6) 這一步在數(shù)據(jù)庫中將操作三張表:?
a) act_re_deployment(部署對(duì)象表)?
存放流程定義的顯示名和部署時(shí)間,每部署一次增加一條記錄。?
?
Deployment deployment = processEngine.getRepositoryService()//?
.createDeployment().name(“入門程序”)//?
.addClasspathResource(“hello/helloworld.bpmn”)// 從classpath的資源中加載,一次只能加載一個(gè)文件?
// .addClasspathResource(“diagrams/helloworld.png”)//?
// 從classpath的資源中加載,一次只能加載一個(gè)文件?
.deploy();?
b) act_re_procdef(流程定義表)?
存放流程定義的屬性信息,部署每個(gè)新的流程定義都會(huì)在這張表中增加一條記錄。?
注意:當(dāng)流程定義的key相同的情況下,使用的是版本升級(jí)?
?
對(duì)應(yīng)的封裝類:
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()// 與流程定義和部署對(duì)象相關(guān)的Service
.createProcessDefinitionQuery()// 創(chuàng)建一個(gè)流程定義的查詢
/** 指定查詢條件,where條件 */
// .deploymentId(deploymentId)//使用部署對(duì)象ID查詢
// .processDefinitionId(processDefinitionId)//使用流程定義ID查詢
// .processDefinitionKey(processDefinitionKey)//使用流程定義的key查詢
// .processDefinitionNameLike(processDefinitionNameLike)//使用流程定義的名稱模糊查詢
/** 排序 */
.orderByProcessDefinitionVersion().asc()// 按照版本的升序排列
// .orderByProcessDefinitionName().desc()//按照流程定義的名稱降序排列
/** 返回的結(jié)果集 */
.list();// 返回一個(gè)集合列表,封裝流程定義
// .singleResult();//返回惟一結(jié)果集
// .count();//返回結(jié)果集數(shù)量
// .listPage(firstResult, maxResults);//分頁查詢
if (list != null && list.size() > 0) {
for (ProcessDefinition pd : list) {
System.out.println("流程定義ID:" + pd.getId());// 流程定義的key+版本+隨機(jī)生成數(shù)
System.out.println("流程定義的名稱:" + pd.getName());// 對(duì)應(yīng)helloworld.bpmn文件中的name屬性值
System.out.println("流程定義的key:" + pd.getKey());// 對(duì)應(yīng)helloworld.bpmn文件中的id屬性值
System.out.println("流程定義的版本:" + pd.getVersion());// 當(dāng)流程定義的key值相同的相同下,版本升級(jí),默認(rèn)1
System.out.println("資源名稱bpmn文件:" + pd.getResourceName());
System.out.println("資源名稱png文件:" + pd.getDiagramResourceName());
System.out.println("部署對(duì)象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?
部署對(duì)象ID:1?
c) act_ge_bytearray(資源文件表)?
存儲(chǔ)流程定義相關(guān)的部署信息。即流程定義文檔的存放地。每部署一次就會(huì)增加兩條記錄,一條是關(guān)于bpmn規(guī)則文件的,一條是圖片的(如果部署時(shí)只指定了bpmn一個(gè)文件,activiti會(huì)在部署時(shí)解析bpmn文件內(nèi)容自動(dòng)生成流程圖)。兩個(gè)文件不是很大,都是以二進(jìn)制形式存儲(chǔ)在數(shù)據(jù)庫中。?
7.3:部署流程定義(zip格式文件)?
?
?
將?
壓縮成zip格式的文件,使用zip的輸入流用作部署流程定義
7.4:查看流程定義?
查詢流程定義的信息?
?
結(jié)果:?
?
再部署一次運(yùn)行結(jié)果為:?
?
可以看到流程定義的key值相同的情況下,版本是從1開始逐次升級(jí)的?
流程定義的Id是【key:版本:生成ID】?
說明:?
1) 流程定義和部署對(duì)象相關(guān)的Service都是RepositoryService。?
2) 創(chuàng)建流程定義查詢對(duì)象,可以在ProcessDefinitionQuery上設(shè)置查詢的相關(guān)參數(shù)?
3) 調(diào)用ProcessDefinitionQuery對(duì)象的list方法,執(zhí)行查詢,獲得符合條件的流程定義列表?
4) 由運(yùn)行結(jié)果可以看出:?
Key和Name的值為:bpmn文件process節(jié)點(diǎn)的id和name的屬性值?
?
5) key屬性被用來區(qū)別不同的流程定義。?
6) 帶有特定key的流程定義第一次部署時(shí),version為1。之后每次部署都會(huì)在當(dāng)前最高版本號(hào)上加1?
7) Id的值的生成規(guī)則為:{processDefinitionKey}:{processDefinitionVersion}:{generated-id}, 這里的generated-id是一個(gè)自動(dòng)生成的唯一的數(shù)字?
8) 重復(fù)部署一次,deploymentId的值以一定的形式變化?
規(guī)則act_ge_property表生成?
?
7.5:刪除流程定義?
刪除部署到activiti中的流程定義。?
?
說明:?
1) 因?yàn)閯h除的是流程定義,而流程定義的部署是屬于倉庫服務(wù)的,所以應(yīng)該先得到RepositoryService?
2) 如果該流程定義下沒有正在運(yùn)行的流程,則可以用普通刪除。如果是有關(guān)聯(lián)的信息,用級(jí)聯(lián)刪除。項(xiàng)目開發(fā)中使用級(jí)聯(lián)刪除的情況比較多,刪除操作一般只開放給超級(jí)管理員使用。?
7.6:獲取流程定義文檔的資源(查看流程圖附件)?
查詢出流程定義文檔。主要查的是圖片,用于顯示流程用。?
?
說明:?
1) deploymentId為流程部署ID?
2) resourceName為act_ge_bytearray表中NAME_列的值?
3) 使用repositoryService的getDeploymentResourceNames方法可以獲取指定部署下得所有文件的名稱?
4) 使用repositoryService的getResourceAsStream方法傳入部署ID和資源圖片名稱可以獲取部署下指定名稱文件的輸入流?
5) 最后的有關(guān)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:流程定義的對(duì)象
map集合的特點(diǎn):當(dāng)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+版本+隨機(jī)生成數(shù)
System.out.println("流程定義的名稱:"+pd.getName());//對(duì)應(yīng)helloworld.bpmn文件中的name屬性值
System.out.println("流程定義的key:"+pd.getKey());//對(duì)應(yīng)helloworld.bpmn文件中的id屬性值
System.out.println("流程定義的版本:"+pd.getVersion());//當(dāng)流程定義的key值相同的相同下,版本升級(jí),默認(rèn)1
System.out.println("資源名稱bpmn文件:"+pd.getResourceName());
System.out.println("資源名稱png文件:"+pd.getDiagramResourceName());
System.out.println("部署對(duì)象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();//
// 遍歷,獲取每個(gè)流程定義的部署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:總結(jié)?
Deployment 部署對(duì)象?
1、一次部署的多個(gè)文件的信息。對(duì)于不需要的流程可以刪除和修改。?
2、對(duì)應(yīng)的表:?
act_re_deployment:部署對(duì)象表?
act_re_procdef:流程定義表?
act_ge_bytearray:資源文件表?
act_ge_property:主鍵生成策略表
ProcessDefinition 流程定義?
1、解析.bpmn后得到的流程定義規(guī)則的信息,工作流系統(tǒng)就是按照流程定義的規(guī)則執(zhí)行的。
8:流程實(shí)例、任務(wù)的執(zhí)行?
8.1:流程圖?
?
8.2:部署流程定義?
?
8.3:啟動(dòng)流程實(shí)例?
說明:?
1) 操作數(shù)據(jù)庫的act_ru_execution表,如果是用戶任務(wù)節(jié)點(diǎn),同時(shí)也會(huì)在act_ru_task添加一條記錄?
act_ru_execution表,#正在執(zhí)行的執(zhí)行對(duì)象表 任務(wù)結(jié)束的之前只有 一個(gè) 變化的字段是act_id?
8.4:查詢我的個(gè)人任務(wù)?
@Test
public void findMyPersonalTask(){
String assignee = "王五";
List<Task> list = processEngine.getTaskService()//與正在執(zhí)行的任務(wù)管理相關(guān)的Service
.createTaskQuery()//創(chuàng)建任務(wù)查詢對(duì)象
/**查詢條件(where部分)*/
.taskAssignee(assignee)//指定個(gè)人任務(wù)查詢,指定辦理人
// .taskCandidateUser(candidateUser)//組任務(wù)的辦理人查詢
// .processDefinitionId(processDefinitionId)//使用流程定義ID查詢
// .processInstanceId(processInstanceId)//使用流程實(shí)例ID查詢
// .executionId(executionId)//使用執(zhí)行對(duì)象ID查詢
/**排序*/
.orderByTaskCreateTime().asc()//使用創(chuàng)建時(shí)間的升序排列
/**返回結(jié)果集*/
// .singleResult()//返回惟一結(jié)果集
// .count()//返回結(jié)果集的數(shù)量
// .listPage(firstResult, maxResults);//分頁查詢
.list();//返回列表
if(list!=null && list.size()>0){
for(Task task:list){
System.out.println("任務(wù)ID:"+task.getId());
System.out.println("任務(wù)名稱:"+task.getName());
System.out.println("任務(wù)的創(chuàng)建時(shí)間:"+task.getCreateTime());
System.out.println("任務(wù)的辦理人:"+task.getAssignee());
System.out.println("流程實(shí)例ID:"+task.getProcessInstanceId());
System.out.println("執(zhí)行對(duì)象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
輸出:?
任務(wù)ID:504?
任務(wù)名稱:提交申請(qǐng)?
任務(wù)的創(chuàng)建時(shí)間:Sat Aug 09 08:50:20 CST 2014?
任務(wù)的辦理人:張三?
流程實(shí)例ID:501?
執(zhí)行對(duì)象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) 因?yàn)槭侨蝿?wù)查詢,所以從processEngine中應(yīng)該得到TaskService?
2) 使用TaskService獲取到任務(wù)查詢對(duì)象TaskQuery?
3) 為查詢對(duì)象添加查詢過濾條件,使用taskAssignee指定任務(wù)的辦理者(即查詢指定用戶的代辦任務(wù)),同時(shí)可以添加分頁排序等過濾條件?
4) 調(diào)用list方法執(zhí)行查詢,返回辦理者為指定用戶的任務(wù)列表?
5) 任務(wù)ID、名稱、辦理人、創(chuàng)建時(shí)間可以從act_ru_task表中查到。?
6) Execution與ProcessInstance見5.6和5.7章節(jié)的介紹。在這種情況下,ProcessInstance相當(dāng)于Execution?
7) 如果assignee屬性為部門經(jīng)理,結(jié)果為空。因?yàn)楝F(xiàn)在流程只到了”填寫請(qǐng)假申請(qǐng)”階段,后面的任務(wù)還沒有執(zhí)行,即在數(shù)據(jù)庫中沒有部門經(jīng)理可以辦理的任務(wù),所以查詢不到。?
8) 一個(gè)Task節(jié)點(diǎn)和Execution節(jié)點(diǎn)是1對(duì)1的情況,在task對(duì)象中使用Execution_來表示他們之間的關(guān)系?
9) 任務(wù)ID在數(shù)據(jù)庫表act_ru_task中對(duì)應(yīng)“ID_”列
附加:?
在activiti任務(wù)中,主要分為兩大類查詢?nèi)蝿?wù)(個(gè)人任務(wù)和組任務(wù)):?
1.確切指定了辦理者的任務(wù),這個(gè)任務(wù)將成為指定者的私有任務(wù),即個(gè)人任務(wù)。?
2.無法指定具體的某一個(gè)人來辦理的任務(wù),可以把任務(wù)分配給幾個(gè)人或者一到 多個(gè)小組,讓這個(gè)范圍內(nèi)的用戶可以選擇性(如有空余時(shí)間時(shí))來辦理這類任務(wù),即組任務(wù)。?
先知道個(gè)人任務(wù)的查詢和辦理,組任務(wù)的操作后面講
8.5:辦理任務(wù)?
說明:?
1) 是辦理任務(wù),所以從ProcessEngine得到的是TaskService。?
2) 當(dāng)執(zhí)行完這段代碼,再以員工的身份去執(zhí)行查詢的時(shí)候,會(huì)發(fā)現(xiàn)這個(gè)時(shí)候已經(jīng)沒有數(shù)據(jù)了,因?yàn)檎趫?zhí)行的任務(wù)中沒有數(shù)據(jù)。?
3) 對(duì)于執(zhí)行完的任務(wù),activiti將從act_ru_task表中刪除該任務(wù),下一個(gè)任務(wù)會(huì)被插入進(jìn)來。?
4) 以”部門經(jīng)理”的身份進(jìn)行查詢,可以查到結(jié)果。因?yàn)榱鞒虉?zhí)行到部門經(jīng)理審批這個(gè)節(jié)點(diǎn)了。?
5) 再執(zhí)行辦理任務(wù)代碼,執(zhí)行完以后以”部門經(jīng)理”身份進(jìn)行查詢,沒有結(jié)果。?
6) 重復(fù)第3和4步直到流程執(zhí)行完。?
act_ru_task表:?
8.6:查詢流程狀態(tài)(判斷流程正在執(zhí)行,還是結(jié)束)?
?
/* 查詢流程狀態(tài)(判斷流程正在執(zhí)行,還是結(jié)束)?/
@Test
public void isProcessEnd() {
String processInstanceId = "501";
ProcessInstance pi = processEngine.getRuntimeService()// 表示正在執(zhí)行的流程實(shí)例和執(zhí)行對(duì)象
.createProcessInstanceQuery()// 創(chuàng)建流程實(shí)例查詢
.processInstanceId(processInstanceId)// 使用流程實(shí)例ID查詢
.singleResult();
if (pi == null) {
System.out.println("流程已經(jīng)結(jié)束");
} else {
System.out.println("流程沒有結(jié)束");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
在流程執(zhí)行的過程中,創(chuàng)建的流程實(shí)例ID在整個(gè)過程中都不會(huì)變,當(dāng)流程結(jié)束后,流程實(shí)例將會(huì)在正在執(zhí)行的執(zhí)行對(duì)象表中(act_ru_execution)被刪除
說明:
1) 因?yàn)槭遣樵兞鞒虒?shí)例,所以先獲取runtimeService?
2) 創(chuàng)建流程實(shí)例查詢對(duì)象,設(shè)置實(shí)例ID過濾參數(shù)?
3) 由于一個(gè)流程實(shí)例ID只對(duì)應(yīng)一個(gè)實(shí)例,使用singleResult執(zhí)行查詢返回一個(gè)唯一的結(jié)果,如果結(jié)果數(shù)量大于1,則拋出異常?
4) 判斷指定ID的實(shí)例是否存在,如果結(jié)果為空,則代表流程結(jié)束,實(shí)例在正在執(zhí)行的執(zhí)行對(duì)象表中已被刪除,轉(zhuǎn)換成歷史數(shù)據(jù)。?
8.7:附加功能:查詢歷史任務(wù)(后面講)?
?
/*查詢歷史任務(wù)(后面講)/
@Test
public void findHistoryTask(){
String taskAssignee = "張三";
List<HistoricTaskInstance> list = processEngine.getHistoryService()//與歷史數(shù)據(jù)(歷史表)相關(guān)的Service
.createHistoricTaskInstanceQuery()//創(chuàng)建歷史任務(wù)實(shí)例查詢
.taskAssignee(taskAssignee)//指定歷史任務(wù)的辦理人
.list();
if(list!=null && list.size()>0){
for(HistoricTaskInstance hti:list){
System.out.println(hti.getId()+" "+hti.getName()+" "+hti.getProcessInstanceId()+" "+hti.getStartTime()+" "+hti.getEndTime()+" "+hti.getDurationInMillis());
System.out.println("################################");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
表《HistoricTaskInstance》?
8.8:附加功能:查詢歷史流程實(shí)例(后面講)
?
8.9:總結(jié)?
Execution 執(zhí)行對(duì)象?
按流程定義的規(guī)則執(zhí)行一次的過程.?
對(duì)應(yīng)的表:?
act_ru_execution: 正在執(zhí)行的信息?
act_hi_procinst:已經(jīng)執(zhí)行完的歷史流程實(shí)例信息?
act_hi_actinst:存放歷史所有完成的活動(dòng)?
ProcessInstance 流程實(shí)例?
特指流程從開始到結(jié)束的那個(gè)最大的執(zhí)行分支,一個(gè)執(zhí)行的流程中,流程實(shí)例只有1個(gè)。
注意?
(1)如果是單例流程,執(zhí)行對(duì)象ID就是流程實(shí)例ID?
(2)如果一個(gè)流程有分支和聚合,那么執(zhí)行對(duì)象ID和流程實(shí)例ID就不相同?
(3)一個(gè)流程中,流程實(shí)例只有1個(gè),執(zhí)行對(duì)象可以存在多個(gè)。
Task 任務(wù)?
執(zhí)行到某任務(wù)環(huán)節(jié)時(shí)生成的任務(wù)信息。?
對(duì)應(yīng)的表:?
act_ru_task:正在執(zhí)行的任務(wù)信息?
act_hi_taskinst:已經(jīng)執(zhí)行完的歷史任務(wù)信息
9:流程變量?
9.1:流程圖?
?
流程變量在整個(gè)工作流中扮演很重要的作用。例如:請(qǐng)假流程中有請(qǐng)假天數(shù)、請(qǐng)假原因等一些參數(shù)都為流程變量的范圍。流程變量的作用域范圍是只對(duì)應(yīng)一個(gè)流程實(shí)例。也就是說各個(gè)流程實(shí)例的流程變量是不相互影響的。流程實(shí)例結(jié)束完成以后流程變量還保存在數(shù)據(jù)庫中。?
例如:?
即:
9.2:部署流程定義?
?
說明:?
? 輸入流加載資源文件的3種方式?
?
9.3:啟動(dòng)流程實(shí)例?
?
9.4:設(shè)置流程變量?
說明:?
1) 流程變量的作用域就是流程實(shí)例,所以只要設(shè)置就行了,不用管在哪個(gè)階段設(shè)置?
2) 基本類型設(shè)置流程變量,在taskService中使用任務(wù)ID,定義流程變量的名稱,設(shè)置流程變量的值。?
3) Javabean類型設(shè)置流程變量,需要這個(gè)javabean實(shí)現(xiàn)了Serializable接口?
4) 設(shè)置流程變量的時(shí)候,向act_ru_variable這個(gè)表添加數(shù)據(jù)
9.5:獲取流程變量?
說明:?
1) 流程變量的獲取針對(duì)流程實(shí)例(即1個(gè)流程),每個(gè)流程實(shí)例獲取的流程變量時(shí)不同的?
2) 使用基本類型獲取流程變量,在taskService中使用任務(wù)ID,流程變量的名稱,獲取流程變量的值。?
3) Javabean類型設(shè)置獲取流程變量,除了需要這個(gè)javabean實(shí)現(xiàn)了Serializable接口外,還要求流程變量對(duì)象的屬性不能發(fā)生變化,否則拋出異常。?
解決方案,在javabean對(duì)象中添加:?
private static final long serialVersionUID = 6757393795687480331L;?
9.6:模擬流程變量的設(shè)置和獲取的場景?
?
說明:?
1) RuntimeService對(duì)象可以設(shè)置流程變量和獲取流程變量?
2) TaskService對(duì)象可以設(shè)置流程變量和獲取流程變量?
3) 流程實(shí)例啟動(dòng)的時(shí)候可以設(shè)置流程變量?
4) 任務(wù)辦理完成的時(shí)候可以設(shè)置流程變量?
5) 流程變量可以通過名稱/值的形式設(shè)置單個(gè)流程變量?
6) 流程變量可以通過Map集合,同時(shí)設(shè)置多個(gè)流程變量?
Map集合的key表示流程變量的名稱?
Map集合的value表示流程變量的值
9.7:查詢歷史的流程變量?
?
說明:?
1)歷史的流程變量查詢,指定流程變量的名稱,查詢act_hi_varinst表(也可以針對(duì),流程實(shí)例ID,執(zhí)行對(duì)象ID,任務(wù)ID查詢)
9.8:流程變量的支持的類型?
如圖是從官網(wǎng)列出來的流程變量的類型:?
?
從圖中可以看出包括了大部分封裝類型和Date、String和實(shí)現(xiàn)了Serializable接口的類的類型。?
9.9:總結(jié)?
? 1:流程變量?
在流程執(zhí)行或者任務(wù)執(zhí)行的過程中,用于設(shè)置和獲取變量,使用流程變量在流程傳遞的過程中傳遞業(yè)務(wù)參數(shù)。?
對(duì)應(yīng)的表:?
act_ru_variable:正在執(zhí)行的流程變量表?
act_hi_varinst:流程變量歷史表
? 2:擴(kuò)展知識(shí):setVariable和setVariableLocal的區(qū)別?
setVariable:設(shè)置流程變量的時(shí)候,流程變量名稱相同的時(shí)候,后一次的值替換前一次的值,而且可以看到TASK_ID的字段不會(huì)存放任務(wù)ID的值?
setVariableLocal:?
1:設(shè)置流程變量的時(shí)候,針對(duì)當(dāng)前活動(dòng)的節(jié)點(diǎn)設(shè)置流程變量,如果一個(gè)流程中存在2個(gè)活動(dòng)節(jié)點(diǎn),對(duì)每個(gè)活動(dòng)節(jié)點(diǎn)都設(shè)置流程變量,即使流程變量的名稱相同,后一次的版本的值也不會(huì)替換前一次版本的值,它會(huì)使用不同的任務(wù)ID作為標(biāo)識(shí),存放2個(gè)流程變量值,而且可以看到TASK_ID的字段會(huì)存放任務(wù)ID的值?
例如act_hi_varinst 表的數(shù)據(jù):不同的任務(wù)節(jié)點(diǎn),即使流程變量名稱相同,存放的值也是不同的。?
如圖:?
2:還有,使用setVariableLocal說明流程變量綁定了當(dāng)前的任務(wù),當(dāng)流程繼續(xù)執(zhí)行時(shí),下個(gè)任務(wù)獲取不到這個(gè)流程變量(因?yàn)檎趫?zhí)行的流程變量中沒有這個(gè)數(shù)據(jù)),所有查詢正在執(zhí)行的任務(wù)時(shí)不能查詢到我們需要的數(shù)據(jù),此時(shí)需要查詢歷史的流程變量。
10:流程執(zhí)行歷史記錄?
10.1:查詢歷史流程實(shí)例?
查找按照某個(gè)流程定義的規(guī)則一共執(zhí)行了多少次流程?
?
10.2:查詢歷史活動(dòng)?
某一次流程的執(zhí)行一共經(jīng)歷了多少個(gè)活動(dòng)?
?
10.3:查詢歷史任務(wù)?
某一次流程的執(zhí)行一共經(jīng)歷了多少個(gè)任務(wù)?
?
10.4:查詢歷史流程變量?
某一次流程的執(zhí)行一共設(shè)置的流程變量?
?
10.5:總結(jié)?
由于數(shù)據(jù)庫中保存著歷史信息以及正在運(yùn)行的流程實(shí)例信息,在實(shí)際項(xiàng)目中對(duì)已完成任務(wù)的查看頻率遠(yuǎn)不及對(duì)代辦和可接任務(wù)的查看,所以在activiti采用分開管理,把正在運(yùn)行的交給RuntimeService、TaskService管理,而歷史數(shù)據(jù)交給HistoryService來管理。?
這樣做的好處在于,加快流程執(zhí)行的速度,因?yàn)檎趫?zhí)行的流程的表中數(shù)據(jù)不會(huì)很大。
總結(jié)
以上是生活随笔為你收集整理的Activiti最新全入门教程(以请假为例讲解)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java学习笔记----Mybatis-
- 下一篇: 7月5日绝地求生服务器维护,7月5日绝地