当前位置:   article > 正文

RuoYi 集成flowable 6.7.0+flowable-modeler_ruoyi flowable

ruoyi flowable
  1. 集成flowable

1.1导入maven依赖

  1. <flowable.version>6.7.0</flowable.version>
  2. <!--flowable 主依赖-->
  3. <dependency>
  4. <groupId>org.flowable</groupId>
  5. <artifactId>flowable-spring-boot-starter</artifactId>
  6. <version>${flowable.version}</version>
  7. </dependency>
  1. 集成flowable-modeler

2.1 maven依赖

  1. <!-- flowable 集成依赖conf ,包内包含 rest,logic -->
  2. <dependency>
  3. <groupId>org.flowable</groupId>
  4. <artifactId>flowable-ui-modeler-conf</artifactId>
  5. <version>${flowable.version}</version>
  6. <exclusions>
  7. <exclusion>
  8. <groupId>org.mybatis</groupId>
  9. <artifactId>mybatis</artifactId>
  10. </exclusion>
  11. <exclusion>
  12. <groupId>org.mybatis</groupId>
  13. <artifactId>mybatis-spring</artifactId>
  14. </exclusion>
  15. </exclusions>
  16. </dependency>

前端下载

地址:GitHub - flowable/flowable-engine: A compact and highly efficient workflow and Business Process Management (BPM) platform for developers, system admins and business users.

直接将github上flowable-engine项目(GitHub - flowable/flowable-engine: A compact and highly efficient workflow and Business Process Management (BPM) platform for developers, system admins and business users.)version 6.7.0 (分支 origin/flowable-release-6.7.0)的前端代码拷贝到自己项目中,路径保持相同:flowable-engine-6.7.0\modules\flowable-ui-modeler\flowable-ui-modeler-app\src\main\resources

2.2 flowable的yml配置

  1. flowable:
  2. # 关闭异步,不关闭历史数据的插入就是异步的,会在同一个事物里面,无法回滚
  3. # 开发可开启会提高些效率,上线需要关闭
  4. database-schema-update: true
  5. process-definition-location-prefix: classpath*:/processes/
  6. process-definition-location-suffixes: "**.bpmn20.xml, **.bpmn"
  7. common:
  8. app:
  9. idm-url: http://localhost:${server.port}/flowable-idm1
  10. idm-admin:
  11. user: admin
  12. password: test
  13. #解决乱码问题
  14. activity-font-name: 宋体
  15. label-font-name: 宋体
  16. annotation-font-name: 宋体
  17. #关闭定时任务JOB
  18. async-executor-activate: false

2.3路径重定向配置

(用于路径跳转直接可免去index.html)

  1. @Override
  2. public void addViewControllers(ViewControllerRegistry registry) {
  3. registry.addViewController("/").setViewName("forward:" + indexUrl);
  4. registry.addViewController("/modeler").setViewName("forward:/modeler/index.html");
  5. }

2.4免登录配置

类名随意定,如FlowableSecurityConfiguration.class,包路径与flowable相同:org.flowable.ui.modeler.conf

  1. import org.flowable.ui.common.security.SecurityConstants;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.core.annotation.Order;
  4. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  5. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  6. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  7. @Configuration(proxyBeanMethods = false)
  8. @EnableWebSecurity
  9. public class FlowableSecurityConfiguration {
  10. @Configuration
  11. @Order(SecurityConstants.TASK_API_SECURITY_ORDER)
  12. public static class ModelerApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
  13. @Override
  14. protected void configure(HttpSecurity http) throws Exception {
  15. http
  16. //必须要将csrf设置为disable,不然后面发送POST请求时会报403错误
  17. .csrf().disable()
  18. //为了简单起见,简单粗暴方式直接放行modeler下面所有请求
  19. .authorizeRequests().antMatchers("/modeler/**").permitAll();
  20. //解决iframe无法访问问题
  21. http.csrf().disable().headers().frameOptions().sameOrigin();
  22. }
  23. }
  24. }

2.5 数据库链接配置

