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

被折叠的 条评论
为什么被折叠?



