主题:提供一个多数据源任意切换的解决方案思路。

jornlin 2018年07月03日 824

最近几天在研究beetlSQL,发现beetlSQL本身对多数据源的支持并不太好(不能通过AbstractRoutingDataSource任意切换数据源。)。在论坛中逛了一大圈,发现有些人通过声明多个SQLManager,使用的时候调用不同的数据源来进行操作。但是通过我的测试发现,虽然这样可以解决多数据源问题,但是当我想要写sql文件的时候,就出问题了。再执行sql的时候,还是会使用默认的数据源去执行(BeetlSqlScannerConfigurer配置的数据源)。这就很让人头大了。于是进过几天的努力,现提供一种解决思路,来应对多数据源任意切换的问题。

  1. 注入多个SQLManager,你有几个数据源,就注入几个SQLManager

  2. 注入一个SQLManagerHolder对象,用于管理多个SQLManager

  3. 创建一个DbContextHolder,用户切换数据源标识
  4. 创建自己的BaseMapper ,并实现对应的MapperInvoke
  5. 重写MapperBuilder,MapperJavaProxy,MapperJava8Proxy

好了,经过以上步骤,就算大功告成了,此时,只需要调用DbContextHolder.setDbType(DataSourceEnum.SYS);

即可针对设置的数据源进行操作了。

希望这个方法能够帮到你们。还请各位大佬多多指教。

附部分代码:

public class SQLManagerHolder {
    private static final Map managerMap = new HashMap<>();

    public SQLManagerHolder(Map maps) {
        for (String key : maps.keySet()) {
            SQLManager sqlManager = maps.get(key);
            buildSQLManager(sqlManager);
            sqlManager.setMapperBuilder(new IsapMapperBuilder(sqlManager));
            managerMap.put(key, sqlManager);
        }
    }

    public static SQLManager get() {
        return managerMap.get(DbContextHolder.getDbType());
    }

    public void buildSQLManager(SQLManager sqlManager) {
        MapperConfigBuilder builder = sqlManager.setBaseMapper(BaseMapper.class).getBuilder();
        //查询单个
        builder.addAmi("selectOneById", new SelectOneByIdAmi());
        //查询单个,加锁
        builder.addAmi("selectOneByIdLock", new SelectOneByIdLockAmi());
        //新增 忽略null
        builder.addAmi("insert", new InsertAmi());
        //新增 忽略null 可以得到 自动生成key
        builder.addAmi("insertGetKey", new InsertGetKeyAmi());
        //新增 包括null
        builder.addAmi("insertAll", new InsertAllAmi());
        //新增 包括null 可以得到 自动生成key
        builder.addAmi("insertAllGetKey", new InsertAllGetKeyAmi());
        //批量新增
        builder.addAmi("insertBatch", new InsertBatchAmi());
        //修改 忽略null
        builder.addAmi("updateById", new UpdateByIdAmi());
        //修改 包括null
        builder.addAmi("updateAllById", new UpdateAllByIdAmi());
        //批量修改
        builder.addAmi("updateBatchById", new UpdateByIdAmi());
        //删除
        builder.addAmi("deleteById", new DeleteByIdAmi());
        //获取 SQLManager
        builder.addAmi("getSQLManager", new GetSQLManagerAmi());

    }
}
   
    
        
            
                
                
            
        
    


附测试成功的截图一张


图片.png

  • hopefully :哥们,逛了一大圈论坛,发现就你这个跟我的业务需求最吻合,也最对胃口,可不可以把代码还有原理贴得更详细一些,表示对beetlsql没有你理解的那么深入,如果不嫌弃加个QQ请教一下,qq:54060642(2019年03月06日)
jornlin 2018年07月03日

感兴趣的朋友可以一起交流讨论

闲大赋 2018年07月04日

看着不错,如群吧,280825689  beetl开发群,进来玩

chris 2018年07月13日

看着可以,暂时不想折腾了,等以后有时间再深入学习吧

三国lz 2018年07月17日

偶然看到了这个贴子,才发现原来多数据源需求还比较大,这里我也贡献一下我以前写的多数据源支持的代码。

https://gitee.com/sanguolz/bootdemo

(请参考beetlsql-spring-boot-starter子模块)

由于这是六月份写的,与现在的beetlsql版本还无法兼容,但解决思路应该可以参考

后面有空了我再单独弄一个beetlsql的starter项目

  • 闲大赋 :确实,多谢!(2018年07月18日)
jAmEs_ 2018年07月24日

什么时候有简单点的多数据源方案,感觉要弄好需要了解好多东西

闲大赋 2018年07月24日

你先说清楚你需求再说

jAmEs_ 2018年07月25日

说白了就是希望lz所说的 [能通过AbstractRoutingDataSource任意切换数据源]。

这样,才能beetlsql内部怎么变化,都不影响多数据源的实现。

闲大赋 2018年07月25日


支持不了 AbstractRoutingDataSource这个概念,你到时可以用当当的shard-jdbc+beetlsql来做,这样各种多数据源需求你都搞定,beetlsql始终是以SQLManager为核心,一个SQLManager对应一个库