类名随意定,如DatabaseConfiguration.class

  1. import liquibase.Liquibase;
  2. import liquibase.database.Database;
  3. import liquibase.database.DatabaseConnection;
  4. import liquibase.database.DatabaseFactory;
  5. import liquibase.database.jvm.JdbcConnection;
  6. import liquibase.exception.DatabaseException;
  7. import liquibase.resource.ClassLoaderResourceAccessor;
  8. import org.apache.ibatis.session.SqlSessionFactory;
  9. import org.flowable.common.engine.api.FlowableException;
  10. import org.flowable.ui.common.service.exception.InternalServerErrorException;
  11. import org.flowable.ui.common.util.LiquibaseUtil;
  12. import org.flowable.ui.modeler.properties.FlowableModelerAppProperties;
  13. import org.mybatis.spring.SqlSessionFactoryBean;
  14. import org.mybatis.spring.SqlSessionTemplate;
  15. import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
  16. import org.slf4j.Logger;
  17. import org.slf4j.LoggerFactory;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import org.springframework.beans.factory.annotation.Qualifier;
  20. import org.springframework.context.annotation.Bean;
  21. import org.springframework.context.annotation.Configuration;
  22. import org.springframework.context.annotation.Primary;
  23. import org.springframework.core.io.Resource;
  24. import org.springframework.core.io.ResourceLoader;
  25. import org.springframework.core.io.support.ResourcePatternResolver;
  26. import org.springframework.core.io.support.ResourcePatternUtils;
  27. import javax.sql.DataSource;
  28. import java.sql.Connection;
  29. import java.sql.DatabaseMetaData;
  30. import java.sql.SQLException;
  31. import java.util.ArrayList;
  32. import java.util.Arrays;
  33. import java.util.List;
  34. import java.util.Properties;
  35. @Configuration
  36. public class DatabaseConfiguration {
  37. private static final Logger LOGGER = LoggerFactory.getLogger(ModelerDatabaseConfiguration.class);
  38. protected static final String LIQUIBASE_CHANGELOG_PREFIX = "ACT_DE_";
  39. @Autowired
  40. protected FlowableModelerAppProperties modelerAppProperties;
  41. @Autowired
  42. protected MybatisProperties mybatisProperties;
  43. @Autowired
  44. protected ResourceLoader resourceLoader;
  45. protected static Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();
  46. public static final String DATABASE_TYPE_H2 = "h2";
  47. public static final String DATABASE_TYPE_HSQL = "hsql";
  48. public static final String DATABASE_TYPE_MYSQL = "mysql";
  49. public static final String DATABASE_TYPE_ORACLE = "oracle";
  50. public static final String DATABASE_TYPE_POSTGRES = "postgres";
  51. public static final String DATABASE_TYPE_MSSQL = "mssql";
  52. public static final String DATABASE_TYPE_DB2 = "db2";
  53. public static Properties getDefaultDatabaseTypeMappings() {
  54. Properties databaseTypeMappings = new Properties();
  55. databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
  56. databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL);
  57. databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
  58. databaseTypeMappings.setProperty("MariaDB", DATABASE_TYPE_MYSQL);
  59. databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
  60. databaseTypeMappings.setProperty("PostgreSQL", DATABASE_TYPE_POSTGRES);
  61. databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
  62. databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
  63. databaseTypeMappings.setProperty("DB2", DATABASE_TYPE_DB2);
  64. databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
  65. databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
  66. databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
  67. databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
  68. databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
  69. databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
  70. databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
  71. databaseTypeMappings.setProperty("DB2/LINUXPPC64", DATABASE_TYPE_DB2);
  72. databaseTypeMappings.setProperty("DB2/LINUXPPC64LE", DATABASE_TYPE_DB2);
  73. databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
  74. databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
  75. databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
  76. databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
  77. databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
  78. databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
  79. databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
  80. databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
  81. databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
  82. databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
  83. databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
  84. return databaseTypeMappings;
  85. }
  86. @Bean
  87. @Qualifier("flowableModeler")
  88. @Primary
  89. public SqlSessionFactory modelerSqlSessionFactory(DataSource dataSource) {
  90. SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  91. sqlSessionFactoryBean.setDataSource(dataSource);
  92. String databaseType = initDatabaseType(dataSource);
  93. if (databaseType == null) {
  94. throw new FlowableException("couldn't deduct database type");
  95. }
  96. try {
  97. Properties properties = new Properties();
  98. properties.put("prefix", modelerAppProperties.getDataSourcePrefix());
  99. properties.put("blobType", "BLOB");
  100. properties.put("boolValue", "TRUE");
  101. properties.load(this.getClass().getClassLoader().getResourceAsStream("org/flowable/db/properties/" + databaseType + ".properties"));
  102. sqlSessionFactoryBean.setConfigurationProperties(properties);
  103. //这个是原始代码,只添加flowable的扫描路径
  104. // sqlSessionFactoryBean
  105. // .setMapperLocations(ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources("classpath:/META-INF/modeler-mybatis-mappings/*.xml"));
  106. //由于后面要设置该SqlSessionFactory为主要的SqlSessionFactory,
  107. // 然后Ruoyi中使用时Mybatis自动注入,所以在这个地方就需要添加Ruoyi配置扫描
  108. ResourcePatternResolver resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
  109. List<Resource> allResourceList = new ArrayList<>();
  110. List<String> mapperLocations = new ArrayList<>();
  111. //先添加
  112. mapperLocations.add("classpath:/META-INF/modeler-mybatis-mappings/*.xml");
  113. mapperLocations.add("classpath*:/mapper/**/*Mapper.xml");
  114. mapperLocations.add("mapper/*/*.xml");
  115. mapperLocations.add("classpath*:mapper/*.xml");
  116. for (String mapperLocation : mapperLocations) {
  117. try {
  118. Resource[] resources = resourcePatternResolver.getResources(mapperLocation);
  119. allResourceList.addAll(Arrays.asList(resources));
  120. } catch (Exception ex) {
  121. throw new FlowableException("Could not create sqlSessionFactory", ex);
  122. }
  123. }
  124. Resource[] allResourceArr = allResourceList.toArray(new Resource[allResourceList.size()]);
  125. //因为若依中使用了类别名基础包,所以需要在这个地方进行添加
  126. sqlSessionFactoryBean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());
  127. sqlSessionFactoryBean.setMapperLocations(allResourceArr);
  128. sqlSessionFactoryBean.afterPropertiesSet();
  129. return sqlSessionFactoryBean.getObject();
  130. } catch (Exception e) {
  131. throw new FlowableException("Could not create sqlSessionFactory", e);
  132. }
  133. }
  134. @Bean(destroyMethod = "clearCache")
  135. // destroyMethod: see https://github.com/mybatis/old-google-code-issues/issues/778
  136. @Qualifier("flowableModeler")
  137. @Primary
  138. public SqlSessionTemplate modelerSqlSessionTemplate(@Qualifier("flowableModeler") SqlSessionFactory sqlSessionFactory) {
  139. return new SqlSessionTemplate(sqlSessionFactory);
  140. }
  141. @Bean
  142. @Qualifier("flowableModeler")
  143. public Liquibase modelerLiquibase(DataSource dataSource) {
  144. LOGGER.info("Configuring Liquibase");
  145. try {
  146. return LiquibaseUtil.runInFlowableScope(() -> createAndUpdateLiquibase(dataSource));
  147. } catch (Exception e) {
  148. throw new InternalServerErrorException("Error creating liquibase database", e);
  149. }
  150. }
  151. protected Liquibase createAndUpdateLiquibase(DataSource dataSource) {
  152. Liquibase liquibase = null;
  153. try {
  154. DatabaseConnection connection = new JdbcConnection(dataSource.getConnection());
  155. Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
  156. database.setDatabaseChangeLogTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogTableName());
  157. database.setDatabaseChangeLogLockTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogLockTableName());
  158. liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database);
  159. liquibase.update("flowable");
  160. return liquibase;
  161. } catch (Exception e) {
  162. throw new InternalServerErrorException("Error creating liquibase database", e);
  163. } finally {
  164. closeDatabase(liquibase);
  165. }
  166. }
  167. protected String initDatabaseType(DataSource dataSource) {
  168. String databaseType = null;
  169. Connection connection = null;
  170. try {
  171. connection = dataSource.getConnection();
  172. DatabaseMetaData databaseMetaData = connection.getMetaData();
  173. String databaseProductName = databaseMetaData.getDatabaseProductName();
  174. LOGGER.info("database product name: '{}'", databaseProductName);
  175. databaseType = databaseTypeMappings.getProperty(databaseProductName);
  176. if (databaseType == null) {
  177. throw new FlowableException("couldn't deduct database type from database product name '" + databaseProductName + "'");
  178. }
  179. LOGGER.info("using database type: {}", databaseType);
  180. } catch (SQLException e) {
  181. LOGGER.error("Exception while initializing Database connection", e);
  182. } finally {
  183. try {
  184. if (connection != null) {
  185. connection.close();
  186. }
  187. } catch (SQLException e) {
  188. LOGGER.error("Exception while closing the Database connection", e);
  189. }
  190. }
  191. return databaseType;
  192. }
  193. private void closeDatabase(Liquibase liquibase) {
  194. if (liquibase != null) {
  195. Database database = liquibase.getDatabase();
  196. if (database != null) {
  197. try {
  198. database.close();
  199. } catch (DatabaseException e) {
  200. LOGGER.warn("Error closing database", e);
  201. }
  202. }
  203. }
  204. }
  205. }

