activiti创建数据表源码解析

本文详细剖析了Activiti 7中创建数据库表的源码流程,从配置文件到执行SQL脚本,涉及Spring配置、ProcessEngine实例化和SchemaOperations过程。重点展示了如何根据`databaseSchemaUpdate`设置执行不同操作,如drop-create、create-drop等。

activiti创建数据表源码解析

     activiti7那段代码创建数据表的?从源码开始分析。

执行过程

      

ProcessEngineConfigurationImpl config = (ProcessEngineConfigurationImpl) ProcessEngineConfiguration
            .createProcessEngineConfigurationFromResource("org/activiti/engine/test/db/connection-mysql-pool.activiti.cfg.xml");

        config.buildProcessEngine();

 

初始化流程引擎,后台使用Mysql数据库,配置文件如下

<?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.StandaloneInMemProcessEngineConfiguration">
  
    <!-- Database configurations -->
<!--    <property name="databaseSchemaUpdate" value="true" />-->

    <property name="jdbcMaxActiveConnections" value="25" />
    <property name="jdbcMaxIdleConnections" value="10" />
    <property name="jdbcMaxCheckoutTime" value="30000" />
    <property name="jdbcMaxWaitTime" value="25000" />
    
    <!-- job executor configurations -->
    <property name="asyncExecutorActivate" value="false" />

    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti_7?serverTimezone=UTC" />
    <property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" />
    <property name="jdbcUsername" value="root" />
    <property name="jdbcPassword" value="shootercheng" />

    <!-- Database configurations -->
    <property name="databaseSchemaUpdate" value="drop-create" />
    
  </bean>

</beans>
public ProcessEngine buildProcessEngine() {
    init();
    ProcessEngineImpl processEngine = new ProcessEngineImpl(this);
    postProcessEngineInitialisation();

    return processEngine;
  }

创建数据库代码在  ProcessEngineImpl processEngine = new ProcessEngineImpl(this); 这一句里面执行

if (processEngineConfiguration.isUsingRelationalDatabase() && processEngineConfiguration.getDatabaseSchemaUpdate() != null) {
      commandExecutor.execute(processEngineConfiguration.getSchemaCommandConfig(), new SchemaOperationsProcessEngineBuild());
    }
public final class SchemaOperationsProcessEngineBuild implements Command<Object> {

  public Object execute(CommandContext commandContext) {
    DbSqlSession dbSqlSession = commandContext.getDbSqlSession();
    if (dbSqlSession != null) {
      dbSqlSession.performSchemaOperationsProcessEngineBuild();
    }
    return null;
  }
}

执行sql文件的类是  DbSqlSession.java

public void performSchemaOperationsProcessEngineBuild() {
        String databaseSchemaUpdate = Context.getProcessEngineConfiguration().getDatabaseSchemaUpdate();
        log.debug("Executing performSchemaOperationsProcessEngineBuild with setting " + databaseSchemaUpdate);
        if (ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_DROP_CREATE.equals(databaseSchemaUpdate)) {
            try {
                dbSchemaDrop();
            } catch (RuntimeException e) {
                // ignore
            }
        }
        if (org.activiti.engine.ProcessEngineConfiguration.DB_SCHEMA_UPDATE_CREATE_DROP.equals(databaseSchemaUpdate)
                || ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_DROP_CREATE.equals(databaseSchemaUpdate) || ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_CREATE.equals(databaseSchemaUpdate)) {
            dbSchemaCreate();
        } else if (org.activiti.engine.ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE.equals(databaseSchemaUpdate)) {
            dbSchemaCheckVersion();
        } else if (ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE.equals(databaseSchemaUpdate)) {
            dbSchemaUpdate();
        }
    }

根据不同的配置走不同的逻辑 读取之前初始化 xml 的  <property name="databaseSchemaUpdate" value="drop-create" />

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();
        }
    }

dbSchemaCreateEngine() 开始走创建数据表逻辑了

protected void dbSchemaCreateEngine() {
        executeMandatorySchemaResource("create",
                                       "engine");
    }
public String getResourceForDbOperation(String directory,
                                            String operation,
                                            String component) {
        String databaseType = dbSqlSessionFactory.getDatabaseType();
        return "org/activiti/db/" + directory + "/activiti." + databaseType + "." + operation + "." + component + ".sql";
    }




