zoukankan      html  css  js  c++  java
  • activiti搭建(一)初始化数据库

      转载请注明源地址:http://www.cnblogs.com/lighten/p/5876681.html

      activiti-engine.jar包中自带了创建activiti工作流数据库表的SQL语句和自动初始化数据库的方法。SQL语句在org.activiti.db.create包下,初始化方法在org.activiti.engine.impl.db.DbSchemaCreate的main方法之中。

    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依赖:

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

  • 相关阅读:
    POJ3159 Candies —— 差分约束 spfa
    POJ1511 Invitation Cards —— 最短路spfa
    POJ1860 Currency Exchange —— spfa求正环
    POJ3259 Wormholes —— spfa求负环
    POJ3660 Cow Contest —— Floyd 传递闭包
    POJ3268 Silver Cow Party —— 最短路
    POJ1797 Heavy Transportation —— 最短路变形
    POJ2253 Frogger —— 最短路变形
    POJ1759 Garland —— 二分
    POJ3685 Matrix —— 二分
  • 原文地址:https://www.cnblogs.com/lighten/p/5876681.html
Copyright © 2011-2022 走看看