2.6修改框架原有mybatis配置

2.6.1重写自动化读取

类名随意定,

  1. import org.apache.ibatis.mapping.DatabaseIdProvider;
  2. import org.apache.ibatis.plugin.Interceptor;
  3. import org.apache.ibatis.session.Configuration;
  4. import org.apache.ibatis.session.ExecutorType;
  5. import org.apache.ibatis.session.SqlSessionFactory;
  6. import org.mybatis.spring.SqlSessionFactoryBean;
  7. import org.mybatis.spring.SqlSessionTemplate;
  8. import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
  9. import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
  10. import org.springframework.context.ApplicationContext;
  11. import org.springframework.core.io.ResourceLoader;
  12. import org.springframework.util.ObjectUtils;
  13. import org.springframework.util.StringUtils;
  14. import javax.sql.DataSource;
  15. public class AbsMybatisAutoConfiguration {
  16. protected SqlSessionFactory getSqlSessionFactory(
  17. DataSource dataSource,
  18. MybatisProperties properties,
  19. ResourceLoader resourceLoader,
  20. Interceptor[] interceptors,
  21. DatabaseIdProvider databaseIdProvider,
  22. ApplicationContext applicationContext
  23. ) throws Exception {
  24. SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
  25. factory.setDataSource(dataSource);
  26. factory.setVfs(SpringBootVFS.class);
  27. if (StringUtils.hasText(properties.getConfigLocation())) {
  28. factory.setConfigLocation(resourceLoader.getResource(properties.getConfigLocation()));
  29. }
  30. Configuration configuration = properties.getConfiguration();
  31. if (configuration == null && !StringUtils.hasText(properties.getConfigLocation())) {
  32. configuration = new Configuration();
  33. }
  34. factory.setConfiguration(configuration);
  35. if (properties.getConfigurationProperties() != null) {
  36. factory.setConfigurationProperties(properties.getConfigurationProperties());
  37. }
  38. if (!ObjectUtils.isEmpty(interceptors)) {
  39. factory.setPlugins(interceptors);
  40. }
  41. if (databaseIdProvider != null) {
  42. factory.setDatabaseIdProvider(databaseIdProvider);
  43. }
  44. if (StringUtils.hasLength(properties.getTypeAliasesPackage())) {
  45. factory.setTypeAliasesPackage(properties.getTypeAliasesPackage());
  46. }
  47. if (StringUtils.hasLength(properties.getTypeHandlersPackage())) {
  48. factory.setTypeHandlersPackage(properties.getTypeHandlersPackage());
  49. }
  50. if (!ObjectUtils.isEmpty(properties.resolveMapperLocations())) {
  51. factory.setMapperLocations(properties.resolveMapperLocations());
  52. }
  53. return factory.getObject();
  54. }
  55. private void applyConfiguration(SqlSessionFactoryBean factory, MybatisProperties properties) {
  56. Configuration configuration = properties.getConfiguration();
  57. if (configuration == null && !StringUtils.hasText(properties.getConfigLocation())) {
  58. configuration = new Configuration();
  59. }
  60. factory.setConfiguration(configuration);
  61. }
  62. public SqlSessionTemplate getSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, MybatisProperties properties) {
  63. ExecutorType executorType = properties.getExecutorType();
  64. if (executorType != null) {
  65. return new SqlSessionTemplate(sqlSessionFactory, executorType);
  66. } else {
  67. return new SqlSessionTemplate(sqlSessionFactory);
  68. }
  69. }
  70. }

