SpringBoot多数据源配置的全过程记录

下面是详细讲解“SpringBoot多数据源配置的全过程记录”的完整攻略。

概述

在实际开发中,我们很可能需要同时连接多个数据库,例如连接MySQL和Redis等。SpringBoot的多数据源配置能够满足我们这一需求。本文将详细记录SpringBoot多数据源配置的全过程。

步骤

1. 添加依赖

pom.xml文件中添加以下依赖:

<!-- MyBatis Plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.2</version>
</dependency>
<!-- MySQL连接驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.25</version>
</dependency>
<!-- Redis客户端 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.5.4</version>
</dependency>

2. 配置application.yml文件

src/main/resources目录下创建application.yml文件,并添加以下配置:

spring:
  datasource:
    master: # 主数据源配置
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/db_master?useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
      username: root
      password: password
    slave: # 从数据源配置
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/db_slave?useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
      username: root
      password: password
  redis:
    host: localhost
    port: 6379
    password: password
    database: 0
    lettuce:
      pool:
        max-active: 8
        max-wait: -1
        max-idle: 8
        min-idle: 0

3. 配置数据源

com.example.demo.config包下创建DataSourceConfig类,并添加以下代码:

@Configuration
public class DataSourceConfig {

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

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

}

4. 配置MyBatis Plus

com.example.demo.config包下创建MybatisPlusConfig类,并添加以下代码:

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

    @Resource(name = "masterDataSource")
    private DataSource masterDataSource;

    @Resource(name = "slaveDataSource")
    private DataSource slaveDataSource;

    /**
     * 主数据源 MyBatis SqlSessionFactory
     */
    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(masterDataSource);
        return sessionFactory.getObject();
    }

    /**
     * 从数据源 MyBatis SqlSessionFactory
     */
    @Bean(name = "slaveSqlSessionFactory")
    public SqlSessionFactory slaveSqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(slaveDataSource);
        return sessionFactory.getObject();
    }

    /**
     * 主数据源 MyBatis 事务管理
     */
    @Bean(name = "masterTransactionManager")
    public DataSourceTransactionManager masterTransactionManager() {
        return new DataSourceTransactionManager(masterDataSource);
    }

    /**
     * 从数据源 MyBatis 事务管理
     */
    @Bean(name = "slaveTransactionManager")
    public DataSourceTransactionManager slaveTransactionManager() {
        return new DataSourceTransactionManager(slaveDataSource);
    }

    /**
     * 主数据源 MyBatis Mapper 接口类扫描包配置
     */
    @Bean(name = "masterSqlSessionTemplate")
    public SqlSessionTemplate masterSqlSessionTemplate() throws Exception {
        return new SqlSessionTemplate(masterSqlSessionFactory());
    }

    /**
     * 从数据源 MyBatis Mapper 接口类扫描包配置
     */
    @Bean(name = "slaveSqlSessionTemplate")
    public SqlSessionTemplate slaveSqlSessionTemplate() throws Exception {
        return new SqlSessionTemplate(slaveSqlSessionFactory());
    }
}

5. 配置事务

com.example.demo.config包下创建TransactionConfig类,并添加以下代码:

@Configuration
public class TransactionConfig {
    @Resource(name = "masterDataSource")
    private DataSource masterDataSource;

    @Resource(name = "slaveDataSource")
    private DataSource slaveDataSource;

    @Bean(name = "dynamicTransactionManager")
    public PlatformTransactionManager dynamicTransactionManager() {
        // 通过DynamicDataSource类中的两个数据源创建动态数据源
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource);
        Map<Object, Object> dataSourceMap = new HashMap<>(2);
        dataSourceMap.put("master", masterDataSource);
        dataSourceMap.put("slave", slaveDataSource);
        dynamicDataSource.setTargetDataSources(dataSourceMap);
        //设置当前线程使用的数据源,默认使用主数据源
        dynamicDataSource.afterPropertiesSet();
        return new DataSourceTransactionManager(dynamicDataSource);
    }

}

6. 配置动态数据源

com.example.demo.config包下创建DynamicDataSource类,并添加以下代码:

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.get();
    }
}

7. 配置数据源上下文

com.example.demo.config包下创建DataSourceContextHolder类,并添加以下代码:

public class DataSourceContextHolder {

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

    public static void set(String dataSourceType) {
        CONTEXT_HOLDER.set(dataSourceType);
    }

    public static String get() {
        return CONTEXT_HOLDER.get();
    }

    public static void clear() {
        CONTEXT_HOLDER.remove();
    }

    public static boolean isMaster() {
        return "master".equals(get());
    }

    public static boolean isSlave() {
        return "slave".equals(get());
    }
}

8. 配置AOP切面

com.example.demo.aspect包下创建DataSourceAspect类,并添加以下代码:

@Component
@Aspect
public class DataSourceAspect {
    @Pointcut("@annotation(com.example.demo.annotation.Slave)")
    public void dataSourceSlave() {
    }

    @Before("dataSourceSlave()")
    public void before(JoinPoint joinPoint){
        System.out.println("切换到从数据源");
        DataSourceContextHolder.set("slave");
    }

    @After("dataSourceSlave()")
    public void after(JoinPoint joinPoint){
        System.out.println("从数据源操作完成,切换回主数据源");
        DataSourceContextHolder.clear();
    }

}

9. 配置Mapper

com.example.demo.mapper包下创建UserMapper类,并添加以下代码:

