国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Flowable 流程部署與刪除

數據庫 其他數據庫
其實當我們使用了 Spring Boot 之后,默認情況下流程是會自動部署的,基本上不需要我們額外做什么事情。不過這些操作里還是有不少細節,今天松哥就來帶大家一起來梳理一下。

本文我們一起來看看流程的部署等細節問題。

其實當我們使用了 Spring Boot 之后,默認情況下流程是會自動部署的,基本上不需要我們額外做什么事情。不過這些操作里還是有不少細節,今天松哥就來帶大家一起來梳理一下。

1. 默認行為

首先我們先來梳理一下默認行為。

默認情況下,我們放在 resources/processes 目錄下的所有流程文件會自動被部署,流程文件的后綴有兩種形式 bpmn20.xml 或者 bpmn。當然,無論是存放流程文件的位置,還是流程文件的格式,都是可以定制的,涉及到的屬性主要有三個,可在 application.properties 中進行配置:

flowable.check-process-definitions=false
flowable.process-definition-location-prefix=classpath*:/processes/
flowable.process-definition-location-suffixes=**.bpmn20.xml,**.bpmn

flowable.check-process-definitions:這個表示是否在項目啟動的時候,去檢查文件目錄是否有對應的流程文件,該屬性為 true 表示如果有流程文件就自動部署,false 表示不檢查,那么也就不會自動部署。

flowable.process-definition-location-prefix?:這個是流程文件的位置,默認就是 classpath*:/processes/,當然開發者也可以進行配置。

flowable.process-definition-location-suffixes?:這個是流程文件的后綴,默認有兩個,分別是 **.bpmn20.xml 和 **.bpmn,當然開發者也可以進行配置。

這個配置應該沒啥好說的。

2. 動態部署

有的時候,我們的流程可能并不是提前設計好的,而是項目啟動之后,動態部署的,例如項目啟動成功之后,動態上傳一個流程的 XML 文件進行部署,這也是一種比較常見的場景,對于這種情況,我們可以按照如下方式進行部署:

@RestController
public class ProcessDeployController {

@Autowired
RepositoryService repositoryService;

@PostMapping("/deploy")
public RespBean deploy(MultipartFile file) throws IOException {
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
.category("javaboy的工作流分類")
.name("javaboy的工作流名稱")
.addInputStream(file.getOriginalFilename(), file.getInputStream())
.key("javaboy的工作流key");
Deployment deployment = deploymentBuilder
.deploy();
return RespBean.ok("部署成功",deployment.getId());
}
}

我這里給了一個簡單的文件上傳接口,關于文件上傳部分我就不多說了。我們來看下流程部署:

首先通過 repositoryService.createDeployment() 方法來創建一個流程部署構建器,即 DeploymentBuilder。

接下來為 DeploymentBuilder 設置分類、名稱以及 key 等屬性。

關鍵的方法是 addInputStream,通過該方法去指定流程文件。官方的提供的指定流程文件的方式有好幾種;除了 addInputStream 之外,另外還有一個 addString,這個就是將流程文件轉為一個字符串傳入進來;addBytes 是將流程文件轉為字節數組傳進來;addClasspathResource 方法則是直接從 classpath 目錄下去加載流程文件,這幾個方法根據自己的使用場景選擇一個合適的方法去調用即可。

這里有一個需要跟大家強調的地方,就是 addInputStream/addBytes/addString 等方法都需要設置資源名,這個名稱是可以隨意設置的,但是注意名稱的后綴,需要是 bpmn20.xml 或者 bpmn,否則流程沒有部署。為什么流程名后綴要是 bpmn20.xml 或者 bpmn 呢?參考第一小節。

3. 表分析

在我們的流程部署過程中,一共有三張表參與到我們的工作中了,雖然松哥之前已經寫過文章和大家梳理 flowable 中各個數據表的作用,不過當時只是大致上介紹了一下,沒有細說,這次我們就先來看看這次涉及到的三張表。

