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(变量)等,这里就不一一介绍了。

相关文章
相关标签/搜索