jfinal 动态多数据源实现

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

image.png

请求2  http://localhost:8080/api/test?businessflag=test2

image.png

4. 注意

此方案适用于不同数据源,但是要求数据结构一致,否则在使用model的时候可能会报找不到表的异常

5. demo地址

https://gitee.com/git_zhanglong/RoutingDatasource

欢迎大家批评指正


关注我的公众号,免费获取Java + Jfinal学习视频

image.png


评论区

或是的话

2022-03-07 03:39

对于在处理请求对业务代码中开了另外一个线程会不会有问题?

或是的话

2022-03-08 11:13

自动任务没有请求 没有参数这种怎么办

热门分享

扫码入社