ACT_RE_DEPLOYMENT

這個表是流程部署表,每部署一個流程,這張表中就會新增一條記錄,用來描述我們剛剛定義好的流程:

圖片

這里的 ID_、NAME_、CATEGORY_ 等等,就是我們在部署流程的時候設置的參數。

ACT_RE_PROCDEF

這是流程定義表,我們每定義的一個流程,都會記錄在這張表中:

圖片

這張表中的字段比較多,我這里只是列出來了其中一部分。這這表中有一個 DEPLOYMENT_ID 字段,和 ACT_RE_DEPLOYMENT 表進行關聯,所以 ACT_RE_DEPLOYMENT 和 ACT_RE_PROCDEF 表的關系,其實是一對一的關系,部署表中的一條記錄對應定義表中的一條記錄。

另外,該表中有一個 CATEGORY_ 的字段,這個字段表示流程的分類,注意這個和部署的分類可不一樣,流程部署的分類參數第二小節的代碼,流程的分類,說白了其實就是我們流程定義 XML 文件中的 targetNamespace 屬性,如下圖:

圖片

大家可根據自己的實際需求去修改 targetNamespace 屬性的值,這個值改了之后,ACT_RE_PROCDEF 表中的 CATEGORY_ 字段也會跟著發生變化。

另外,該表中還有一個 VERSION_ 字段,這個看名字就知道是描述記錄的版本號,當我們修改了流程的內容之后,重新部署的時候,ACT_RE_DEPLOYMENT 表和 ACT_RE_PROCDEF 表均會自動增加一條記錄數,其中,流程定義表 ACT_RE_PROCDEF 中的記錄的 VERSION_ 字段的值會自動加 1,這樣我們就能夠看到不同歷史版本的流程定義。

那么系統是怎么識別修改后的流程和前一個流程是同一個呢?主要是靠流程的 id 屬性,如下圖:

圖片

這個流程的 id 屬性,對應到表中,就是 ACT_RE_PROCDEF 表的 KEY_ 字段。

ACT_GE_BYTEARRAY

涉及到的第三張表是這個通用數據存儲表,這個表的字段比較少,如下圖:

圖片

小伙伴們看到,這個表中有一個 DEPLOYMENT_ID 字段,這個就是跟 ACT_RE_DEPLOYMENT 表關聯的字段,一條流程部署記錄在 ACT_GE_BYTEARRAY 表中對應兩條記錄,分別是記錄 XML 文件和記錄流程圖片。

這個表中有一個 BYTES_ 字段,我們部署的流程的 XML 文件就保存在這里,同時,系統默認還會根據 XML 文件生成一張流程圖片,也保存在這里,圖片就像下面這種:

圖片

所以一個流程部署,在這張表中對應兩條記錄,一條記錄 XML 文件,一條記錄流程圖片。

好啦,這就是流程部署涉及到的三張表。

4. 查詢操作

接下來,強烈建議大家在 Spring Boot 的 application.properties 中添加如下配置,開啟 flowable 日志:

logging.level.org.flowable=debug

這個配置表示開啟 flowable 的日志,開啟日志的好處是我們可以看到底層的 SQL,學習 flowable,調用 API 的時候,不能只掌握 API 的使用,調用 API 的時候,心里想著這是操作哪張表,學起來更快。

4.1 查詢部署信息

例如我們現在想要查詢流程的部署信息,如下:

@Test
void test01() throws IOException {
List<Deployment> list = repositoryService.createDeploymentQuery().list();
for (Deployment deployment : list) {
logger.info("id:{};key:{}", deployment.getId(), deployment.getKey());
}
}

創建一個查詢器,然后返回所有的流程部署信息并打印出來,我們看下此時 IDEA 控制臺打印出來的 SQL 信息:

圖片

可以看到,底層執行的 SQL 其實就是去查詢 ACT_RE_DEPLOYMENT 表。

現在我們再去看一些查詢的方法,應該就很容易明白其含義了:

