基于AbstractRoutingDataSource的动态切换数据库
来源:互联网 发布:超级基因优化液第二部 编辑:程序博客网 时间:2024/06/04 18:38
当项目发展到一定阶段,就需要对数据库进行一定的优化。一般会对数据库进行横向和纵向切库分表,但是这样的问题就来了,在我们操作数据库时,需要根据切分规则提前获得我们需要的数据库的连接,这明显会加重程序员的负担。
比如我们将“用户信息数据库”按照用户注册的年月来分库,在用户注册的时候,为用户分配一个以yyyyMM开头的唯一标示,以方便我们能快速定位到切分后的子数据库。那么问题来了,我们在项目中,如何动态且方便的获得我们需要的数据源呢?Spring提供了一个解决方案,那就是基于AbstractRoutingDataSource的动态数据源切换。
AbstractRoutingDataSource的类结构:
想要使用,只需要重写determineCurrentLookupKey方法,在说明他的作用之前,先看下调用他的位置:
private Map
protected DataSource determineTargetDataSource() { Assert.notNull(this.resolvedDataSources, "DataSource router not initialized"); Object lookupKey = determineCurrentLookupKey(); DataSource dataSource = this.resolvedDataSources.get(lookupKey); if (dataSource == null && (this.lenientFallback || lookupKey == null)) { dataSource = this.resolvedDefaultDataSource; } if (dataSource == null) { throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]"); } return dataSource; }
可以看到,determineCurrentLookupKey的返回值会作为Map的key来查找数据库连接。而determineTargetDataSource方法通常是用来返回给调用端DataSource,因此我们可以通过重写这两个方法,来实现动态切换数据库。
首先定义一个Bean来保存数据库信息,也将它作为Map的key,数据库连接作为Value。
public class DatabaseDefineBean { private String userName; private String passWord; private String url; ...getter/setter}
编写我们自己的数据源
public class MyDataSource extends AbstractRoutingDataSource { private String driverClassName; static ThreadLocal<DatabaseDefineBean> defineBeans = new ThreadLocal<DatabaseDefineBean>(); @Override protected Object determineCurrentLookupKey() { return defineBeans.get(); } @Override protected DataSource determineTargetDataSource() { DriverManagerDataSource dataSource = getDataSource((DatabaseDefineBean) determineCurrentLookupKey()); return dataSource; } private DriverManagerDataSource getDataSource(DatabaseDefineBean databse) { DriverManagerDataSource dataSource = new DriverManagerDataSource(databse.getUrl(), databse.getUserName(), databse.getPassWord()); return dataSource; }}
这里使用Spring+Mybatis测试(源码及数据库文件下载):
String userName = "writeuser"; String passWord = "writeuser"; String url = "jdbc:mysql://192.168.1.61:3306/DataBaseRoute"; @Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"/com/smart/config/spring-jdbc.xml"}); MyDataSource.setDefineBeans(new DatabaseDefineBean(userName, passWord, url)); DataSource dataSource = context.getBean(DataSource.class); System.out.println(dataSource); SqlSessionTemplate sessionTemplate = context.getBean(SqlSessionTemplate.class); DatabaseInfoMapper mapper = sessionTemplate.getSqlSessionFactory().openSession().getMapper(DatabaseInfoMapper.class); List<?> list = mapper.selectAll(); System.out.println(list); }
那么如何动态切换呢?这里使用到了ThreadLocal,用于为每个线程保存一个副本,我们只需在操作数据库之前设置一下Database的基本信息就可以轻松获得想要的数据源了。
MyDataSource.setDefineBeans(new DatabaseDefineBean(userName, passWord, url));
0 0
- 基于AbstractRoutingDataSource的动态切换数据库
- AbstractRoutingDataSource动态切换数据源
- Spring的AbstractRoutingDataSource 实现 数据源DB的动态切换
- 利用AbstractRoutingDataSource实现动态数据源切换
- 利用AbstractRoutingDataSource实现动态数据源切换
- 利用AbstractRoutingDataSource实现动态数据源切换
- 利用AbstractRoutingDataSource实现动态数据源切换
- 利用AbstractRoutingDataSource实现动态数据源切换
- 利用AbstractRoutingDataSource实现动态数据源切换
- Spring(AbstractRoutingDataSource)实现动态数据源切换
- Spring(AbstractRoutingDataSource)实现动态数据源切换
- 利用AbstractRoutingDataSource实现动态数据源切换
- Spring(AbstractRoutingDataSource)实现动态数据源切换
- Spring(AbstractRoutingDataSource)实现动态数据源切换
- Spring(AbstractRoutingDataSource)实现动态数据源切换
- Spring AbstractRoutingDataSource 实现动态数据源切换
- Spring(AbstractRoutingDataSource)实现动态数据源切换
- Spring(AbstractRoutingDataSource)实现动态数据源切换
- 仿支付宝/微信的密码输入框效果GridPasswordView解析
- POJ 2528 Mayor's posters 线段树+离散化
- POJ 2492 A Bug's Life(并查集+逻辑关系)
- FZU1150 Farmer Bill's Problem
- 黑马程序员——正则表达式2:功能演示
- 基于AbstractRoutingDataSource的动态切换数据库
- FZU1171 Hard to Believe, but True!
- scala柯里化函数
- Jenkins API curl创建job、执行构建
- Find The Multiple
- jquery代码阅读jQuery.makeArray()
- Sparql语言模型(一)
- STL 之 优先队列(priority_queue)
- Java聊天模拟