jfinal目前提供了多数据源的支持,但是根据前端传过来的业务标识去动态的切换数据源的场景还显得有些力不从心,我看到社区也有一部分关于这方面的分享,但是总感觉不够简洁,要改的东西比较多,下面分享一下我的实现,希望对大家有所启发。
原理: 因为对数据库的操作,最后都用到了DataSource.getConnection方法,所以这个方案的原理就是重写DataSource的getConnection方法,在调用到getConnection的时候根据业务标识去初始化DataSource
1. 定义一个多数据源DataSource
public class RoutingDatasource implements DataSource { //缓存多个datasource private Map<String, DataSource> datasources = new HashMap<String,DataSource>(); //重写 getConnection 方法 //businessFlag 就是业务标识信息,表示要连哪个数据库,可以放在ThreadLocal里面,每个线程不一样 @Override public Connection getConnection() throws SQLException { DataSource routingDataSource = datasources.get("businessFlag"); if(routingDataSource == null) { synchronized (this) { routingDataSource = datasources.get("businessFlag"); if(routingDataSource == null) { routingDataSource = createDatasource("businessFlag"); datasources.put("businessFlag", routingDataSource); } } } return routingDataSource.getConnection(); } //根据不同的业务标识创建DataSource //可以把不同数据库的连接信息放到数据库中,然后这个地方读取连接信息 private DataSource createDatasource(String businessFlag) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("");// url dataSource.setUsername(""); // username dataSource.setPassword(""); // password return dataSource; } }
2.创建ActiveRecordPlugin 的时候调用下面的构造函数
DruidPlugin dbPlugin = new DruidPlugin(new RoutingDatasource());
这样每次前端发来请求之后,在进行数据库操作之前都会初始化相应的DataSource,然后获取connection,从而实现了动态数据源的切换
3.效果
请求1 http://localhost:8080/api/test?businessflag=test1
请求2 http://localhost:8080/api/test?businessflag=test2
4. 注意
此方案适用于不同数据源,但是要求数据结构一致,否则在使用model的时候可能会报找不到表的异常
5. demo地址
https://gitee.com/git_zhanglong/RoutingDatasource
欢迎大家批评指正
关注我的公众号,免费获取Java + Jfinal学习视频