2.6.2MyBatisConfig.class修改

屏蔽内部所有方法,继承上边的自动化配置类,增加注解和注入bean

  1. import org.apache.ibatis.session.SqlSessionFactory;
  2. import org.mybatis.spring.SqlSessionTemplate;
  3. import org.mybatis.spring.annotation.MapperScan;
  4. import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Qualifier;
  7. import org.springframework.context.ApplicationContext;
  8. import org.springframework.context.annotation.Bean;
  9. import org.springframework.context.annotation.Configuration;
  10. import org.springframework.core.env.Environment;
  11. import org.springframework.core.io.ResourceLoader;
  12. import org.springframework.transaction.annotation.EnableTransactionManagement;
  13. import javax.sql.DataSource;
  14. /**
  15. * Mybatis支持*匹配扫描包
  16. *
  17. * @author ruoyi
  18. */
  19. @EnableTransactionManagement(proxyTargetClass = true)
  20. @Configuration
  21. @MapperScan(sqlSessionFactoryRef = "sqlSessionFactory", sqlSessionTemplateRef = "sqlSessionTemplate")
  22. public class MyBatisConfig extends AbsMybatisAutoConfiguration{
  23. @Bean(name = "mySqlSessionFactory")
  24. public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource,
  25. MybatisProperties properties,
  26. ResourceLoader resourceLoader,
  27. ApplicationContext applicationContext) throws Exception {
  28. return getSqlSessionFactory(dataSource,
  29. properties,
  30. resourceLoader,
  31. null,
  32. null,
  33. applicationContext);
  34. }
  35. @Bean(name = "mySqlSessionTemplate")
  36. public SqlSessionTemplate sqlSessionTemplate(MybatisProperties properties,
  37. @Qualifier("mySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
  38. return getSqlSessionTemplate(sqlSessionFactory, properties);
  39. }
  40. }

