里面什么都没有AbstractRoutingDataSource
强制你使用静态地图DataSourceS
。由你来构建一个 bean 来实现Map<Object, Object>
,其中 key 是您用来选择的DataSource
,价值是DataSource
或(默认情况下)引用 JNDI 定义的数据源的字符串。您甚至可以动态修改它,因为当地图存储在内存中时,AbstractRoutingDataSource
不进行缓存。
我没有完整的示例代码。但这是我能想象到的。在 Web 应用程序中,每个客户端都有一个数据库,所有数据库都具有相同的结构 - 好吧,这将是一个奇怪的设计,假设这只是为了示例。在登录时,应用程序为客户端创建数据源并将其存储在由 sessionId 索引的映射中 - 该映射是根上下文中名为的 beandataSources
@Autowired
@Qualifier("dataSources");
Map<String, DataSource> sources;
// I assume url, user and password have been found from connected user
// I use DriverManagerDataSource for the example because it is simple to setup
DataSource dataSource = new DriverManagerDataSource(url, user, password);
sources.put(request.getSession.getId(), dataSource);
您还需要一个会话监听器来清理dataSources
in its destroy
method
@Autowired
@Qualifier("dataSources");
Map<String, DataSource> sources;
public void sessionDestroyed(HttpSessionEvent se) {
// eventually cleanup the DataSource if appropriate (nothing to do for DriverManagerDataSource ...)
sources.remove(se.getSession.getId());
}
路由数据源可能是这样的:
public class SessionRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
return request.getSession().getId();
}
@Autowired
@Qualifier("dataSources")
public void setDataSources(Map<String, DataSource> dataSources) {
setTargetDataSources(dataSources);
}
我没有测试任何东西,因为设置不同的数据库需要很多工作,但我认为应该没问题。在现实世界中,每个会话不会有不同的数据源,而是每个用户都有一个数据源,每个用户有一个会话计数,但正如我所说,这是一个过于简化的示例。