圖片

小伙伴們看到,我們可以利用流程部署的名字、分類、ID 等各種信息去查詢,可以精確匹配也可以模糊匹配。

例如我想查詢 key 為 javaboy的工作流key 的流程部署文件,但是這個流程我之前部署過多次(版本升級),現在我想查詢最近一次的流程部署信息,查詢方式如下:

@Test
void test01() throws IOException {
Deployment deployment = repositoryService.createDeploymentQuery().deploymentKey("javaboy的工作流key").latest().singleResult();
logger.info("id:{};key:{}", deployment.getId(), deployment.getKey());
}

我們來看下控制臺打印出來的 SQL:

--- [           main] i.p.e.D.selectDeploymentsByQueryCriteria : ==>  Preparing: SELECT RES.* from ACT_RE_DEPLOYMENT RES WHERE RES.KEY_ = ? and RES.DEPLOY_TIME_ = (select max(DEPLOY_TIME_) from ACT_RE_DEPLOYMENT where KEY_ = RES.KEY_ and DERIVED_FROM_ is null and ( (TENANT_ID_ IS NOT NULL and TENANT_ID_ = RES.TENANT_ID_) or (TENANT_ID_ IS NULL and RES.TENANT_ID_ IS NULL) ) ) order by RES.ID_ asc
--- [ main] i.p.e.D.selectDeploymentsByQueryCriteria : ==> Parameters: javaboy的工作流key(String)
--- [ main] i.p.e.D.selectDeploymentsByQueryCriteria : <== Total: 1

這個 SQL 寫的有點復雜,但是仔細看就一個意思,給定查詢的 key 是 javaboy的工作流key,查詢時間是一個最大的時間,這就很好懂了。

4.2 查詢流程定義信息

接下來我們再來看看查詢流程的定義信息。查詢所有的流程定義信息,如下:

@Test
void test02() {
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
for (ProcessDefinition pd : list) {
logger.info("id:{};key:{};version:{};",pd.getId(),pd.getKey(),pd.getVersion());
}
}

來看看控制臺打印的 SQL:

圖片

可以看到,就是去流程定義表 ACT_RE_PROCDEF 去查看所有。

基于此,其他的查詢 API 就都好理解了,例如根據流程定義的 KEY 去查詢所有的流程定義,這個 KEY 其實就是流程定義 XML 文件中的 id:

@Test
void test02() {
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionKey("javaboy_submit_an_expense_account").list();
for (ProcessDefinition pd : list) {
logger.info("id:{};key:{};version:{};",pd.getId(),pd.getKey(),pd.getVersion());
}
}

我們來看下查詢 SQL:

圖片

其他的查詢 API 我就不挨個演示了,方法基本上都是見名知意的。

4.3 原生查詢

要是覺得用 API 查詢 不過癮,我們也可以自己寫 SQL 查詢。

跟前面一樣,例如我想查詢 key 為 javaboy的工作流key 的流程部署文件,但是這個流程我之前部署過多次(版本升級),現在我想查詢最近一次的流程部署信息,查詢方式如下:

@Test
void test03() {
Deployment deployment = repositoryService.createNativeDeploymentQuery().sql("SELECT RES.* from ACT_RE_DEPLOYMENT RES WHERE RES.KEY_ = #{key} and RES.DEPLOY_TIME_ = (select max(DEPLOY_TIME_) from ACT_RE_DEPLOYMENT where KEY_ = RES.KEY_) order by RES.ID_ asc").parameter("key", "javaboy的工作流key").singleResult();
logger.info("id:{};key:{}", deployment.getId(), deployment.getKey());
}

自己寫 SQL 即可,參數的占位符用 #,因為這里底層的 SQL 操作實際上是 MyBatis。

相同的道理,我想根據流程定義的 KEY 去查詢流程定義信息,使用原生查詢方式如下:

