方法一
- 配置多个数据库
spring:
datasource:
master:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3305/se?useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
movies:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3307/se_movies?useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
复制代码
- 配置数据库连接
package com.my.equipment.config.oldConfig;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.my.equipment.web.seMoviesDao", sqlSessionTemplateRef = "seMoviesSqlSessionTemplate")
public class SeMoviesDatasourceConfig {
@Bean(name = "seMoviesDataSource")
@ConfigurationProperties(prefix = "spring.datasource.movies")
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "seMoviesSqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("seMoviesDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
return bean.getObject();
}
@Bean(name = "seMoviesTransactionManager")
public DataSourceTransactionManager testTransactionManager(@Qualifier("seMoviesDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "seMoviesSqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("seMoviesSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
复制代码
package com.my.equipment.config.oldConfig;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.my.equipment.web.dao",sqlSessionTemplateRef = "seSqlSessionTemplate")
public class SeDatasourceConfig {
@Bean(name = "seDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master")
@Primary
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "seSqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("seDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
return bean.getObject();
}
@Bean(name = "seTransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("seDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "seSqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("seSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
复制代码
方法2
1.配置多个数据库
spring:
datasource:
master:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3305/se?useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
slave:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3310/se?useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
movies:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3307/se_movies?useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
复制代码
2.配置数据库连接
定义多元数据库
package com.my.equipment.utils;
public enum DBTypeEnum {
MASTER,SLAVE,MOVIES;
}
复制代码
定义数据源切换
package com.my.equipment.utils;
public class DBContextHolder {
private static final ThreadLocal<DBTypeEnum> contextHolder=new ThreadLocal<>();
public static void set(DBTypeEnum dbTypeEnum){
contextHolder.set(dbTypeEnum);
}
public static DBTypeEnum get(){
return contextHolder.get();
}
public static void master(){
set(DBTypeEnum.MASTER);
System.out.println("写");
}
public static void slave(){
set(DBTypeEnum.SLAVE);
System.out.println("读");
}
public static void movies(){
set(DBTypeEnum.MOVIES);
System.out.println("movies");
}
public static void clear(){
contextHolder.remove();
}
}
复制代码
重写路由选择类
package com.my.equipment.utils;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.lang.Nullable;
public class MyRoutingDataSource extends AbstractRoutingDataSource {
@Nullable
@Override
protected Object determineCurrentLookupKey() {
return DBContextHolder.get();
}
}
复制代码
配置Mybatis SqlSessionFactory 和事务管理器
package com.my.equipment.config;
import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.annotation.Resource;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement
public class MyBatisConfig {
@Value("${mybatis.mapper-locations}")
private String mapperLocation;
@Resource(name = "myRoutingDataSource")
private DataSource myRoutingDataSource;
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(myRoutingDataSource);
ResourcePatternResolver resolver=new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocation));
return sqlSessionFactoryBean.getObject();
}
@Bean
public PlatformTransactionManager platformTransactionManager(){
return new DataSourceTransactionManager(myRoutingDataSource);
}
}
复制代码
配置数据源
package com.my.equipment.config;
import com.my.equipment.utils.DBTypeEnum;
import com.my.equipment.utils.MyRoutingDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DatasourceConfig {
/**
* 配置从数据库
* @return
*/
@Bean(name = "slaveDataSource")
@ConfigurationProperties("spring.datasource.slave")
public DataSource slaveDataSource(){
return DataSourceBuilder.create().build();
}
/**
* 配置主数据库
* @return
*/
@Bean(name = "masterDataSource")
@ConfigurationProperties("spring.datasource.master")
public DataSource masterDataSource(){
return DataSourceBuilder.create().build();
}
@Bean(name = "moviesDataSource")
@ConfigurationProperties("spring.datasource.movies")
public DataSource moviesDataSource(){
return DataSourceBuilder.create().build();
}
@Bean
public DataSource myRoutingDataSource(@Qualifier("slaveDataSource") DataSource slaveDataSource,
@Qualifier("masterDataSource") DataSource masterDataSource,
@Qualifier("moviesDataSource") DataSource moviesDataSource){
Map<Object,Object> targetDataSource=new HashMap<>();
targetDataSource.put(DBTypeEnum.MASTER,masterDataSource);
targetDataSource.put(DBTypeEnum.SLAVE,slaveDataSource);
targetDataSource.put(DBTypeEnum.MOVIES,moviesDataSource);
MyRoutingDataSource myRoutingDataSource=new MyRoutingDataSource();
//找不到用默认数据源
myRoutingDataSource.setDefaultTargetDataSource(masterDataSource);
//可选择的目标数据源
myRoutingDataSource.setTargetDataSources(targetDataSource);
return myRoutingDataSource;
}
}
复制代码
切面实现数据源切换
package com.my.equipment.aspect;
import com.my.equipment.utils.DBContextHolder;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class DataSourceAop {
//com.my.equipment.web.dao及其子包下所有的方法
@Pointcut("execution(* com.my.equipment.web.dao..*.*(..))")
public void writePoint(){
}
//com.my.equipment.web.seSlaveDao及其子包下所有的方法(..*代表当前及其子目录)
@Pointcut("execution(* com.my.equipment.web.seSlaveDao..*.*(..))")
public void readPoint(){
}
@Pointcut("execution(* com.my.equipment.web.seMoviesDao..*.*(..))")
public void moviesPoint(){
}
@Before("readPoint()")
public void read(){
DBContextHolder.slave();
}
@Before("writePoint()")
public void write(){
DBContextHolder.master();
}
@Before("moviesPoint()")
public void movies(){
DBContextHolder.movies();
}
}
复制代码