在 d2js 使用多种数据源如spring数据源

不少人误以为 d2js 只能通过 database.js 指定一个数据库,是一个单数据库方案。实际上 d2js 也可以使用多个数据库。

在 WEB-INF/jslib/d2js/base.js 的末尾,是 dj2s 创建 DataSource 为 d2js 的 SqlExecutor 的主要代码:

D2JS.init = function(){
    
    var datasource = application.datasource || (application.datasource = (function(){
        var properties = new java.util.Properties();
        for(var k in datasourceConfig){
            properties.setProperty(k, datasourceConfig[k] + '');
        }
        return Java.type('org.apache.commons.dbcp2.BasicDataSourceFactory').createDataSource(properties);
    }()));
    
    var sqlExecutor = new org.siphon.jssql.SqlExecutor(datasource, engine, JSON);
    sqlExecutor.defaultJsonDbType = datasourceConfig.defaultJsonDbType || 'JSONB';
    sqlExecutor.columnNameCase = datasourceConfig.columnNameCase || 0;    // LOWER
    sqlExecutor.useColumnLabelAsName = datasourceConfig.useColumnLabelAsName || false;    ;
    
    d2js = handler = new D2JS(sqlExecutor);
    engine.put('handler', handler);
    engine.put('d2js', d2js);
}

这个 D2JS.init 函数在 application.d2js.js 和 application.jssp.js 中调用。

通过自定义 D2JS.init 函数,可以自定义数据库连接。

如对于spring,可编写 spring-datasource.js :

D2JS.init = function(){
    
    var sqlExecutor = D2JS.createExecutorForDataSource("dataSource");
    
    d2js = handler = new D2JS(sqlExecutor);
    engine.put('handler', handler);
    engine.put('d2js', d2js);
        
}

D2JS.createExecutorForDataSource = function(beanName){
    var WebApplicationContextUtils = Java.type('org.springframework.web.context.support.WebApplicationContextUtils');
    var wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
    var datasource = wac.getBean(beanName);    
    var sqlExecutor = new org.siphon.jssql.SqlExecutor(datasource, engine);
    sqlExecutor.columnNameCase = 1; // KEEP
    sqlExecutor.useColumnLabelAsName = true;
    return sqlExecutor;
}

对于其它数据源,如 h2 db 可编写:

    var executor = (function createMemExecutor(){
        var datasource = (function(){
            var properties = new java.util.Properties();
            for(var k in datasourceConfig){
                properties.setProperty(k, datasourceConfig[k] + '');
            }
            return Java.type('org.apache.commons.dbcp2.BasicDataSourceFactory').createDataSource(properties);
        })();
        
        var sqlExecutor = new org.siphon.jssql.SqlExecutor(datasource, engine);
        sqlExecutor.columnNameCase = datasourceConfig.columnNameCase || 0;    // LOWER
        sqlExecutor.useColumnLabelAsName = true;
        return sqlExecutor;
    })();

修改 application.d2js.js 和 application.jssp.js,在  imports("jslib/d2js.js"); 后执行 

imports("./spring-datasource.js");

这样,spring-datasource.js 中的 D2JS.init 就覆盖了 base.js 中原来的 D2JS.init,实现了使用 spring 数据源或其它数据源。

如何让多个数据源并存呢?

如上面的内存数据源,登记为 d2js.memSqlExecutor。

    d2js.memSqlExecutor = (function createMemExecutor(){
        var datasource = (function(){
            var properties = new java.util.Properties();
            for(var k in datasourceConfig){
                properties.setProperty(k, datasourceConfig[k] + '');
            }
            return Java.type('org.apache.commons.dbcp2.BasicDataSourceFactory').createDataSource(properties);
        })();
        
        var sqlExecutor = new org.siphon.jssql.SqlExecutor(datasource, engine);
        sqlExecutor.columnNameCase = datasourceConfig.columnNameCase || 0;    // LOWER
        sqlExecutor.useColumnLabelAsName = true;
        return sqlExecutor;
    })();

前面的博客介绍过,每个 d2js 实例都是从 d2js 对象复制的,所以每个 d2js 实例都会拥有 memSqlExecutor 成员。

使用时只要通过 this.executor = d2js.memSqlExecutor 就可以切换数据源(记得切换回来)。

如考虑为web容器环境,也可将设为 application.memSqlExecutor。

如果需要对多个数据源前后执行同一条语句,可按如下操作:

d2js.test = function(){
  [sqlExecutor1, sqlExecutor2, this.executor].forEach(function(executor){
    this.executor = executor;  // 循环过程依次切换为 sqlExecutor1, sqlExecutor2, this.executor

    this.execute(sql, {args})
  }, this)
}

这个办法只有一个 d2js 对象,此外也可直接创建一些真正的 d2js 对象。

    var d = new D2JS(this.executor);
    for(var k in this){
        if(this.hasOwnProperty(k)) {
            d[k] = this[k];
        } else {
            break;
        }
    }
d.executor = executor1;

d 就是一个从当前 d2js 实例复制出来但是数据源不同的 d2js 对象。

原文地址:https://www.cnblogs.com/inshua/p/8488643.html