activiti搭建(一)初始化數據庫

  轉載請註明源地址:http://www.cnblogs.com/lighten/p/5876681.htmlhtml

  activiti-engine.jar包中自帶了建立activiti工做流數據庫表的SQL語句和自動初始化數據庫的方法。SQL語句在org.activiti.db.create包下,初始化方法在org.activiti.engine.impl.db.DbSchemaCreate的main方法之中。java

public class DbSchemaCreate {

  public static void main(String[] args) {
    ProcessEngineConfiguration
      .createProcessEngineConfigurationFromResourceDefault()
      .setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_CREATE)
      .buildProcessEngine();
  }

}

  以上都是以5.21版本的包爲例。由第一張圖能夠看出兩點:(一)目前activiti支持的數據庫類型有:db二、h二、hsql、mssql、mysql、oracle和postgres數據庫。(二)activiti的數據庫表核心在於engine,identity和history是分離了出來。根據官方指導手冊的說法,activiti的history功能是能夠選擇是否開啓的,若是不須要天然不用history相關的表,而identity和用戶以及用戶組相關的表也是不必定須要的,可使用本身的用戶結構表(具體怎麼作尚未嘗試)。mysql

  初始化數據庫的代碼很簡單,其實際上就是使用配置文件建立了一個工做流引擎,只是將配置項中的databaseSchemaUpdate改爲了create,這句就是建立數據庫的含義。下面詳細說一下具體操做步驟,本次操做是基於maven的,不會的須要本身手動導入包,使用maven也是爲了避免用下載依賴包。數據庫使用的是mysql。開發工具用的eclipse。spring

  主要步驟有四步:sql

  1.添加activiti-engine.jar包以及其依賴包到構建路徑數據庫

  2.添加mysql-connector-java包,mysql數據庫的驅動包數組

  3.編寫activiti.cfg.xml配置文件,將其放入classpath下,maven項目就是src/main/resources下就好了。oracle

  4.運行DbSchemaCreate的main方法eclipse

  下面是相關操做:maven

  1.新建一個maven項目,這個就不講了。在pom.xml中添加activiti-engine依賴:

		<dependency>
			<groupId>org.activiti</groupId>
			<artifactId>activiti-engine</artifactId>
			<version>5.21.0</version>
		</dependency>

  2.添加mysql數據庫驅動依賴

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.38</version>
		</dependency>

  3.在src/main/resources下新建一個文件,命名爲activiti.cfg.xml(不能是其它的名字)。在裏面配置如下內容:

<?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()方法開始:

  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()方法,其真正做用的是下面這段:

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(變量)等,這裏就不一一介紹了。

相關文章
相關標籤/搜索