@Mapper
public interface UserMapper extends BaseMapper<User> {
    @Slave
    List<User> selectAllFromSlave();
}

10. 测试代码

现在我们已经配置好了多数据源,下面就来测试一下吧。

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    void testMaster() {
        List<User> users = userMapper.selectList(null);
        System.out.println(users);
    }

    @Test
    void testSlave() {
        List<User> users = userMapper.selectAllFromSlave();
        System.out.println(users);
    }

}

运行以上测试代码,可以看到控制台输出如下:

[User(id=1, name=Tom, age=18), User(id=2, name=Jerry, age=21)]
切换到从数据源
[User(id=3, name=Kate, age=30), User(id=4, name=Lucy, age=25)]
从数据源操作完成,切换回主数据源

11. 示例说明

以上只是一个简单的示例,更多的多数据源配置方式也会有所不同。另外,上面的示例中,我们只是手动在代码中切换了从数据源,实际上我们可以通过配置MyBatis Plus来实现自动切换数据源。

例如,我们可以通过实现com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor接口来实现自动切换数据源,例如:

public class DynamicDataSourceInterceptor implements MybatisPlusInterceptor {

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

    public static void putDataSource(String name) {
        holder.set(name);
    }

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

    @Override
    public void intercept(SqlSession sqlSession, Invocation invocation) throws Throwable {
        String dataSourceName = holder.get();
        if (dataSourceName == null) {
            invocation.proceed();
            return;
        }
        DynamicDataSource dynamicDataSource = (DynamicDataSource) applicationContext.getBean("dynamicDataSource");
        dynamicDataSource.setDataSource(dataSourceName);
        try {
            invocation.proceed();
        } finally {
            dynamicDataSource.clearDataSource();
        }
    }

}

以上就是SpringBoot多数据源配置的全过程记录。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot多数据源配置的全过程记录 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • SpringBoot利用自定义注解实现多数据源

    搭建多数据源环境 首先,我们需要在pom.xml中引入所需依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </depen…

    Java 2023年5月20日
    00
  • MAC 命令行启动tomcat的详细介绍

    下面是启动 Tomcat 的详细攻略。 安装 Tomcat 在使用 MAC 命令行启动 Tomcat 之前,需要先安装 Tomcat。你可以在 Tomcat 的官网 https://tomcat.apache.org/ 下载最新版本的 Tomcat。安装方法如下: 将下载的 Tomcat 压缩包解压到你希望安装的目录中,例如 /opt/tomcat/。 打开…

    Java 2023年5月19日
    00
  • 利用asp或jsp,flash怎样把数据库中的一张表中的所有记录读取并显示出来

    要利用ASP或JSP,Flash将数据库中的一张表中的所有记录读取并显示出来,需要以下几个步骤: 连接数据库 首先需要先连接数据库。可以使用ASP中的ADODB对象,或JSP中的JDBC驱动来完成数据库连接。连接后,需要指定连接的数据库名称、服务器地址、用户名和密码等信息。 查询数据库 连接成功后,需要使用SQL语句查询数据。可以使用SELECT语句查询数据…

    Java 2023年6月16日
    00
  • spring学习教程之@ModelAttribute注解运用详解

    Spring学习教程之@ModelAttribute注解运用详解 在Spring框架中,@ModelAttribute注解用于将请求参数绑定到模型对象中。在本文中,我们将详细介绍@ModelAttribute注解的使用方法,并提供两个示例说明。 @ModelAttribute注解的使用方法 @ModelAttribute注解可以用于方法参数和方法上。当用于方…

    Java 2023年5月18日
    00
  • Mybatis自动创建表和更新表结构

    下面给您详细讲解Mybatis自动创建表和更新表结构的完整攻略。 什么是Mybatis Mybatis是一种基于Java语言的开源持久化框架,它的主要功能是将Java对象映射到关系型数据库。 Mybatis自动创建表和更新表结构的配置方法 配置实体类 首先我们需要在实体类中添加注解,用来指定表名、字段名和主键。 下面是一个示例: public class U…

    Java 2023年5月20日
    00
  • 浅析Redis中String数据类型及其底层编码

    浅析Redis中String数据类型及其底层编码 String数据类型介绍 Redis中String数据类型是最基本、最常用的数据类型之一,它可以保存字符串、整数或者浮点数。String类型可以进行增删改查等常见操作,支持的操作包括SET、GET、INCR等。 String数据类型底层编码 Redis中,对于每一种数据类型,都有对应的底层编码方式,Strin…

    Java 2023年6月1日
    00
  • 什么是Java对象关系映射(ORM)?

    Java对象关系映射(ORM)是一种理念,它将数据库中的关系数据模型转换为Java对象模型,并且提供了一种交互式的方式,使得Java程序可以访问和操作数据库,而不必使用SQL语言。ORM的使用可以大幅度减少代码的重复性,提高开发效率。 下面是一个基于ORM实现的小型Java Web应用的开发过程: 首先,我们需要选择一款Java ORM框架,常见的有Hibe…

    Java 2023年5月11日
    00
  • java实现动态时钟并设置闹钟功能

    Java实现动态时钟并设置闹钟功能 概述 本攻略将介绍如何使用Java语言实现一个动态时钟并设置闹钟功能。该时钟将会不断更新并显示当前的时间,并允许用户设置一个闹钟时间。当时钟时间到达设置的闹钟时间时,用户将会收到一条提示消息。 实现过程 步骤一:创建界面和布局 我们可以使用Swing工具箱来创建用户界面,如下所示: public class Clock e…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部