public void executeSchemaResource(String operation,
                                      String component,
                                      String resourceName,
                                      boolean isOptional) {
        InputStream inputStream = null;
        try {
            inputStream = ReflectUtil.getResourceAsStream(resourceName);
            if (inputStream == null) {
                if (isOptional) {
                    log.info("no schema resource {} for {}",
                             resourceName,
                             operation);
                } else {
                    throw new ActivitiException("resource '" + resourceName + "' is not available");
                }
            } else {
                executeSchemaResource(operation,
                                      component,
                                      resourceName,
                                      inputStream);
            }
        } finally {
            IoUtil.closeSilently(inputStream);
        }
    }

读取测试resources里面的sql文件  activiti.mysql.create.engine.sql

private void executeSchemaResource(String operation,
                                       String component,
                                       String resourceName,
                                       InputStream inputStream) {
        log.info("performing {} on {} with resource {}",
                 operation,
                 component,
                 resourceName);
        String sqlStatement = null;
        String exceptionSqlStatement = null;
        try {
            Connection connection = sqlSession.getConnection();
            Exception exception = null;
            byte[] bytes = IoUtil.readInputStream(inputStream,
                                                  resourceName);
            String ddlStatements = new String(bytes);

            // Special DDL handling for certain databases
            try {
                if (isMysql()) {
                    DatabaseMetaData databaseMetaData = connection.getMetaData();
                    int majorVersion = databaseMetaData.getDatabaseMajorVersion();
                    int minorVersion = databaseMetaData.getDatabaseMinorVersion();
                    log.info("Found MySQL: majorVersion=" + majorVersion + " minorVersion=" + minorVersion);

                    // Special care for MySQL < 5.6
                    if (majorVersion <= 5 && minorVersion < 6) {
                        ddlStatements = updateDdlForMySqlVersionLowerThan56(ddlStatements);
                    }
                }
            } catch (Exception e) {
                log.info("Could not get database metadata",
                         e);
            }

            BufferedReader reader = new BufferedReader(new StringReader(ddlStatements));
            String line = readNextTrimmedLine(reader);
            boolean inOraclePlsqlBlock = false;
            while (line != null) {
                if (line.startsWith("# ")) {
                    log.debug(line.substring(2));
                } else if (line.startsWith("-- ")) {
                    log.debug(line.substring(3));
                } else if (line.startsWith("execute java ")) {
                    String upgradestepClassName = line.substring(13).trim();
                    DbUpgradeStep dbUpgradeStep = null;
                    try {
                        dbUpgradeStep = (DbUpgradeStep) ReflectUtil.instantiate(upgradestepClassName);
                    } catch (ActivitiException e) {
                        throw new ActivitiException("database update java class '" + upgradestepClassName + "' can't be instantiated: " + e.getMessage(),
                                                    e);
                    }
                    try {
                        log.debug("executing upgrade step java class {}",
                                  upgradestepClassName);
                        dbUpgradeStep.execute(this);
                    } catch (Exception e) {
                        throw new ActivitiException("error while executing database update java class '" + upgradestepClassName + "': " + e.getMessage(),
                                                    e);
                    }
                } else if (line.length() > 0) {

                    if (isOracle() && line.startsWith("begin")) {
                        inOraclePlsqlBlock = true;
                        sqlStatement = addSqlStatementPiece(sqlStatement,
                                                            line);
                    } else if ((line.endsWith(";") && !inOraclePlsqlBlock) || (line.startsWith("/") && inOraclePlsqlBlock)) {

                        if (inOraclePlsqlBlock) {
                            inOraclePlsqlBlock = false;
                        } else {
                            sqlStatement = addSqlStatementPiece(sqlStatement,
                                                                line.substring(0,
                                                                               line.length() - 1));
                        }

                        Statement jdbcStatement = connection.createStatement();
                        try {
                            // no logging needed as the connection will log it
                            log.debug("SQL: {}",
                                      sqlStatement);
                            jdbcStatement.execute(sqlStatement);
                            jdbcStatement.close();
                        } catch (Exception e) {
                            if (exception == null) {
                                exception = e;
                                exceptionSqlStatement = sqlStatement;
                            }
                            log.error("problem during schema {}, statement {}",
                                      operation,
                                      sqlStatement,
                                      e);
                        } finally {
                            sqlStatement = null;
                        }
                    } else {
                        sqlStatement = addSqlStatementPiece(sqlStatement,
                                                            line);
                    }
                }

                line = readNextTrimmedLine(reader);
            }

            if (exception != null) {
                throw exception;
            }

            log.debug("activiti db schema {} for component {} successful",
                      operation,
                      component);
        } catch (Exception e) {
            throw new ActivitiException("couldn't " + operation + " db schema: " + exceptionSqlStatement,
                                        e);
        }
    }

执行sql

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chengdu.S

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值