折腾了一天,终于完成了多数据源的配置,记录在这里!
1,先上SpringBoot 基础配置
①,系统引入了Security的包,但是没有配置Security相关信息,在启动时会打印警告log,故这里排除SecurityAutoConfiguration这个类
2,配置两个数据源
@Configuration
public class DataBaseConfig implements EnvironmentAware {
private RelaxedPropertyResolver dbPropertyResolver;
private static final Logger logger = LoggerFactory.getLogger(EnvironmentAware.class);
@Override
public void setEnvironment(Environment environment) {
dbPropertyResolver = new RelaxedPropertyResolver(environment,"jdbc.");
}
/**
* 写库
* @return
*/
@Bean(name="writeDataSource", destroyMethod = "close", initMethod="init")
@Primary
public DataSource writeDataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(dbPropertyResolver.getProperty("url"));
datasource.setDriverClassName(dbPropertyResolver.getProperty("driverClass"));
datasource.setUsername(dbPropertyResolver.getProperty("username"));
datasource.setPassword(dbPropertyResolver.getProperty("password"));
return datasource;
}
/**
* 读库
* @return
*/
@Bean(name="readDataSource", destroyMethod = "close", initMethod="init")
public DataSource readOneDataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(dbPropertyResolver.getProperty("url"));
datasource.setDriverClassName(dbPropertyResolver.getProperty("driverClassName"));
datasource.setUsername(dbPropertyResolver.getProperty("username"));
datasource.setPassword(dbPropertyResolver.getProperty("password"));
return datasource;
}
}
②,将写库作为默认主数据源,在注入时,若没有指定该注入哪一个数据源,默认注入使用写库数据源
3,配置只读数据源与Mybatis的配置信息
@Configuration
@EnableTransactionManagement
@AutoConfigureAfter(WriteMybatisConfig.class)
public class ReadMybatisConfig implements EnvironmentAware {
/**
* 日志记录器
*/
private static final Logger LOGGER = LoggerFactory.getLogger(ReadMybatisConfig.class);
private RelaxedPropertyResolver mybatisPropertyResolver;
/**
* 获取配置信息
* @param environment
*/
@Override
public void setEnvironment(Environment environment) {
mybatisPropertyResolver = new RelaxedPropertyResolver(environment,"mybatis.");
}
//从库数据源
@Resource(name = "readDataSource")
private DataSource readDataSource;
/**
* 只读sqlSessionFactory
* @return
*/
@Bean(name = "readSqlSessionFactory")
public SqlSessionFactory readSqlSessionFactory() {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(readDataSource);
bean.setTypeAliasesPackage(mybatisPropertyResolver.getProperty("typeAliasesPackage"));
//分页插件
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("returnPageInfo", "check");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
bean.setPlugins(new Interceptor[]{pageHelper});
//添加mybatis配置文件
PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
bean.setConfigLocation(resourceResolver.getResource(mybatisPropertyResolver.getProperty("configLocation")));
try {
bean.setMapperLocations(resourceResolver.getResources(mybatisPropertyResolver.getProperty("mapperLocations")));
return bean.getObject();
} catch (IOException e) {
LOGGER.error("获取mapper资源出现异常",e);
throw new RuntimeException("获取mapper资源出现异常",e);
} catch (Exception e){
LOGGER.error("初始化sqlSessionFactory时出现异常",e);
throw new RuntimeException("初始化sqlSessionFactory时出现异常",e);
}
}
}
4,配置写数据源与Mybatis的配置
@Configuration
@EnableTransactionManagement
@AutoConfigureAfter
public class WriteMybatisConfig implements EnvironmentAware {
public static final Logger LOGGER = LoggerFactory.getLogger(WriteMybatisConfig.class);
private RelaxedPropertyResolver mybatisPropertyResolver;
@Override
public void setEnvironment(Environment environment) {
mybatisPropertyResolver = new RelaxedPropertyResolver(environment,"mybatis.");
}
//写库
@Resource(name = "writeDataSource")
private DataSource writeDataSource;
/**
* 可读可写sqlSessionFactory
* @return
*/
@Bean(name = "writeSqlSessionFactory")
public SqlSessionFactory writeSqlSessionFactory() {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(writeDataSource);
bean.setTypeAliasesPackage(mybatisPropertyResolver.getProperty("typeAliasesPackage"));
//分页插件
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("returnPageInfo", "check");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
bean.setPlugins(new Interceptor[]{pageHelper});
//添加mybatis配置文件
PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
bean.setConfigLocation(resourceResolver.getResource(mybatisPropertyResolver.getProperty("configLocation")));
try {
bean.setMapperLocations(resourceResolver.getResources(mybatisPropertyResolver.getProperty("mapperLocations")));
return bean.getObject();
} catch (IOException e) {
LOGGER.error("获取mapper资源出现异常",e);
throw new RuntimeException("获取mapper资源出现异常",e);
} catch (Exception e){
LOGGER.error("初始化sqlSessionFactory时出现异常",e);
throw new RuntimeException("初始化sqlSessionFactory时出现异常",e);
}
}
/**
* 因为当前项目中有
* @return
*/
@Bean(name = "writeTransactionManager")
public DataSourceTransactionManager writeTransactionManager() {
DataSourceTransactionManager manager = new DataSourceTransactionManager(writeDataSource);
return manager;
}
}
5,配置Mybatis的Mapper扫描器
@Configuration
public class MybatisMapperScannerConfig {
/**
* 扫描读写模式-mapper,只有在basePackage包下且继承自BaseWriterMapper的mapper才会被扫描到
* @return
*/
@Bean(name = "writeMapperScanner")
public MapperScannerConfigurer writeMapperScanner(){
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage("com.llktop.dao");
configurer.setMarkerInterface(BaseWriteMapper.class);
configurer.setSqlSessionFactoryBeanName("writeSqlSessionFactory");
return configurer;
}
/**
* 扫描只读模式-mapper,只有在basePackage包下且继承自BaseReadMapper的mapper才会被扫描到
* @return
*/
@Bean(name = "readMapperScanner")
public MapperScannerConfigurer readMapperScanner(){
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage("com.llktop.dao");
configurer.setMarkerInterface(BaseReadMapper.class);
configurer.setSqlSessionFactoryBeanName("readSqlSessionFactory");
return configurer;
}
}
注意,这里多配置了一个叫MarkerInterface的属性,目的是,所有的mapper中只有继承自BaseWriteMapper这个类的Mapper会走写数据源,而所有继承自ReadMapper的Mapper会走读数据源
这样,就做到了多套数据源,可以配合Mysql读写分离进行使用!