activiti支持国产数据库

 activit作为一种轻量级,可嵌入的BPM引擎,广泛应用于企业级管理系统,然而他只支持一些数据库,国产数据库基本不支持,但我们可以扩展

原生支持的数据库:

Activiti数据库类型JDBC URL实例备注
h2jdbc:h2:tcp://localhost/activiti默认配置的数据库
mysqljdbc:mysql://localhost:3306/activiti?autoReconnect=true使用mysql-connector-java驱动测试
oraclejdbc:oracle:thin:@localhost:1521:xe 
postgresjdbc:postgresql://localhost:5432/activiti 
db2jdbc:db2://localhost:50000/activiti 
mssqljdbc:sqlserver://localhost:1433/activiti

怎么才能支持国产的一些数据库呢,废话不多说,直接上代码。

1、流程引擎扩展配置接口
public interface ActivitiEngineConfigurationConfigurer {
    public void configure(SpringProcessEngineConfiguration processEngineConfiguration);
}

扩展实现国产数据库类型可配置
@Component
public class ActivitiEngineConfiguration implements ActivitiEngineConfigurationConfigurer {

    //设置数据库类型
    @Value(value = "${jiuqi.nr.activiti.dbtype}")
    private String databaseType;

    //设置DbSqlSessionConfigurator
    @Autowired
    private DbSqlSessionConfigurator dbSqlSessionConfigurator;

    @Override
    public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
        //设置数据库类型
        processEngineConfiguration.setDatabaseType(databaseType);
        processEngineConfiguration.setUsingRelationalDatabase(false);
        List<ProcessEngineConfigurator> configurators = new ArrayList<ProcessEngineConfigurator>();
        configurators.add(dbSqlSessionConfigurator);
        processEngineConfiguration.setConfigurators(configurators);


    }
}

2、编写ProcessEngineConfigurator,配置SqlSessionFactory
/**
 * SqlSessionFactory配置
 */
@Component
public class DbSqlSessionConfigurator implements ProcessEngineConfigurator {

    private static final String DEFAULT_MYBATIS_MAPPING_FILE = "config/mapper/mappings.xml";

    private static final String DATABASE_GBASE="gbase";

    private static final String DATABASE_DM="dameng";

    private static final String DATABASE_GAUSSDB100="gaussdb100";

    private static final String DATABASE_OSCAR="oscar";

    private  static Set<String> dbSets=new HashSet<>();

    static {
        dbSets.add(DATABASE_GBASE);
        dbSets.add(DATABASE_DM);
        dbSets.add(DATABASE_GAUSSDB100);
        dbSets.add(DATABASE_OSCAR);
    }