2.6.3yml修改mybatis配置

让其支持BLOB

  1. # MyBatis
  2. mybatis:
  3. # 搜索指定包别名
  4. typeAliasesPackage: org.morfly.kdla.pdmp.**.domain
  5. # 配置mapper的扫描,找到所有的mapper.xml映射文件
  6. mapperLocations: mapper/*/*.xml,classpath*:mapper/*.xml,classpath:/META-INF/modeler-mybatis-mappings/*.xml
  7. # 加载全局的配置文件
  8. configLocation: classpath:mybatis/mybatis-config.xml
  9. # 参数配置
  10. configuration-properties:
  11. # 配置流程引擎参数,详情可见 DatabaseConfiguration
  12. blobType: BLOB
  13. boolValue: TRUE
  14. # 不要设置库名,否则会出现双库名 bug
  15. prefix: ''

外记:

1.项目集成mybatis-plus

如果项目中的mybatis升级成mybatis-plus,需要对三个配置类修改:MybatisConfiguration.class和MyBatisConfig.class,DatabaseConfiguration.class,内容如下:

AbstractMybatisPlusConfiguration.class

  1. import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
  2. import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS;
  3. import com.baomidou.mybatisplus.core.MybatisConfiguration;
  4. import com.baomidou.mybatisplus.core.config.GlobalConfig;
  5. import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
  6. import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
  7. import com.baomidou.mybatisplus.core.injector.ISqlInjector;
  8. import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
  9. import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
  10. import org.apache.ibatis.mapping.DatabaseIdProvider;
  11. import org.apache.ibatis.plugin.Interceptor;
  12. import org.apache.ibatis.session.ExecutorType;
  13. import org.apache.ibatis.session.SqlSessionFactory;
  14. import org.mybatis.spring.SqlSessionTemplate;
  15. import org.springframework.context.ApplicationContext;
  16. import org.springframework.core.io.ResourceLoader;
  17. import org.springframework.util.StringUtils;
  18. import javax.sql.DataSource;
  19. import java.util.List;
  20. public class AbstractMybatisPlusConfiguration {
  21. protected SqlSessionFactory getSqlSessionFactory(
  22. DataSource dataSource,
  23. MybatisPlusProperties properties,
  24. ResourceLoader resourceLoader,
  25. Interceptor[] interceptors,
  26. DatabaseIdProvider databaseIdProvider,
  27. ApplicationContext applicationContext
  28. ) throws Exception {
  29. MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
  30. factory.setDataSource(dataSource);
  31. factory.setVfs(SpringBootVFS.class);
  32. if (StringUtils.hasText(properties.getConfigLocation())) {
  33. factory.setConfigLocation(resourceLoader.getResource(properties.getConfigLocation()));
  34. }
  35. applyConfiguration(factory, properties);
  36. if (properties.getConfigurationProperties() != null) {
  37. factory.setConfigurationProperties(properties.getConfigurationProperties());
  38. }
  39. if (!ObjectUtils.isEmpty(interceptors)) {
  40. factory.setPlugins(interceptors);
  41. }
  42. if (databaseIdProvider != null) {
  43. factory.setDatabaseIdProvider(databaseIdProvider);
  44. }
  45. if (StringUtils.hasLength(properties.getTypeAliasesPackage())) {
  46. factory.setTypeAliasesPackage(properties.getTypeAliasesPackage());
  47. }
  48. // TODO 自定义枚举包
  49. if (StringUtils.hasLength(properties.getTypeEnumsPackage())) {
  50. factory.setTypeEnumsPackage(properties.getTypeEnumsPackage());
  51. }
  52. if (properties.getTypeAliasesSuperType() != null) {
  53. factory.setTypeAliasesSuperType(properties.getTypeAliasesSuperType());
  54. }
  55. if (StringUtils.hasLength(properties.getTypeHandlersPackage())) {
  56. factory.setTypeHandlersPackage(properties.getTypeHandlersPackage());
  57. }
  58. if (!ObjectUtils.isEmpty(properties.resolveMapperLocations())) {
  59. factory.setMapperLocations(properties.resolveMapperLocations());
  60. }
  61. // TODO 此处必为非 NULL
  62. GlobalConfig globalConfig = properties.getGlobalConfig();
  63. //注入填充器
  64. if (applicationContext.getBeanNamesForType(MetaObjectHandler.class,
  65. false, false).length > 0) {
  66. MetaObjectHandler metaObjectHandler = applicationContext.getBean(MetaObjectHandler.class);
  67. globalConfig.setMetaObjectHandler(metaObjectHandler);
  68. }
  69. //注入主键生成器
  70. if (applicationContext.getBeanNamesForType(IKeyGenerator.class, false,
  71. false).length > 0) {
  72. IKeyGenerator keyGenerator = applicationContext.getBean(IKeyGenerator.class);
  73. globalConfig.getDbConfig().setKeyGenerators((List<IKeyGenerator>) keyGenerator);
  74. }
  75. //注入sql注入器
  76. if (applicationContext.getBeanNamesForType(ISqlInjector.class, false,
  77. false).length > 0) {
  78. ISqlInjector iSqlInjector = applicationContext.getBean(ISqlInjector.class);
  79. globalConfig.setSqlInjector(iSqlInjector);
  80. }
  81. factory.setGlobalConfig(globalConfig);
  82. return factory.getObject();
  83. }
  84. private void applyConfiguration(MybatisSqlSessionFactoryBean factory, MybatisPlusProperties properties) {
  85. MybatisConfiguration configuration = properties.getConfiguration();
  86. if (configuration == null && !StringUtils.hasText(properties.getConfigLocation())) {
  87. configuration = new MybatisConfiguration();
  88. }
  89. // if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
  90. // for (ConfigurationCustomizer customizer : this.configurationCustomizers) {
  91. // customizer.customize(configuration);
  92. // }
  93. // }
  94. factory.setConfiguration(configuration);
  95. }
  96. public SqlSessionTemplate getSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, MybatisPlusProperties properties) {
  97. ExecutorType executorType = properties.getExecutorType();
  98. if (executorType != null) {
  99. return new SqlSessionTemplate(sqlSessionFactory, executorType);
  100. } else {
  101. return new SqlSessionTemplate(sqlSessionFactory);
  102. }
  103. }
  104. }

DatabaseConfiguration.class

  1. import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
  2. import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
  3. import liquibase.Liquibase;
  4. import liquibase.database.Database;
  5. import liquibase.database.DatabaseConnection;
  6. import liquibase.database.DatabaseFactory;
  7. import liquibase.database.jvm.JdbcConnection;
  8. import liquibase.exception.DatabaseException;
  9. import liquibase.resource.ClassLoaderResourceAccessor;
  10. import lombok.extern.slf4j.Slf4j;
  11. import org.apache.ibatis.session.SqlSessionFactory;
  12. import org.flowable.common.engine.api.FlowableException;
  13. import org.flowable.ui.common.service.exception.InternalServerErrorException;
  14. import org.flowable.ui.modeler.properties.FlowableModelerAppProperties;
  15. import org.mybatis.spring.SqlSessionTemplate;
  16. import org.springframework.beans.factory.annotation.Autowired;
  17. import org.springframework.beans.factory.annotation.Qualifier;
  18. import org.springframework.context.annotation.Bean;
  19. import org.springframework.context.annotation.Configuration;
  20. import org.springframework.context.annotation.Primary;
  21. import org.springframework.core.io.Resource;
  22. import org.springframework.core.io.ResourceLoader;
  23. import org.springframework.core.io.support.ResourcePatternResolver;
  24. import org.springframework.core.io.support.ResourcePatternUtils;
  25. import javax.sql.DataSource;
  26. import java.sql.Connection;
  27. import java.sql.DatabaseMetaData;
  28. import java.sql.SQLException;
  29. import java.util.ArrayList;
  30. import java.util.Arrays;
  31. import java.util.List;
  32. import java.util.Properties;
  33. @Configuration
  34. @Slf4j
  35. public class DatabaseConfiguration {
  36. protected static final String LIQUIBASE_CHANGELOG_PREFIX = "ACT_DE_";
  37. @Autowired
  38. protected FlowableModelerAppProperties modelerAppProperties;
  39. @Autowired
  40. protected ResourceLoader resourceLoader;
  41. @Autowired
  42. protected MybatisPlusProperties mybatisPlusProperties;
  43. protected static Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();
  44. public static final String DATABASE_TYPE_H2 = "h2";
  45. public static final String DATABASE_TYPE_HSQL = "hsql";
  46. public static final String DATABASE_TYPE_MYSQL = "mysql";
  47. public static final String DATABASE_TYPE_ORACLE = "oracle";
  48. public static final String DATABASE_TYPE_POSTGRES = "postgres";
  49. public static final String DATABASE_TYPE_MSSQL = "mssql";
  50. public static final String DATABASE_TYPE_DB2 = "db2";
  51. public static Properties getDefaultDatabaseTypeMappings() {
  52. Properties databaseTypeMappings = new Properties();
  53. databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
  54. databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL);
  55. databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
  56. databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
  57. databaseTypeMappings.setProperty("PostgreSQL", DATABASE_TYPE_POSTGRES);
  58. databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
  59. databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
  60. databaseTypeMappings.setProperty("DB2", DATABASE_TYPE_DB2);
  61. databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
  62. databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
  63. databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
  64. databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
  65. databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
  66. databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
  67. databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
  68. databaseTypeMappings.setProperty("DB2/LINUXPPC64", DATABASE_TYPE_DB2);
  69. databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
  70. databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
  71. databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
  72. databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
  73. databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
  74. databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
  75. databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
  76. databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
  77. databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
  78. databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
  79. databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
  80. return databaseTypeMappings;
  81. }
  82. @Bean
  83. @Qualifier("flowableModeler")
  84. @Primary
  85. public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {
  86. MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
  87. sqlSessionFactoryBean.setDataSource(dataSource);
  88. String databaseType = initDatabaseType(dataSource);
  89. if (databaseType == null) {
  90. throw new FlowableException("couldn't deduct database type");
  91. }
  92. try {
  93. Properties properties = new Properties();
  94. properties.put("prefix", modelerAppProperties.getDataSourcePrefix());
  95. properties.put("blobType", "BLOB");
  96. properties.put("boolValue", "TRUE");
  97. log.info("this.getClass().getClassLoader():{}",databaseType);
  98. properties.load(this.getClass().getClassLoader().getResourceAsStream("org/flowable/db/properties/" + databaseType + ".properties"));
  99. sqlSessionFactoryBean.setConfigurationProperties(properties);
  100. //这个是原始代码,只添加flowable的扫描路径
  101. // sqlSessionFactoryBean
  102. // .setMapperLocations(ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources("classpath:/META-INF/modeler-mybatis-mappings/*.xml"));
  103. //由于后面要设置该SqlSessionFactory为主要的SqlSessionFactory,
  104. // 然后Ruoyi中使用时Mybatis自动注入,所以在这个地方就需要添加Ruoyi配置扫描
  105. ResourcePatternResolver resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
  106. List<Resource> allResourceList = new ArrayList<>();
  107. List<String> mapperLocations = new ArrayList<>();
  108. //先添加
  109. mapperLocations.add("classpath:/META-INF/modeler-mybatis-mappings/*.xml");
  110. mapperLocations.add("classpath*:/mapper/**/*Mapper.xml");
  111. mapperLocations.add("mapper/*/*.xml");
  112. mapperLocations.add("classpath*:mapper/*.xml");
  113. for (String mapperLocation : mapperLocations) {
  114. try {
  115. Resource[] resources = resourcePatternResolver.getResources(mapperLocation);
  116. allResourceList.addAll(Arrays.asList(resources));
  117. } catch (Exception ex) {
  118. throw new FlowableException("Could not create sqlSessionFactory", ex);
  119. }
  120. }
  121. Resource[] allResourceArr = allResourceList.toArray(new Resource[allResourceList.size()]);
  122. //因为若依中使用了类别名基础包,所以需要在这个地方进行添加
  123. sqlSessionFactoryBean.setTypeAliasesPackage(mybatisPlusProperties.getTypeAliasesPackage());
  124. sqlSessionFactoryBean.setMapperLocations(allResourceArr);
  125. sqlSessionFactoryBean.afterPropertiesSet();
  126. return sqlSessionFactoryBean.getObject();
  127. } catch (Exception e) {
  128. throw new FlowableException("Could not create sqlSessionFactory", e);
  129. }
  130. }
  131. @Primary
  132. @Bean(destroyMethod = "clearCache") // destroyMethod: see https://github.com/mybatis/old-google-code-issues/issues/778
  133. public SqlSessionTemplate SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
  134. return new SqlSessionTemplate(sqlSessionFactory);
  135. }
  136. @Bean
  137. public Liquibase liquibase(DataSource dataSource) {
  138. log.info("Configuring Liquibase");
  139. Liquibase liquibase = null;
  140. try {
  141. DatabaseConnection connection = new JdbcConnection(dataSource.getConnection());
  142. Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
  143. database.setDatabaseChangeLogTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogTableName());
  144. database.setDatabaseChangeLogLockTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogLockTableName());
  145. liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database);
  146. liquibase.update("flowable");
  147. return liquibase;
  148. } catch (Exception e) {
  149. throw new InternalServerErrorException("Error creating liquibase database", e);
  150. } finally {
  151. closeDatabase(liquibase);
  152. }
  153. }
  154. protected String initDatabaseType(DataSource dataSource) {
  155. String databaseType = null;
  156. Connection connection = null;
  157. try {
  158. connection = dataSource.getConnection();
  159. DatabaseMetaData databaseMetaData = connection.getMetaData();
  160. String databaseProductName = databaseMetaData.getDatabaseProductName();
  161. log.info("database product name: '{}'", databaseProductName);
  162. databaseType = databaseTypeMappings.getProperty(databaseProductName);
  163. if (databaseType == null) {
  164. throw new FlowableException("couldn't deduct database type from database product name '" + databaseProductName + "'");
  165. }
  166. log.info("using database type: {}", databaseType);
  167. } catch (SQLException e) {
  168. log.error("Exception while initializing Database connection", e);
  169. } finally {
  170. try {
  171. if (connection != null) {
  172. connection.close();
  173. }
  174. } catch (SQLException e) {
  175. log.error("Exception while closing the Database connection", e);
  176. }
  177. }
  178. return databaseType;
  179. }
  180. private void closeDatabase(Liquibase liquibase) {
  181. if (liquibase != null) {
  182. Database database = liquibase.getDatabase();
  183. if (database != null) {
  184. try {
  185. database.close();
  186. } catch (DatabaseException e) {
  187. log.warn("Error closing database", e);
  188. }
  189. }
  190. }
  191. }
  192. }

