沃梦达 / IT编程 / 数据库 / 正文

Springboot mybais配置多数据源过程解析

下面就详细讲解“Springboot mybais配置多数据源过程解析”的完整攻略。

下面就详细讲解“Springboot mybais配置多数据源过程解析”的完整攻略。

一、引入依赖

首先,我们需要在pom.xml文件中引入相关的依赖,具体如下:

<dependencies>
    <!--SpringBoot启动器-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.5.5</version>
    </dependency>
    <!--Mybatis依赖-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.0</version>
    </dependency>
    <!--Mysql驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.25</version>
    </dependency>
</dependencies>

二、配置application.properties

application.properties文件中,我们需要配置相关的数据源信息,具体如下所示:

# 主数据源
spring.datasource.master.url=jdbc:mysql://localhost:3306/master_database?useSSL=false&serverTimezone=UTC
spring.datasource.master.username=root
spring.datasource.master.password=123456
spring.datasource.master.driver-class-name=com.mysql.jdbc.Driver

# 从数据源
spring.datasource.slave.url=jdbc:mysql://localhost:3306/slave_database?useSSL=false&serverTimezone=UTC
spring.datasource.slave.username=root
spring.datasource.slave.password=123456
spring.datasource.slave.driver-class-name=com.mysql.jdbc.Driver

三、配置DataSource及SqlSessionFactory

@Configuration
@MapperScan(basePackages = {"com.example.demo.mapper"})
public class DataSourceConfiguration {

    @Bean(name = "masterDataSource")
    @Qualifier("masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "slaveDataSource")
    @Qualifier("slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dynamicDataSource")
    public DynamicDataSource dynamicDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
                                               @Qualifier("slaveDataSource") DataSource slaveDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceEnum.MASTER.getName(), masterDataSource);
        targetDataSources.put(DataSourceEnum.SLAVE.getName(), slaveDataSource);
        DynamicDataSource dynamicDataSource = new DynamicDataSource(masterDataSource, targetDataSources);
        return dynamicDataSource;
    }

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DynamicDataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml");
        bean.setMapperLocations(resources);
        return bean.getObject();
    }

    @Bean(name = "sqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

四、自定义DynamicDataSource

public class DynamicDataSource extends AbstractRoutingDataSource {

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    private Object defaultDataSource;
    private Object readDataSource;
    private Map<Object, Object> targetDataSources;

    public DynamicDataSource(Object defaultDataSource, Map<Object, Object> targetDataSources) {
        this.defaultDataSource = defaultDataSource;
        this.targetDataSources = targetDataSources;
    }

    public void setReadDataSource(Object readDataSource) {
        this.readDataSource = readDataSource;
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return contextHolder.get();
    }

    @Override
    public void afterPropertiesSet() {
        setDefaultTargetDataSource(defaultDataSource);
        setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    public static void setDataSource(String name) {
        contextHolder.set(name);
    }

    public static void clearDataSource() {
        contextHolder.remove();
    }

    public static String getDataSource() {
        return contextHolder.get();
    }

}

五、定义数据源枚举类

public enum DataSourceEnum {

    MASTER("masterDataSource"),
    SLAVE("slaveDataSource");

    private String name;

    DataSourceEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

六、使用

在需要使用的方法上标注使用哪个数据源,如下所示:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserDao userDao;

    @Override
    public List<User> getUsers() {
        DynamicDataSource.setDataSource(DataSourceEnum.MASTER.getName());
        return userDao.getUsers();
    }

    @Override
    public List<User> getSlaveUsers() {
        DynamicDataSource.setDataSource(DataSourceEnum.SLAVE.getName());
        return userDao.getUsers();
    }
}

七、示例说明

示例一:查询主数据源

在使用主数据源查询用户列表时,我们可以去除@DataSource注解,使用默认数据源即可。代码示例如下:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserDao userDao;

    @Override
    public List<User> getUsers() {
        return userDao.getUsers();
    }

}

示例二:查询从数据源

在使用从数据源查询用户列表时,我们需要在方法上加上自定义的@DataSource注解,如下所示:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserDao userDao;

    @DataSource(name = DataSourceEnum.SLAVE)
    @Override
    public List<User> getSlaveUsers() {
        return userDao.getUsers();
    }
}

以上就是“Springboot mybais配置多数据源过程解析”的完整攻略。

本文标题为:Springboot mybais配置多数据源过程解析