一,第一种方式
1.配置文件
spring.datasource.test1.jdbc-url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
spring.datasource.test1.username=root
spring.datasource.test1.password=123456
spring.datasource.test1.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.test2.jdbc-url=jdbc:mysql://localhost:3306/demo1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
spring.datasource.test2.username=root
spring.datasource.test2.password=123456
spring.datasource.test2.driver-class-name=com.mysql.jdbc.Driver
server.port=8083
logging.level.com.atguigu=trace
2.第一数据源配置
package com.config;
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 javax.sql.DataSource;
/**
* 用@Primary区分主数据源
* @Date 2018/10/30.
*/
@Configuration
@MapperScan(basePackages = "com.mapper.test01",sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class PrimaryConfig {
// 将这个对象放入Spring容器中
@Bean(name = "test1DataSource")
// 表示这个数据源是默认数据源
@Primary
// 读取application.properties中的配置参数映射成为一个对象
// prefix表示参数的前缀
@ConfigurationProperties(prefix = "spring.datasource.test1")
public DataSource getDateSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "test1SqlSessionFactory")
// 表示这个数据源是默认数据源
@Primary
// @Qualifier表示查找Spring容器中名字为test1DataSource的对象
public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1DataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
// 设置mybatis的xml所在位置
new PathMatchingResourcePatternResolver().getResources("classpath*:com/mapper/test01/*.xml"));
return bean.getObject();
}
@Bean("test1SqlSessionTemplate")
// 表示这个数据源是默认数据源
@Primary
public SqlSessionTemplate test1sqlsessiontemplate(
@Qualifier("test1SqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
/* @Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}*/
}
3.第二数据源配置
package com.config;
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 javax.sql.DataSource;
/**
* @Date 2018/10/30.
*/
@Configuration
@MapperScan(basePackages = "com.mapper.test02",sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class SecondaryConfig {
@Bean(name = "test2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSource getDateSource2() {
return DataSourceBuilder.create().build();
}
@Bean(name = "test2SqlSessionFactory")
public SqlSessionFactory test2SqlSessionFactory(@Qualifier("test2DataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:com/mapper/test02/*.xml"));
return bean.getObject();
}
@Bean("test2SqlSessionTemplate")
public SqlSessionTemplate test2sqlsessiontemplate(
@Qualifier("test2SqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
/* @Bean(name = "test2TransactionManager")
public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
*/
}
service
package com.service.test02;
import com.domain.test02.User2;
/**
* @Date 2018/8/22.
*/
public interface UserService {
public User2 getUser2(String username);
}
impl实现
package com.service.test02.impl;
import com.domain.test02.User2;
import com.mapper.test02.User2Mapper;
import com.service.test02.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Date 2018/8/22.
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private User2Mapper user2Mapper;
@Override
public User2 getUser2(String username) {
// 数据库查询有没此用户如无直接返回null
User2 user = user2Mapper.findUserByUsername(username);
return user;
}
}
控制
package com.controller;
import com.domain.test01.Depot;
import com.domain.test02.User2;
import com.service.test01.DepotService;
import com.service.test02.UserService;
import com.utils.ResponseBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Date 2018/10/30.
*/
@RestController
public class TestController {
@Autowired
private DepotService depotService;
@Autowired
private UserService userService;
@GetMapping("/depot")
public ResponseBean getDepot(int id) {
Depot depot = depotService.selectByPrimaryKey(id);
ResponseBean responseBean = new ResponseBean(200, "success", depot);
return responseBean;
}
@GetMapping("/user")
public ResponseBean getUser(String name) {
User2 user = userService.getUser2(name);
ResponseBean responseBean = new ResponseBean(200, "success", user);
return responseBean;
}
}
返回结果类
package com.utils;
/**
* 返回结果集
*/
public class ResponseBean {
// http 状态码
private int code;
// 返回信息
private String msg;
// 返回的数据
private Object data;
public ResponseBean(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
目录结构
二,第二种方式:aop
package com.config.aop;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* 切换数据源类型的类
* @Date 2021/1/4.
*/
public class DataSourceType {
private static final Logger logger = LogManager.getLogger(DataSourceType.class);
public enum DataBaseType {
TEST01, TEST02
}
// 使用ThreadLocal保证线程安全
private static final ThreadLocal<DataBaseType> TYPE = new ThreadLocal<DataBaseType>();
// 往当前线程里设置数据源类型
public static void setDataBaseType(DataBaseType dataBaseType) {
if (dataBaseType == null) {
throw new NullPointerException();
}
logger.info("[将当前数据源改为]:" + dataBaseType);
//System.err.println("[将当前数据源改为]:" + dataBaseType);
TYPE.set(dataBaseType);
}
// 获取数据源类型
public static DataBaseType getDataBaseType() {
DataBaseType dataBaseType = TYPE.get() == null ? DataBaseType.TEST01 : TYPE.get();
logger.info("[获取当前数据源的类型为]:" + dataBaseType);
//System.err.println("[获取当前数据源的类型为]:" + dataBaseType);
return dataBaseType;
}
// 清空数据类型
public static void clearDataBaseType() {
TYPE.remove();
}
}
package com.config.aop;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 动态数据源
* @Date 2021/1/4.
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
DataSourceType.DataBaseType dataBaseType = DataSourceType.getDataBaseType();
return dataBaseType;
}
}
package com.config.aop;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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 javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 多个数据源配置
* @Date 2021/1/4.
*/
@Configuration
@MapperScan(basePackages = "com.mapper", sqlSessionFactoryRef = "SqlSessionFactory")
public class DataSourceConfig {
@Primary
@Bean(name = "test1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test1")
public DataSource getDateSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "test2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSource getDateSource2() {
return DataSourceBuilder.create().build();
}
@Bean(name = "dynamicDataSource")
public DynamicDataSource DataSource(@Qualifier("test1DataSource") DataSource test1DataSource,
@Qualifier("test2DataSource") DataSource test2DataSource) {
Map<Object, Object> targetDataSource = new HashMap<>();
targetDataSource.put(DataSourceType.DataBaseType.TEST01, test1DataSource);
targetDataSource.put(DataSourceType.DataBaseType.TEST02, test2DataSource);
DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSource);
dataSource.setDefaultTargetDataSource(test1DataSource);
return dataSource;
}
@Bean(name = "SqlSessionFactory")
public SqlSessionFactory test1SqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dynamicDataSource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:com/mapper/*.xml"));
return bean.getObject();
}
}
package com.config.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* 不同业务切换不同数据库的入口
* @Date 2021/1/4.
*/
@Aspect
@Component
public class DataSourceAop {
@Before("execution(* com.service.test01.impl..*.*(..))")
public void setDataSource2test01() {
System.err.println("test01业务");
DataSourceType.setDataBaseType(DataSourceType.DataBaseType.TEST01);
}
@Before("execution(* com.service.test02.impl..*.*(..))")
public void setDataSource2test02() {
System.err.println("test02业务");
DataSourceType.setDataBaseType(DataSourceType.DataBaseType.TEST02);
}
}
目录结构