Activiti搭建---初始化資料庫
Activiti介紹
Activiti5是由Alfresco軟體在2010年5月17日釋出的業務流程管理(BPM)框架,它是覆蓋了業務流程管理、工作流、服務協作等領域的一個開源的、靈活的、易擴充套件的可執行流程語言框架。Activiti基於Apache許可的開源BPM平臺,創始人Tom Baeyens是JBoss jBPM的專案架構師,它特色是提供了eclipse外掛,開發人員可以通過外掛直接繪畫出業務
流程圖。
1.工作流引擎
ProcessEngine物件,這是Activiti工作的核心。負責生成流程執行時的各種例項及資料、監控和管理流程的執行。
2. BPMN
業務流程建模與標註(Business Process Model and Notation,BPMN) ,描述流程的基本符號,包括這些圖元如何組合成一個業務流程圖(Business Process Diagram)
3. 資料庫
Activiti資料庫支援:
Activiti的後臺是有資料庫的支援,所有的表都以ACT_開頭。 第二部分是表示表的用途的兩個字母標識。 用途也和服務的API對應。
ACT_RE_*: 'RE'表示repository。 這個字首的表包含了流程定義和流程靜態資源 (圖片,規則,等等)。
ACT_RU_*: 'RU'表示runtime。 這些執行時的表,包含流程例項,任務,變數,非同步任務,等執行中的資料。 Activiti只在流程例項執行過程中儲存這些資料, 在流程結束時就會刪除這些記錄。 這樣執行時表可以一直很小速度很快。
ACT_ID_*: 'ID'表示identity。 這些表包含身份資訊,比如使用者,組等等。
ACT_HI_*: 'HI'表示history。 這些表包含歷史資料,比如歷史流程例項, 變數,任務等等。
ACT_GE_*: 通用資料, 用於不同場景下,如存放資原始檔。
4. 下載庫activiti
地址:http://activiti.org/download.html
5. 解壓後的目錄
database資料夾中就是關於資料庫的相關檔案指令碼
create資料夾中就是Activiti所有支援的資料庫指令碼檔案
activiti-engine.jar包中自帶了建立activiti工作流資料庫表的SQL語句和自動初始化資料庫的方法。SQL語句在org.activiti.db.create包下,初始化方法在org.activiti.engine.impl.db.DbSchemaCreate的main方法之中。
原始碼如下:
1 2 3 4 5 6 7 8 9 10 |
public
class
DbSchemaCreate {
public
static
void
main(String[] args) {
ProcessEngineConfiguration
.createProcessEngineConfigurationFromResourceDefault()
.setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_CREATE)
.buildProcessEngine();
}
}
|
以上都是以5.21版本的包為例。由第一張圖可以看出兩點:(一)目前activiti支援的資料庫型別有:db2、h2、hsql、mssql、mysql、oracle和postgres資料庫。(二)activiti的資料庫表核心在於engine,identity和history是分離了出來。根據官方指導手冊的說法,activiti的history功能是可以選擇是否開啟的,如果不需要自然不用history相關的表,而identity和使用者以及使用者組相關的表也是不一定需要的,可以使用自己的使用者結構表(具體怎麼做還沒有嘗試)。
初始化資料庫的程式碼很簡單,其實際上就是使用配置檔案建立了一個工作流引擎,只是將配置項中的databaseSchemaUpdate改成了create,這句就是建立資料庫的含義。下面詳細說一下具體操作步驟,本次操作是基於maven的,不會的需要自己手動匯入包,使用maven也是為了不用下載依賴包。資料庫使用的是mysql。開發工具用的eclipse。
主要步驟有四步:
1.新增activiti-engine.jar包以及其依賴包到構建路徑
2.新增mysql-connector-java包,mysql資料庫的驅動包
3.編寫activiti.cfg.xml配置檔案,將其放入classpath下,maven專案就是src/main/resources下就行了。
4.執行DbSchemaCreate的main方法
下面是相關操作:
1.新建一個maven專案,這個就不講了。在pom.xml中新增activiti-engine依賴:
1 2 3 4 5 |
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>
5.21 . 0
</version>
</dependency>
|
2.新增mysql資料庫驅動依賴
1 2 3 4 5 |
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>
5.1 . 38
</version>
</dependency>
|
3.在src/main/resources下新建一個檔案,命名為activiti.cfg.xml(不能是其它的名字)。在裡面配置以下內容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:
//www.springframework.org/schema/beans
http:
//www.springframework.org/schema/beans/spring-beans.xsd">
<bean id=
"processEngineConfiguration"
class
=
"org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"
>
<property name=
"databaseType"
value=
"mysql"
></property> <!-- 資料庫型別,最好配置一下 -->
<property name=
"jdbcUrl"
value=
"jdbc:mysql://localhost:3306/activiti"
></property> <!-- 資料庫URL,我放在名為activiti資料庫中 -->
<property name=
"jdbcDriver"
value=
"com.mysql.jdbc.Driver"
></property> <!-- 資料庫驅動類 mysql是這個,其它的資料庫修改一下即可 -->
<property name=
"jdbcUsername"
value=
"root"
></property> <!-- 連線資料庫的賬號 -->
<property name=
"jdbcPassword"
value=
"root"
></property> <!-- 連線資料庫的密碼 -->
<!-- <property name=
"databaseSchema"
value=
"activiti"
></property> --> <!-- 這個屬性可能會用到,後面會進行說明 -->
</bean>
</beans>
|
裡面的相關配置databaseType,jdbcUrl等5個配置項,改成自己的相符合的就行了。
4.eclipse中選中專案,右擊選擇Run As->Java Application,在彈出的框Select type中輸入DBSchemaCreate,選擇Matching items中相應的類,點選OK即可,如圖:
如果沒什麼問題,用工具檢視資料庫,應該是能夠看到自動創建出來的25張表的。
但是有的時候會出現一些問題。oracle資料庫中,如果存在一個使用者建了這些表,而我使用另一個使用者建這些表會失敗。或者是建好表後,將使用者刪除,再重新建立這個使用者,一樣會導致建立表失敗,提示:表或檢視不存在。這個問題的產生與程式執行和oracle資料庫的機制有關。
首先看程式,啟動專案後會驗證一次資料庫的表結構版本和當前jar包版本是否匹配,這個流程是為了校驗而已。而在初始化資料庫的時候一般不會執行這個校驗,但是當錯誤的判定資料庫的表存在時,會錯誤的進入校驗資料庫表結構版本的分支之中,導致原本資料庫還沒有初始化表,卻去查詢表act_ge_property(存放了版本資訊),自然而然地報了表或檢視不存在了。問題在於為什麼明明表不存在,卻判定表示存在的。
檢視異常鏈追蹤原始碼會發現其實際上判斷的是表act_ru_execution是否存在。其從DbSqlSession的dbSchemaCreate()方法開始:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public void
dbSchemaCreate() {
if
(isEngineTablePresent()) {
String dbVersion = getDbVersion();
if
(!ProcessEngine.VERSION.equals(dbVersion)) {
throw
new
ActivitiWrongDbException(ProcessEngine.VERSION, dbVersion);
}
}
else
{
dbSchemaCreateEngine();
}
if
(dbSqlSessionFactory.isDbHistoryUsed()) {
dbSchemaCreateHistory();
}
if
(dbSqlSessionFactory.isDbIdentityUsed()) {
dbSchemaCreateIdentity();
}
}
|
這段程式碼很清楚地展示了相關關係,先判斷表是否存在,存在就驗證版本號,不存在就建立engine,後面判斷history和identity是否被使用(預設使用),使用了就建立相關的表。這裡很明顯就是isEngineTablePresent()返回了true才導致了這個問題,繼續追蹤到這個類中的isTablePresent()方法,其真正作用的是下面這段:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public static
String[] JDBC_METADATA_TABLE_TYPES = {
"TABLE"
};
try
{
tables = databaseMetaData.getTables(catalog, schema, tableName, JDBC_METADATA_TABLE_TYPES);
return
tables.next();
}
finally
{
try
{
tables.close();
}
catch
(Exception e) {
log.error(
"Error closing meta data tables"
, e);
}
}
|
tables.next()返回了true,那麼問題肯定是出在了databaseMetaData.getTables()這條語句上。斷點發現前兩個引數都是null,tableName就是驗證的表act_ru_execution。最後一個上面以給出,就是字串陣列,裡面只有一個“TABLE”字串。這個方法具體出在第二個引數上面。具體的引數含義可以百度,這裡提供一個連結(勿刪):http://blog.sina.com.cn/s/blog_707a9f0601014y1a.html
第二個引數對於oracle資料庫來說比較重要,就像之前說的造成這個問題的兩種可能的場景。如果出現了這個問題,就需要配置,使schema這個引數為大寫的登陸使用者名稱(必須大寫,與oracle的機制有關)。這個引數的設定,不斷向上查詢原始碼,會發現只需要在配置檔案中配置databaseSchema屬性就可以了(value大寫)。mysql資料庫應該就沒有太大問題了。
最後簡單介紹一下activiti資料庫表的組成。之前看建立資料庫的sql語句就很清楚,表分為必要的engine和非必要的history以及identity。
其中act_hi_*這8張表就與history相關。act_id_*這4張與identity有關。剩餘的全是engine必備的表,也可以簡單的分下類:act_ru_*這6張表是runtime流程執行中相關的表。act_re_*這3張表是repository這個是管理部署和流程定義相關的表,基本不會改變,除非更改部署和流程定義。act_ge_property存放了資料庫表版本的相關資訊,只有在升級版本的時候會改變。act_ge_bytearray存放了一些位元組流資料,一般是各種資源資料如流程定義的xml,流程圖等。act_evt_log看名字就知道是事件日誌的表,如何使用暫時不知。最後一張act_procdef_info表看名字也就是流程定義詳情表。那些歸類了得表具體作用看*,其後綴的名字,大概就知道其具體作用,如:task(任務)、variable(變數)等,這裡就不一一介紹了。