    /**此出设置重写的NrDbSqlSessionFactory是为了处理Gbase8s不支持批量插入,其他数据库可不实现该方法*/
    @Override
    public void beforeInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
        //添加重写的SqlSessionFactory
        processEngineConfiguration.setDbSqlSessionFactory(new NrDbSqlSessionFactory());
    }

    //ProcessEngineConfigurationImpl中的configuratorsAfterInit会执行到此处
    @Override
    public void configure(ProcessEngineConfigurationImpl processEngineConfiguration) {
        //创建SqlSessionFactory并设置ProcessEngineConfigurationImpl
        processEngineConfiguration.setSqlSessionFactory(createSqlSessionFactory(processEngineConfiguration));
        //重新执行initDbSqlSessionFactory
        processEngineConfiguration.initDbSqlSessionFactory();

    }

    private SqlSessionFactory createSqlSessionFactory(ProcessEngineConfigurationImpl processEngineConfiguration) {
        InputStream inputStream = null;
        try {
            //读取的mappings.xm为了处理gbase8s的长字符串类型错误,不是gbase可以加载activiti默认的配置
            inputStream = getResourceAsStream(DEFAULT_MYBATIS_MAPPING_FILE);

            Environment environment = new Environment("default", processEngineConfiguration.getTransactionFactory(),
                    processEngineConfiguration.getDataSource());
            Reader reader = new InputStreamReader(inputStream);
            Properties properties = new Properties();
            properties.put("prefix", processEngineConfiguration.getDatabaseTablePrefix());
            String wildcardEscapeClause = "";
            if ((processEngineConfiguration.getDatabaseWildcardEscapeCharacter() != null)
                    && (processEngineConfiguration.getDatabaseWildcardEscapeCharacter().length() != 0)) {
                wildcardEscapeClause = " escape '" + processEngineConfiguration.getDatabaseWildcardEscapeCharacter()
                        + "'";
            }
            properties.put("wildcardEscapeClause", wildcardEscapeClause);
            // set default properties
            properties.put("limitBefore", "");
            properties.put("limitAfter", "");
            properties.put("limitBetween", "");
            properties.put("limitOuterJoinBetween", "");
            properties.put("limitBeforeNativeQuery", "");
            properties.put("orderBy", "order by ${orderByColumns}");
            properties.put("blobType", "BLOB");
            properties.put("boolValue", "TRUE");

            if (processEngineConfiguration.getDatabaseType() != null) {
                //设置读取数据库语法配置文件,文件路径src/main/resource/config/custom/   自定义的数据类型对应语法文件
                if(dbSets.contains(processEngineConfiguration.getDatabaseType().toLowerCase())) {
                    properties.load(getResourceAsStream("config/custom/"+ processEngineConfiguration.getDatabaseType() + ".properties"));
                }else {
                    properties.load(getResourceAsStream("org/activiti/db/properties/"
                            + processEngineConfiguration.getDatabaseType() + ".properties"));
                }

            }

            Configuration configuration = processEngineConfiguration.initMybatisConfiguration(environment, reader,
                    properties);
            return new DefaultSqlSessionFactory(configuration);

        } catch (Exception e) {
            throw new ActivitiException("Error while building ibatis SqlSessionFactory: " + e.getMessage(), e);
        } finally {
            IoUtil.closeSilently(inputStream);
        }

    }

    private InputStream getResourceAsStream(String resource) {
        return ReflectUtil.getResourceAsStream(resource);
    }

    @Override
    public int getPriority() {
        return 0;
    }
}

2、重写DbSqlSession的flushInsertEntities方法(适配gbase才需要此步骤)
/**
 * SqlSession会话工厂
 * 在DbSqlSessionConfigurator(beforeInit方法)中重置会话工厂
 */
public class MyDbSqlSessionFactory extends DbSqlSessionFactory {

    @Override
    public Session openSession(CommandContext commandContext) {
        return new MyDbSqlSession(this, commandContext.getEntityCache());
    }

}


public class NrDbSqlSession extends DbSqlSession {

    private static final Logger log = LoggerFactory.getLogger(NrDbSqlSession.class);

    public NrDbSqlSession(DbSqlSessionFactory dbSqlSessionFactory, EntityCache entityCache) {
        super(dbSqlSessionFactory, entityCache);
    }

    /**
     * 重写此方法是为了解决gbase不支持批量插入的问题
     * @param entityClass
     * @param entitiesToInsert
     */
    @Override
    protected void flushInsertEntities(Class<? extends Entity> entityClass, Collection<Entity> entitiesToInsert) {
        if (entitiesToInsert.size() == 1) {
            flushRegularInsert(entitiesToInsert.iterator().next(), entityClass);
        }else {
            for (Entity entity : entitiesToInsert) {
                flushRegularInsert(entity, entityClass);
            }
        }
    }

}

3、装配自定义扩展配置
MyProcessEngineConfiguration cfg = new MyProcessEngineConfiguration();
engineFactory.setProcessEngineConfiguration(cfg);
buildDataSource(cfg);
//判断原生activiti是否支持应用数据库
if(!isSupportDatabase(cfg)){
    //国产数据库扩展适配,构建引擎之前
   activitiEngineConfigurationConfigurer.configure(cfg);
}
return new Activiti6ProcessEngine(engineFactory.getObject()).setActorStrategyProvider(actorStrategyProvider)
      .setUserActionEventHandler(actionEventHandler).setProcessProviders(processProviders)
      .setNrParameterUtils(ParameterUtils).setConditionalExecute(conditionalExecutes);

最后说一句,不按以上方法也可以,可以重写ProcessEngineConfigurationImpl类的相关方法实现。当然,你也可以修改activiti源码,替换jar包,但是那样很不方便也不太合适。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值