网站怎么做搜素引擎,如何建网站商城,网站备案个人好还是企业好,港海建设网站既然在整理Mybatis那就把经常用的这个多数据源的笔记也整一下吧。
Spring集成Mybatis在之前就已经提到了。Spring集成Mybatis
集成Mybatis多数据源有两种方式#xff1a;
1、创建多个SqlSessionFactory#xff0c;扫描每个SqlSessionFactoryBean对应的包#xff0c;形成了…既然在整理Mybatis那就把经常用的这个多数据源的笔记也整一下吧。
Spring集成Mybatis在之前就已经提到了。Spring集成Mybatis
集成Mybatis多数据源有两种方式
1、创建多个SqlSessionFactory扫描每个SqlSessionFactoryBean对应的包形成了每个Factory对应一个数据源。
2、创建一个SqlSessionFactory通过动态切换数据源对象达到多数据源操作功能。
第一种方式
通过在Spring的配置文件中配置多个SqlSessionFactoryBean对象每个对应不同的MapperScannerConfigurer每个MapperScannerConfigurer扫描不同的包路径接口 另外一个数据源也如上配置只需替换对应的扫描包即可这样调用指定包下的接口就能访问指定的数据库了。
第二种方式
创建单个SqlSessionFactory指定默认数据源后期查询不同的数据库切换SqlSessionFactory中数据源如果访问次数过多频繁切换的话就会导致一个并发问题。
解决这个问题就应该使用并发中一些机制如果使用锁机制的话那么查询的效率就会降低同时只有当线程去执行采用ThreadLocal的话就能解决这个效率以及线程安全的问题了。
由于需切换数据源所以在创建SqlSessionFactory时需要有几个注意的点
1、设置数据源对象应该为一个支持切换的一个DataSource对象我们先定义为RouteDataSource对象由于是DataSource所以这个RouteDataSource就必须实现DataSource接口但是又不能侵入原本数据库链接池的对象所以这个采用装饰器模式进行装饰这个类
2、支持动态切换即需要一个暴露的静态方法进行切换由于数据源对象都在这个Spring容器当中所以这个类需拿到Spring的容器使用权实现ApplicationContextAware接口
3、需指定切换那个数据源可以采用ENUM枚举进行指定也可以通过String都可以。
创建一个枚举类
public enum DataSourceEnum {DATASOURCE1(null),DATASOURCE2(null);DataSource dataSource;private DataSourceEnum(DataSource dataSource) {this.dataSource dataSource;}public DataSource getValue() {return dataSource;}public DataSourceEnum setDataSource(DataSource dataSource) {this.dataSource dataSource;return this;}}
RouteDataSource类如下
Component(routeDataSource)
public class RouteDataSource implements DataSource,InitializingBean,ApplicationContextAware {private static final MapDataSourceEnum,DataSource targetDataSources new HashMapDataSourceEnum,DataSource(2); //避免并发问题ThreadLocalDataSource targetDataSource new ThreadLocalDataSource();//装时器模式进行数据源增强private static RouteDataSource route null;public void setDataSource(DataSource targetDataSource) {this.targetDataSource.set(targetDataSource);}Overridepublic PrintWriter getLogWriter() throws SQLException {return targetDataSource.get().getLogWriter();}Overridepublic void setLogWriter(PrintWriter out) throws SQLException {targetDataSource.get().setLogWriter(out);}Overridepublic void setLoginTimeout(int seconds) throws SQLException {targetDataSource.get().setLoginTimeout(seconds);}Overridepublic int getLoginTimeout() throws SQLException {return targetDataSource.get().getLoginTimeout();}Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return targetDataSource.get().getParentLogger();}Overridepublic T T unwrap(ClassT iface) throws SQLException {return targetDataSource.get().unwrap(iface);}Overridepublic boolean isWrapperFor(Class? iface) throws SQLException {return targetDataSource.get().isWrapperFor(iface);}Overridepublic Connection getConnection() throws SQLException {return targetDataSource.get().getConnection();}Overridepublic Connection getConnection(String username, String password) throws SQLException {return targetDataSource.get().getConnection(username, password);}//初始化枚举数据已经默认数据源Overridepublic void afterPropertiesSet() throws Exception {targetDataSources.put(DataSourceEnum.DATASOURCE1.setDataSource((DataSource) applicationContext.getBean(dataSource)), (DataSource) applicationContext.getBean(dataSource));targetDataSources.put(DataSourceEnum.DATASOURCE2.setDataSource((DataSource) applicationContext.getBean(dataSource1)), (DataSource) applicationContext.getBean(dataSource1));targetDataSource.set(targetDataSources.get(DataSourceEnum.DATASOURCE1));route (RouteDataSource) applicationContext.getBean(routeDataSource);}private ApplicationContext applicationContext;Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext applicationContext;}/*** description 更改数据源方法* param enumDataSource*/public static void setDataSource(DataSourceEnum enumDataSource) {route.setDataSource(targetDataSources.get(enumDataSource));}}
所以在调用Mybatis的接口之前调用RouteDataSource.setDataSource(DataSourceEnum.DATASOURCE);即可切换成对应的数据源进行查询啦。
上面是一个自定义的数据源路由类后来才发现在Spring的jdbc包下有个支持数据源切换的动态数据源类AbstractRoutingDataSource。
如果使用这个类做数据源切换也是可以的实现的思想以及模式都和自定义的那个是一致的
示例
public class ThreadLocalRountingDataSource extends AbstractRoutingDataSource {Overrideprotected Object determineCurrentLookupKey() {// TODO Auto-generated method stub//在这里做数据源切换return DataSourceTypeManager.get();}}
//管理数据源类
public class DataSourceTypeManager {//数据源保存private static final ThreadLocalMybatisDataSource dataSourceTypes new ThreadLocalMybatisDataSource() {Overrideprotected MybatisDataSource initialValue() {return MybatisDataSource.JKDSJ;}};public static MybatisDataSource get() {return dataSourceTypes.get();}public static void set(MybatisDataSource dataSourceType) {dataSourceTypes.set(dataSourceType);}public static void reset() {dataSourceTypes.set(MybatisDataSource.JKDSJ);}}
这个类还是挺好用的