MybatisConfig.class改名 MybatisPlusConfig.class

  1. import com.baomidou.mybatisplus.annotation.DbType;
  2. import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
  3. import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
  4. import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
  5. import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
  6. import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.mybatis.spring.SqlSessionTemplate;
  9. import org.mybatis.spring.annotation.MapperScan;
  10. import org.springframework.beans.factory.annotation.Qualifier;
  11. import org.springframework.context.ApplicationContext;
  12. import org.springframework.context.annotation.Bean;
  13. import org.springframework.context.annotation.Configuration;
  14. import org.springframework.core.io.ResourceLoader;
  15. import org.springframework.transaction.annotation.EnableTransactionManagement;
  16. import javax.sql.DataSource;
  17. /**
  18. * Mybatis Plus 配置
  19. *
  20. * @author ruoyi
  21. */
  22. @EnableTransactionManagement(proxyTargetClass = true)
  23. @Configuration
  24. @MapperScan(sqlSessionFactoryRef = "sqlSessionFactory", sqlSessionTemplateRef = "sqlSessionTemplate")
  25. public class MybatisPlusConfig extends AbstractMybatisPlusConfiguration
  26. {
  27. @Bean
  28. public MybatisPlusInterceptor mybatisPlusInterceptor()
  29. {
  30. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  31. // 分页插件
  32. interceptor.addInnerInterceptor(paginationInnerInterceptor());
  33. // 乐观锁插件
  34. interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
  35. // 阻断插件
  36. interceptor.addInnerInterceptor(blockAttackInnerInterceptor());
  37. return interceptor;
  38. }
  39. /**
  40. * 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
  41. */
  42. public PaginationInnerInterceptor paginationInnerInterceptor()
  43. {
  44. PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
  45. // 设置数据库类型为mysql
  46. paginationInnerInterceptor.setDbType(DbType.MYSQL);
  47. // 设置最大单页限制数量,默认 500 条,-1 不受限制
  48. paginationInnerInterceptor.setMaxLimit(-1L);
  49. return paginationInnerInterceptor;
  50. }
  51. /**
  52. * 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html
  53. */
  54. public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor()
  55. {
  56. return new OptimisticLockerInnerInterceptor();
  57. }
  58. /**
  59. * 如果是对全表的删除或更新操作,就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html
  60. */
  61. public BlockAttackInnerInterceptor blockAttackInnerInterceptor()
  62. {
  63. return new BlockAttackInnerInterceptor();
  64. }
  65. @Bean(name = "mySqlSessionFactory")
  66. public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource,
  67. MybatisPlusProperties properties,
  68. ResourceLoader resourceLoader,
  69. ApplicationContext applicationContext) throws Exception {
  70. return getSqlSessionFactory(dataSource,
  71. properties,
  72. resourceLoader,
  73. null,
  74. null,
  75. applicationContext);
  76. }
  77. @Bean(name = "mySqlSessionTemplate")
  78. public SqlSessionTemplate sqlSessionTemplate(MybatisPlusProperties properties,
  79. @Qualifier("mySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
  80. return getSqlSessionTemplate(sqlSessionFactory, properties);
  81. }
  82. }

主要修改的是配置获取方法。有时mybatis-plus版本不同也会出现一些问题,比如重写的自动化配置在注入主键生成器:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/852363
推荐阅读
相关标签
  

闽ICP备14008679号