@Test
void test04() {
List<ProcessDefinition> list = repositoryService.createNativeProcessDefinitionQuery()
.sql("SELECT RES.* from ACT_RE_PROCDEF RES WHERE RES.KEY_ = #{key} order by RES.ID_ asc")
.parameter("key", "javaboy_submit_an_expense_account").list();
for (ProcessDefinition pd : list) {
logger.info("id:{};key:{};version:{};", pd.getId(), pd.getKey(), pd.getVersion());
}
}

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2022-09-28 21:24:33

SQL字段ID

2023-04-10 07:47:01

流程引擎Flowable

2022-09-26 14:25:55

Flowable流程ID

2020-10-13 18:25:33

技術流程云計算

2022-10-27 14:18:13

Flowable流程變量

2022-05-06 10:42:09

JavaFlowable引擎

2022-10-31 10:41:02

Flowable流程前綴

2025-05-30 01:00:00

開源流程引擎

2023-08-02 18:48:23

Flowable工作流引擎

2022-07-07 08:38:15

Springflowable引擎

2022-09-05 14:37:14

flowableVue 庫XML

2024-05-23 08:07:05

2020-06-10 08:55:36

Docker容器工具

2025-01-02 15:16:26

Docker容器云計算

2022-10-08 11:40:18

Receive阻塞Trigger

2015-06-11 16:36:27

ASP.NET

2022-10-11 10:47:04

UserTaskSQL查詢

2024-05-07 08:31:09

SpringFlowable業務流程

2021-05-13 10:12:55

Kubernetes 微服務軟件開發

2021-09-08 10:47:33

Flink執行流程
點贊
收藏

51CTO技術棧公眾號

