From 00b2f6312d50793c5d7d74096b0f5f034f2ac187 Mon Sep 17 00:00:00 2001 From: chenbowen Date: Thu, 27 Nov 2025 16:01:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20flowable=20=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E9=80=9A=E8=BF=87=20dm=20=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E6=AD=A3=E5=B8=B8=E8=8E=B7=E5=8F=96=20schema?= =?UTF-8?q?=20=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../engine/impl/db/DbSqlSessionFactory.java | 354 ++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 zt-module-bpm/zt-module-bpm-server/src/main/java/org/flowable/common/engine/impl/db/DbSqlSessionFactory.java diff --git a/zt-module-bpm/zt-module-bpm-server/src/main/java/org/flowable/common/engine/impl/db/DbSqlSessionFactory.java b/zt-module-bpm/zt-module-bpm-server/src/main/java/org/flowable/common/engine/impl/db/DbSqlSessionFactory.java new file mode 100644 index 00000000..ed2f0c94 --- /dev/null +++ b/zt-module-bpm/zt-module-bpm-server/src/main/java/org/flowable/common/engine/impl/db/DbSqlSessionFactory.java @@ -0,0 +1,354 @@ +/* Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.flowable.common.engine.impl.db; + +import org.apache.ibatis.session.SqlSessionFactory; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.impl.context.Context; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.common.engine.impl.interceptor.Session; +import org.flowable.common.engine.impl.interceptor.SessionFactory; +import org.flowable.common.engine.impl.persistence.cache.EntityCache; +import org.flowable.common.engine.impl.persistence.entity.Entity; + +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author Tom Baeyens + * @author Joram Barrez + */ +public class DbSqlSessionFactory implements SessionFactory { + + protected Map> databaseSpecificStatements = new HashMap<>(); + + protected String databaseType; + protected String databaseTablePrefix = ""; + protected boolean tablePrefixIsSchema; + + protected String databaseCatalog; + protected String databaseSchema; + protected SqlSessionFactory sqlSessionFactory; + protected Map statementMappings; + + protected Map, String> insertStatements = new ConcurrentHashMap<>(); + protected Map, String> updateStatements = new ConcurrentHashMap<>(); + protected Map, String> deleteStatements = new ConcurrentHashMap<>(); + protected Map, String> selectStatements = new ConcurrentHashMap<>(); + + protected List> insertionOrder = new ArrayList<>(); + protected List> deletionOrder = new ArrayList<>(); + + protected boolean isDbHistoryUsed = true; + + protected Set> bulkInserteableEntityClasses = new HashSet<>(); + protected Map, String> bulkInsertStatements = new ConcurrentHashMap<>(); + + protected int maxNrOfStatementsInBulkInsert = 100; + + protected Map> logicalNameToClassMapping = new ConcurrentHashMap<>(); + + protected boolean usePrefixId; + + public DbSqlSessionFactory(boolean usePrefixId) { + this.usePrefixId = usePrefixId; + } + + @Override + public Class getSessionType() { + return DbSqlSession.class; + } + + @Override + public Session openSession(CommandContext commandContext) { + DbSqlSession dbSqlSession = createDbSqlSession(); + // 当前系统适配 dm,如果存在 schema 为空的情况,从 connection 获取 + try { + if (getDatabaseSchema() == null || getDatabaseSchema().length() == 0){ + setDatabaseSchema(dbSqlSession.getSqlSession().getConnection().getSchema()); + } + dbSqlSession.getSqlSession().getConnection().getSchema(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + + if (getDatabaseSchema() != null && getDatabaseSchema().length() > 0) { + try { + dbSqlSession.getSqlSession().getConnection().setSchema(getDatabaseSchema()); + } catch (SQLException e) { + throw new FlowableException("Could not set database schema on connection", e); + } + } + if (getDatabaseCatalog() != null && getDatabaseCatalog().length() > 0) { + try { + dbSqlSession.getSqlSession().getConnection().setCatalog(getDatabaseCatalog()); + } catch (SQLException e) { + throw new FlowableException("Could not set database catalog on connection", e); + } + } + if (dbSqlSession.getSqlSession().getConnection() == null) { + throw new FlowableException("Invalid dbSqlSession: no active connection found"); + } + return dbSqlSession; + } + + protected DbSqlSession createDbSqlSession() { + return new DbSqlSession(this, Context.getCommandContext().getSession(EntityCache.class)); + } + + // insert, update and delete statements + // ///////////////////////////////////// + + public String getInsertStatement(Entity object) { + return getStatement(object.getClass(), insertStatements, "insert"); + } + + public String getInsertStatement(Class clazz) { + return getStatement(clazz, insertStatements, "insert"); + } + + public String getUpdateStatement(Entity object) { + return getStatement(object.getClass(), updateStatements, "update"); + } + + public String getDeleteStatement(Class entityClass) { + return getStatement(entityClass, deleteStatements, "delete"); + } + + public String getSelectStatement(Class entityClass) { + return getStatement(entityClass, selectStatements, "select"); + } + + protected String getStatement(Class entityClass, Map, String> cachedStatements, String prefix) { + String statement = cachedStatements.get(entityClass); + if (statement != null) { + return statement; + } + statement = prefix + entityClass.getSimpleName(); + if (statement.endsWith("Impl")) { + statement = statement.substring(0, statement.length() - 10); // removing 'entityImpl' + } else { + statement = statement.substring(0, statement.length() - 6); // removing 'entity' + } + cachedStatements.put(entityClass, statement); + return statement; + } + + // db specific mappings + // ///////////////////////////////////////////////////// + + protected void addDatabaseSpecificStatement(String databaseType, String activitiStatement, String ibatisStatement) { + Map specificStatements = databaseSpecificStatements.get(databaseType); + if (specificStatements == null) { + specificStatements = new HashMap<>(); + databaseSpecificStatements.put(databaseType, specificStatements); + } + specificStatements.put(activitiStatement, ibatisStatement); + } + + public String mapStatement(String statement) { + if (statementMappings == null) { + return statement; + } + String mappedStatement = statementMappings.get(statement); + return (mappedStatement != null ? mappedStatement : statement); + } + + // customized getters and setters + // /////////////////////////////////////////// + + public void setDatabaseType(String databaseType) { + this.databaseType = databaseType; + this.statementMappings = databaseSpecificStatements.get(databaseType); + } + + public boolean isMysql() { + return "mysql".equals(getDatabaseType()); + } + + public boolean isOracle() { + return "oracle".equals(getDatabaseType()); + } + + public Boolean isBulkInsertable(Class entityClass) { + return bulkInserteableEntityClasses != null && bulkInserteableEntityClasses.contains(entityClass); + } + + @SuppressWarnings("rawtypes") + public String getBulkInsertStatement(Class clazz) { + return getStatement(clazz, bulkInsertStatements, "bulkInsert"); + } + + public Set> getBulkInserteableEntityClasses() { + return bulkInserteableEntityClasses; + } + + public void setBulkInserteableEntityClasses(Set> bulkInserteableEntityClasses) { + this.bulkInserteableEntityClasses = bulkInserteableEntityClasses; + } + + public int getMaxNrOfStatementsInBulkInsert() { + return maxNrOfStatementsInBulkInsert; + } + + public void setMaxNrOfStatementsInBulkInsert(int maxNrOfStatementsInBulkInsert) { + this.maxNrOfStatementsInBulkInsert = maxNrOfStatementsInBulkInsert; + } + + public Map, String> getBulkInsertStatements() { + return bulkInsertStatements; + } + + public void setBulkInsertStatements(Map, String> bulkInsertStatements) { + this.bulkInsertStatements = bulkInsertStatements; + } + + // getters and setters ////////////////////////////////////////////////////// + + public SqlSessionFactory getSqlSessionFactory() { + return sqlSessionFactory; + } + + public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { + this.sqlSessionFactory = sqlSessionFactory; + } + + public String getDatabaseType() { + return databaseType; + } + + public Map> getDatabaseSpecificStatements() { + return databaseSpecificStatements; + } + + public void setDatabaseSpecificStatements(Map> databaseSpecificStatements) { + this.databaseSpecificStatements = databaseSpecificStatements; + } + + public Map getStatementMappings() { + return statementMappings; + } + + public void setStatementMappings(Map statementMappings) { + this.statementMappings = statementMappings; + } + + public Map, String> getInsertStatements() { + return insertStatements; + } + + public void setInsertStatements(Map, String> insertStatements) { + this.insertStatements = insertStatements; + } + + public Map, String> getUpdateStatements() { + return updateStatements; + } + + public void setUpdateStatements(Map, String> updateStatements) { + this.updateStatements = updateStatements; + } + + public Map, String> getDeleteStatements() { + return deleteStatements; + } + + public void setDeleteStatements(Map, String> deleteStatements) { + this.deleteStatements = deleteStatements; + } + + public Map, String> getSelectStatements() { + return selectStatements; + } + + public void setSelectStatements(Map, String> selectStatements) { + this.selectStatements = selectStatements; + } + + public boolean isDbHistoryUsed() { + return isDbHistoryUsed; + } + + public void setDbHistoryUsed(boolean isDbHistoryUsed) { + this.isDbHistoryUsed = isDbHistoryUsed; + } + + public void setDatabaseTablePrefix(String databaseTablePrefix) { + this.databaseTablePrefix = databaseTablePrefix; + } + + public String getDatabaseTablePrefix() { + return databaseTablePrefix; + } + + public String getDatabaseCatalog() { + return databaseCatalog; + } + + public void setDatabaseCatalog(String databaseCatalog) { + this.databaseCatalog = databaseCatalog; + } + + public String getDatabaseSchema() { + return databaseSchema; + } + + public void setDatabaseSchema(String databaseSchema) { + this.databaseSchema = databaseSchema; + } + + public void setTablePrefixIsSchema(boolean tablePrefixIsSchema) { + this.tablePrefixIsSchema = tablePrefixIsSchema; + } + + public boolean isTablePrefixIsSchema() { + return tablePrefixIsSchema; + } + + public List> getInsertionOrder() { + return insertionOrder; + } + + public void setInsertionOrder(List> insertionOrder) { + this.insertionOrder = insertionOrder; + } + + public List> getDeletionOrder() { + return deletionOrder; + } + + public void setDeletionOrder(List> deletionOrder) { + this.deletionOrder = deletionOrder; + } + public void addLogicalEntityClassMapping(String logicalName, Class entityClass) { + logicalNameToClassMapping.put(logicalName, entityClass); + } + + public Map> getLogicalNameToClassMapping() { + return logicalNameToClassMapping; + } + + public void setLogicalNameToClassMapping(Map> logicalNameToClassMapping) { + this.logicalNameToClassMapping = logicalNameToClassMapping; + } + + public boolean isUsePrefixId() { + return usePrefixId; + } + + public void setUsePrefixId(boolean usePrefixId) { + this.usePrefixId = usePrefixId; + } +}