欧美人与禽猛交乱配视频| 久久新电视剧免费观看| 欧美激情手机在线视频| 亚洲资源一区| 精品久久久久久久久久国产 | 国产精品中文在线| 136国产福利精品导航网址应用| 亚洲国产精品久久久久秋霞不卡| 黄色在线免费观看大全| 亚洲一区二区影院| hbad中文字幕| 亚洲色图丝袜美腿| 在线观看免费播放网址成人| 久久久不卡网国产精品一区| 中国一级大黄大黄大色毛片| 免费黄网站欧美| 日韩av电影免费观看| 久久资源在线| 亚洲一区二区三区免费观看| 蜜桃视频在线一区| 91xxx视频| 99久久免费视频.com| 免费国产a级片| 久久久精品tv| 九色丨porny丨| 午夜欧美2019年伦理| 最新亚洲人成网站在线观看| 欧美日韩国产精品一区二区不卡中文 | 99久久久久久99| 日韩伦理在线免费观看| 91色porny蝌蚪| 国产性xxxx18免费观看视频| 国产欧美一区二区三区鸳鸯浴| 亚洲成色www.777999| 中文字幕一区在线观看视频| 九色福利视频| 在线一区二区三区四区五区| 黄色av免费在线| 欧美tickling网站挠脚心| 午夜无码国产理论在线| 久久99精品国产99久久6尤物| 台湾色综合娱乐中文网| 91免费看片网站| 日韩电影免费在线| 日本国产在线播放| 亚洲精品视频自拍| 超碰国产在线| 亚洲日本成人女熟在线观看 | 99热成人精品热久久66| 亚洲免费三区一区二区| 成人亚洲综合天堂| 亚洲视频精品在线| 小说区图片区色综合区| 国产一区二区三区四区五区在线| 精品一区二区三区蜜桃| 中文字幕在线观看第三页| 欧美午夜激情在线| 黄色软件视频在线观看| 久久久久久久久久久免费 | 国产永久免费高清在线观看| 亚洲国产精品悠悠久久琪琪| 日本精品在线播放| 亚洲综合一区二区不卡| 国产成人av福利| 宅男深夜免费观看视频| 欧美一区二区播放| julia中文字幕一区二区99在线| 国产欧美中文字幕| 日本不卡中文字幕| wwwav91| 亚洲成人精品视频在线观看| 成人精品动漫一区二区三区| 久久影视中文粉嫩av| 国产三级久久久| 国产在线高清视频| 亚州av一区二区| 麻豆精品一二三| 一本到av在线| 中文字幕成人在线| 激情欧美日韩一区| wwwwxxxx日韩| 精品久久久久久久久久久久久久久久久| 亚洲高清在线一区| 欧美激情第一页在线观看| 国产精品私人自拍| segui88久久综合9999| 国产美女久久精品香蕉69| 国产精品亚洲人在线观看| 加勒比一区二区三区在线| 久久综合久久八八| 久久久成人网| 粉嫩tv在线播放| 久久久精品视频成人| 午夜在线a亚洲v天堂网2018| 国产黄色免费网| 伊人久久久久久久久久久久久| 亚洲影视一区| 中文字幕第38页| 亚洲天堂色网站| 久久欧美肥婆一二区| 亚州av中文字幕在线免费观看| 精品视频9999| 国产成人av影院| а√天堂中文资源在线bt| 狠狠色噜噜狠狠色综合久| 亚洲电影一区二区| 狼人天天伊人久久| 午夜精品久久久内射近拍高清 | 成人黄色国产精品网站大全在线免费观看 | 欧美一级电影免费在线观看| 在线国产精品一区| 能在线观看av网站| 欧美人在线视频| 国产成人精品综合在线观看| 性欧美高清come| 国产精品免费在线播放| 欧美日韩在线看| 国产精品一线天粉嫩av| 久草福利视频在线| 欧美老少做受xxxx高潮| 岛国av在线一区| 三级中文字幕在线观看| 一区二区三视频| 精品国产91久久久久久久妲己| 国产日韩亚洲| 免费日本一区二区三区视频| av免费观看久久| 欧美中文一区二区三区| 亚洲视频中文| 免费的黄网站在线观看| 精品国产乱码久久久久久108| 91福利在线播放| 国产精品a久久久久| 成人精品福利| 国产精品一码二码三码在线| 欧美熟乱第一页| 亚洲久色影视| av在线免费网站| 在线观看日韩羞羞视频| 亚洲欧洲日产国码av系列天堂| 久久9热精品视频| 在线免费三级电影网站| 狠狠干视频网站| 久久久精品久久久| 国产精品久久久久影院| 日韩电影免费网址| 加勒比一区二区三区在线| 99久久精品免费看国产一区二区三区| 色哟哟一区二区| 亚洲精品九九| 麻豆mv在线看| 国产裸体免费无遮挡| 91国产精品91| 偷拍日韩校园综合在线| 国产精品久久| 欧美激情网站| xxxx一级片| 成人午夜高潮视频| 欧美一区二区三区婷婷月色| 久久丁香综合五月国产三级网站| 成人国产网站| 天海翼女教师无删减版电影| 操人视频欧美| 亚洲欧美综合另类中字| 国产精品你懂的在线| 日韩欧美国产精品综合嫩v| 日本三级视频在线播放| 成人午夜视频免费观看| 欧洲成人免费aa| 欧美精品丝袜中出| k8久久久一区二区三区| 成人情趣视频| 少妇视频在线观看| jizzjizzjizz亚洲| 久久免费一区| 久久久久国产一区二区三区| 在线观看亚洲a| 成人福利视频在线看| 国产精选一区| av在线视屏| 全部孕妇毛片丰满孕妇孕交| 日韩三级在线播放| …久久精品99久久香蕉国产| 制服视频三区第一页精品| 久久久影视传媒| 在线免费高清一区二区三区| 2019中文亚洲字幕| 91精彩在线视频| 久久久久久香蕉| 国产日韩一区二区三区| 久久福利视频网| 欧美在线观看一二区| 91老师国产黑色丝袜在线| 亚洲婷婷免费| 国产人妖ts一区二区| 在线看福利影| 色影视在线视频资源站| 日本老太婆做爰视频| 91在线网站视频| 欧美精品一区二区三区国产精品|