SpringBoot通过自定义注解实现多数据源

这篇具有很好参考价值的文章主要介绍了SpringBoot通过自定义注解实现多数据源。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringBoot通过自定义注解实现多数据源,实战案例,spring boot,后端,java

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉
🍎个人主页:Leo的博客
💞当前专栏: Java从入门到精通
✨特色专栏: MySQL学习
🥭本文内容:SpringBoot通过自定义注解实现多数据源
📚个人知识库: Leo知识库,欢迎大家访问

1.前言☕

大家好,我是Leo哥🫣🫣🫣,今天继续带来一篇关于SpringBoot实现多数据源的实战案例。好了,话不多说让我们开始吧😎😎😎。

2.概述

在实际开发中,我们往往面临一个应用需要访问多个数据库的情况。例如下面两种场景。

  • 业务复杂: 数据分布在不同的数据库,数据库拆了,应用没拆,一个公司有多个子项目,各用各的数据库。

  • 写分离: 为了解决数据库的读性能瓶颈(读比写性能更高,写锁会影响读阻塞,从而影响读的性能)

    很多数据库拥有主从架构,也就是说,一台 主数据库服务器,是对外提供增删改查业务的生产服务器;

    另一台从数据库服务器,主要进行读的操作。

    读写分离:解决高并发下读写受影响。数据更新在主库上进行,主库将数据变更信息同步给从库。在查询时,在从库上进行,从而分担主库的压力。

我们可以在代码层面解决这种动态数据源切换的问题,而不需要使用 mycatshardingJDBC 等其他中间件。本文将主要以自定义注解 + 继承 AbstractRoutingDataSource 实现读写分离。

3.如何实现多数据源

SpringBoot 项目中实现读写分离通常需要以下几步:

  1. 配置数据源:你需要为读操作和写操作分别配置一个数据源。
  2. 创建数据源路由逻辑:这通常通过扩展 Spring 的 AbstractRoutingDataSource 来实现。它允许你根据一定的逻辑来决定使用哪个数据源(读或写)。
  3. 配置事务管理器:这使得你能够在使用不同数据源时保持事务的一致性。
  4. 服务层或DAO层设计:确保在执行读操作时使用读数据源,在执行写操作时使用写数据源。
  5. 自定义切面,在切面中解析 @DataSource 注解。当一个方法或者类上面,有 @DataSource 注解的时候,将 @DataSource 注解所标记的数据源列出来存入到 ThreadLocal 中。

注意:这里使用ThreadLocal的原因是为了保证我们的线程安全。

4.案例实现

接下来我们就按照以上步骤进行编码实现。

4.1 创建新模块

首先我们创建一个新的模块命名为:springboot-dynamic-source

SpringBoot通过自定义注解实现多数据源,实战案例,spring boot,后端,java

1.导入依赖
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <!--mybatis plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
    </dependencies>
2.创建yml配置文件
server:
  port: 8007


spring:
  application:
    name:  dynamic-source
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    ds:
      # 主库数据源
      master:
        url: jdbc:mysql://localhost:3307/test01?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: root
      # 从库数据源
      slave:
        url: jdbc:mysql://localhost:3307/test02?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: root
    # 初始连接数
    initialSize: 5
    # 最小连接池数量
    minIdle: 10
    # 最大连接池数量
    maxActive: 20
    # 配置获取连接等待超时的时间
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    # 配置一个连接在池中最大生存的时间,单位是毫秒
    maxEvictableIdleTimeMillis: 900000
    # 配置检测连接是否有效
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    webStatFilter:
      enabled: true
    statViewServlet:
      enabled: true
      # 设置白名单,不填则允许所有访问
      allow:
      url-pattern: /druid/*
      # 控制台管理用户名和密码
      login-username: admin
      login-password: 123456
    filter:
      stat:
        enabled: true
        # 慢SQL记录
        log-slow-sql: true
        slow-sql-millis: 1000
        merge-sql: true
      wall:
        config:
          multi-statement-allow: true


logging:
  level:
    org.javatop: debug
  pattern:
    dateformat: HH:mm:ss:SSS
  file:
    path: "logs/${spring.application.name}"

ds 中是我们的所有数据源。master 是默认的数据源,不可修改,其他的数据源可以修改并添加多个。

3.准备数据库

我这里需要提前准备两个数据库,一个是主数据库master,一个是从数据库slave。

我们会后面会通过一个自定义注解去实现动态切换数据库。

这里给出我们创建的一个user表的SQL语句。

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

4.2 加载数据源

我们可以通过@ConfigurationProperties 注解加载定义的配置文件。spring.datasource 对应的注解都会匹配到。

package org.javatop.dynamic.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;

import javax.sql.DataSource;
import java.util.Map;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:10
 * @description :
 */
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidProperties {
    private String type;
    private String driverClassName;
    private Map<String, Map<String,String>> ds;

    private Integer initialSize;
    private Integer minIdle;
    private Integer maxActive;
    private Integer maxWait;

    /**
     *一会在外部构建好一个 DruidDataSource 对象,包含三个核心属性 url、username、password
     * 在这个方法中设置公共属性
     * @param druidDataSource
     * @return
     */
    public DataSource dataSource(DruidDataSource druidDataSource){
        druidDataSource.setInitialSize(initialSize);
        druidDataSource.setMinIdle(minIdle);
        druidDataSource.setMaxActive(maxActive);
        druidDataSource.setMaxWait(maxWait);
        return druidDataSource;
    }
    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public Map<String, Map<String, String>> getDs() {
        return ds;
    }

    public void setDs(Map<String, Map<String, String>> ds) {
        this.ds = ds;
    }

    public Integer getInitialSize() {
        return initialSize;
    }

    public void setInitialSize(Integer initialSize) {
        this.initialSize = initialSize;
    }

    public Integer getMinIdle() {
        return minIdle;
    }

    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }

    public Integer getMaxActive() {
        return maxActive;
    }

    public void setMaxActive(Integer maxActive) {
        this.maxActive = maxActive;
    }

    public Integer getMaxWait() {
        return maxWait;
    }

    public void setMaxWait(Integer maxWait) {
        this.maxWait = maxWait;
    }
}

然后我们开始通过进行加载DruidProperties来加载数据源。

@EnableConfigurationProperties :这个注解的意思是使 ConfigurationProperties 注解生效。

package org.javatop.dynamic.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:12
 * @description : 加载数据源
 */

@Component
@EnableConfigurationProperties(DruidProperties.class)
public class LoadDataSource {

    @Autowired
    DruidProperties druidProperties;

    public Map<String, DataSource> loadAllDataSource()   {
        Map<String, DataSource> map =new HashMap<>();
        Map<String, Map<String, String>> ds = druidProperties.getDs();
        try {
            Set<String> keySet = ds.keySet();
            for (String key : keySet) {
                map.put(key, druidProperties.dataSource((DruidDataSource) DruidDataSourceFactory.createDataSource(ds.get(key))));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
}

loadAllDataSource() 方法可以通过读取application.yml配置文件中所有数据源对象。(我们这里有一个master主数据库,和一个slave从数据库)

druidProperties.dataSource(DruidDataSource druidDataSource) 这个方法为每个数据源配置其他额外的属性(最大连接池等信息)。

DruidDataSourceFactory.createDataSource(ds.get(key):创建一个数据源,赋予三个核心的属性。(username、url、password)

最终,所有的数据源都会存入map中。

4.3 自定义ThreadLocal工具类

我们这里定义一个简单的ThreadLocal工具类

package org.javatop.dynamic.utils;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:13
 * @description : ThreadLocal工具类
 */
public class DynamicDataSourceUtil {

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

    public static void setDataSourceType(String dsType){
        CONTEXT_HOLDER.set(dsType);
    }
    public static String getDataSourceType(){
        return CONTEXT_HOLDER.get();
    }

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

4.4 自定义注解

首先需要通过一个枚举类来设定一下我们的默认数据源,也是是master主数据库。

package org.javatop.dynamic.constant;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:13
 * @description :
 */
public interface DataSourceType {
    String default_ds_name ="master";
}

然后自定义一个注解,后面也就是通过这个注解来动态的配置切换我们的数据源,这里就也叫Datasource吧。

package org.javatop.dynamic.annotation;

import org.javatop.dynamic.constant.DataSourceType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:14
 * @description :  这个注解将来可以加在某一个 service 类上或者方法上,通过 value 属性来指定类或者方法应该使用哪个数据源
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface DataSource{

    /**
     * 如果一个方法上加了 @DataSource 注解,但是却没有指定数据源的名称,那么默认使用 Master 数据源
     * @return
     */
    String value() default DataSourceType.default_ds_name;
}

4.5 AOP解析自定义注解

package org.javatop.dynamic.annotation;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.javatop.dynamic.utils.DynamicDataSourceUtil;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:15
 * @description : AOP解析自定义注解
 */
@Component
@Aspect
public class DataSourceAspect {


    /**
     * @annotation(org.javatop.dynamic.annotation.DataSource) 表示方法上有 @DataSource 注解 就将方法拦截下来。
     * @within :如果类上面有 @DataSource 注解,就将类中的方法拦截下来。
     */
    @Pointcut("@annotation(org.javatop.dynamic.annotation.DataSource) || " +
            "@within(org.javatop.dynamic.annotation.DataSource)")
    public void pc(){

    }

    @Around("pc()")
    public Object around(ProceedingJoinPoint point){
        //获取方法上面的注解
        DataSource dataSource =getDataSource(point);
        if(dataSource!=null){
            // 注解中数据源的名称
            String value = dataSource.value();
            DynamicDataSourceUtil.setDataSourceType(value);
        }
        try {
            return point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }finally {
            DynamicDataSourceUtil.clear();
        }
        return null;
    }

    private DataSource getDataSource(ProceedingJoinPoint point) {
        /**
         * 先去查找方法上的注解,如果没有,再去类中找。
         */
        MethodSignature signature = (MethodSignature)point.getSignature();
        DataSource annotation = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if(annotation!=null){
            return annotation;
        }
        return AnnotationUtils.findAnnotation(signature.getDeclaringType(),DataSource.class);
    }
}
@Pointcut 定义
@Pointcut("@annotation(org.javatop.dynamic.annotation.DataSource) || " +
          "@within(org.javatop.dynamic.annotation.DataSource)")
public void pc() {

}
  • @Pointcut 是一个定义在方法上的注解,用来指定一个切点(即在何处进行拦截)。
  • "@annotation(org.javatop.dynamic.annotation.DataSource)" 表示拦截所有被 @DataSource 注解标记的方法。
  • "@within(org.javatop.dynamic.annotation.DataSource)" 表示拦截所有在类级别被 @DataSource 注解标记的类中的方法。
  • pc() 方法本身是空的,因为所有的逻辑都将在与这个切点相关的通知(advice)中定义。
@Around 通知
e@Around("pc()")
public Object around(ProceedingJoinPoint point) {
    DataSource dataSource = getDataSource(point);
    if (dataSource != null) {
        String value = dataSource.value();
        DynamicDataSourceUtil.setDataSourceType(value);
    }
    try {
        return point.proceed();
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    } finally {
        DynamicDataSourceUtil.clear();
    }
    return null;
}
  • @Around("pc()") 表示这是一个环绕通知,它会在 pc() 方法所定义的切点前后执行。
  • ProceedingJoinPoint point 是连接点的信息,它包含了方法的所有相关信息,如方法名、参数等。
  • getDataSource(point) 用来获取方法或类上的 @DataSource 注解。
  • 如果存在 @DataSource 注解,它会从注解中获取数据源的名称,并通过 DynamicDataSourceUtil.setDataSourceType(value) 设置当前线程的数据源。
  • point.proceed() 是调用原始方法的地方。
  • finally 块中的 DynamicDataSourceUtil.clear() 用于在方法执行完毕后清理数据源设置,确保不会影响其他的数据库操作。

最后获取@DataSource注解

4.6 自定义动态数据源

package org.javatop.dynamic.config;

import org.javatop.dynamic.constant.DataSourceType;
import org.javatop.dynamic.utils.DynamicDataSourceUtil;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:18
 * @description : 定义动态数据源
 */
@Component
public class DynamicDataSource extends AbstractRoutingDataSource {

    public DynamicDataSource(LoadDataSource loadDataSource) {
        // 1、设置所有的数据源
        Map<String, DataSource> stringDataSourceMap = loadDataSource.loadAllDataSource();
        super.setTargetDataSources(new HashMap<>(stringDataSourceMap));
        // 2、设置默认的数据源
        super.setDefaultTargetDataSource(stringDataSourceMap.get(DataSourceType.default_ds_name));

        super.afterPropertiesSet();
    }

    /**
     * 这个方法用来返回数据源名称,当系统需要获取数据源的时候,会自动调用该方法获取数据源的名称
     * @return
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceUtil.getDataSourceType();
    }
}
  1. DynamicDataSource 类扩展自 AbstractRoutingDataSource 类,这是Spring框架提供的一个抽象类,用于实现数据源的动态路由。
  2. 构造函数 public DynamicDataSource(LoadDataSource loadDataSource) 接收一个 LoadDataSource 类型的参数。这个参数被用于加载所有的数据源配置。
    • Map<String, DataSource> stringDataSourceMap = loadDataSource.loadAllDataSource(); 这行代码调用了 loadDataSourceloadAllDataSource 方法来加载所有数据源配置,并将其存储在一个名为 stringDataSourceMap 的Map中,其中键是数据源的名称,值是对应的 DataSource 对象。
    • super.setTargetDataSources(new HashMap<>(stringDataSourceMap)); 这行代码设置了目标数据源。它将前面加载的所有数据源 stringDataSourceMap 设置为目标数据源。
    • super.setDefaultTargetDataSource(stringDataSourceMap.get(DataSourceType.default_ds_name)); 这行代码设置了默认的数据源。它通过 DataSourceType.default_ds_namestringDataSourceMap 中获取默认的数据源,并设置为默认数据源。
    • super.afterPropertiesSet(); 是一个初始化方法,确保所有属性都被正确设置。
  3. determineCurrentLookupKey() 方法是 AbstractRoutingDataSource 的一个抽象方法,必须要实现。这个方法用于决定使用哪个数据源,通常情况下是根据某种条件动态返回数据源名称。
    • return DynamicDataSourceUtil.getDataSourceType(); 这行代码返回当前线程所使用的数据源的名称。DynamicDataSourceUtil 是一个工具类,可能提供了线程局部变量(ThreadLocal)来存储每个线程所选择的数据源名称。

这样,当应用程序需要与数据库进行交互时,就会通过 DynamicDataSource 获取到当前线程所指定的数据源,并进行相应的数据库操作。这种方式能够在不同业务场景中灵活切换数据源,非常适合多租户、读写分离等复杂的数据库应用场景。

4.7 编写业务层

我们编写一个service层

package org.javatop.dynamic.service;

import org.javatop.dynamic.annotation.DataSource;
import org.javatop.dynamic.domain.User;
import org.javatop.dynamic.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:26
 * @description :
 */
@Service
public class UserService{
    @Autowired
    private UserMapper userMapper;

    @DataSource("slave")
//    @DataSource
    public List<User> getAll(){
        List<User> all = userMapper.getAll();
        return all;
    }
}

我们在getAll()方法上加上@DataSource(“slave”),并指定slave从数据库。

然后再编写一个mapper,去操作数据库。

package org.javatop.dynamic.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.javatop.dynamic.domain.User;

import java.util.List;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:26
 * @description :
 */
@Mapper
public interface UserMapper {
    @Select("select * from user")
    List<User> getAll();
}

4.8 测试

package org.javatop.dynamic;

import org.javatop.dynamic.domain.User;
import org.javatop.dynamic.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

/**
 * @author : Leo
 * @version 1.0
 * @date 2024-01-02 15:32
 * @description :
 */
@SpringBootTest
public class DynamicTest {

    @Autowired
    private UserService userService;

    /**
     *  用于测试:
     */
    @Test
    public void test() {
        List<User> all = userService.getAll();
        if(all !=null){
            for (User user : all) {
                System.out.println(user);
            }
        }
    }
}

我们查看控制台。

SpringBoot通过自定义注解实现多数据源,实战案例,spring boot,后端,java

SpringBoot通过自定义注解实现多数据源,实战案例,spring boot,后端,java

可以看出来我们去查询的是test02库中的user数据。

大功告成!!!

5.总结🍭

以上便是本文的全部内容,本人才疏学浅,文章有什么错误的地方,欢迎大佬们批评指正!我是Leo,一个在互联网行业的小白,立志成为更好的自己。

如果你想了解更多关于Leo,可以关注公众号-程序员Leo,后面文章会首先同步至公众号。

SpringBoot通过自定义注解实现多数据源,实战案例,spring boot,后端,java文章来源地址https://www.toymoban.com/news/detail-779743.html

到了这里,关于SpringBoot通过自定义注解实现多数据源的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot整合Druid数据库连接池&多数据源&注解切换&动态添加

    配置好之后 Druid 会通过 DruidDataSourceAutoConfigure 自动装配 属性配置 数据源枚举 动态数据源 继承 AbstractRoutingDataSource 就可以实现动态数据源了 实现了一个动态数据源类的构造方法,主要是为了设置默认数据源,以及以Map保存的各种目标数据源。其中Map的key是设置的数据源名称

    2024年03月22日
    浏览(68)
  • SpringBoot+MyBatis-Plus多数据源@DS注解失效的解决方法

    引入 dynamic-datasource: application.yml 数据源配置: 详细使用请看 MyBatis-Plus官网 这种场景还是比较常见,比如在一个为master数据源的调用slave数据源就会失效 slave数据源Service方法 mater数据源Service方法调用slave数据源Service方法 这里会出现没有走slave_1,依然还是master数据源 需要在

    2024年01月18日
    浏览(52)
  • Spring 多数据源方法级别注解实现

    Spring框架提供了多种数据源管理方式,其中多数据源管理是其中之一。多数据源管理允许应用程序使用多个数据源,而不是只使用一个数据源,从而提高了应用程序的灵活性和可靠性。 多数据源管理的主要目的是让应用程序能够在不同的数据库之间切换,以满足不同的业务需

    2024年02月15日
    浏览(60)
  • springboot多数据源支持自定义连接池

    springboot 多数据源网上的文章很多,但大多都是互相抄袭,虽然可以实现多数据源的效果,但都是使用的默认的连接池,如果盲目使用可能会导致自定义的连接池参数没生效从而引发数据库连接问题。下面是参考官方文档多数据源支持自定义连接池的配置。 https://docs.spring.i

    2024年01月20日
    浏览(48)
  • springboot配置自定义数据源(Druid德鲁伊)的步骤。

    今天和大家分享下在Springboot中配置自定义数据源Druid的两种方法及步骤。 方法一: 1.在pom.xml配置依赖(注释里面的内容) 2.配置自己的数据源设置,我是在yaml文件中配置的,顺便提醒一下,在配置yaml文件的时候缩进问题一定要注意,不然无法读取到就会报错。 spring: datasourc

    2024年02月15日
    浏览(58)
  • java_Springboot_Mybatis-Plus_自定义多数据源MybatisSqlSessionFactoryBean配置

    需要在服务中集成表结构维护的功能,维护表结构就需要使用具有执行DDL脚本权限的账号。 为了保证系统的安全性,考虑在工程中配置多个数据源引入不同权限账号,高权限账号只在特定逻辑中使用,其它默认业务使用低权限账号。 加入新的数据源不能影响已有的功能,保

    2024年01月16日
    浏览(45)
  • springboot+mybatis实现多数据源

    最近做项目碰到了一个需要连4个不同数据库的需求,其中db1、db2表结构都不相同;另外两个数据库same_db_private、same_db_public表结构完全相同,一个对内一个对外,只是从物理上隔离了数据而已。 所以打算通过静态配置包路径的方式来实现db1、db2的操作,并且通过扩展Spring的

    2024年02月09日
    浏览(43)
  • springboot 多数据源的2种实现

    这里介绍2种多数据源: 固定数据源 动态数据源 业务场景:项目涉及多个数据库,比如本项目数据库、财务系统数据库、物资系统数据库。系统需要操作多个数据库。 1.1 分别定义各个数据源 第1个数据源: dataSourceMySql 第2个数据源: dataSource2 第3个数据源: dataSource3 1.2 动态

    2024年02月07日
    浏览(41)
  • MyBatis整合Springboot多数据源实现

    数据源,实际就是数据库连接池,负责管理数据库连接,在 Springboot 中,数据源通常以一个 bean 的形式存在于 IOC 容器中,也就是我们可以通过依赖注入的方式拿到数据源,然后再从数据源中获取数据库连接。 那么什么是多数据源呢,其实就是 IOC 容器中有多个数据源的 bea

    2023年04月22日
    浏览(65)
  • SpringBoot结合MyBatis实现多数据源配置

    SpringBoot框架实现多数据源操作,首先需要搭建Mybatis的运行环境。 由于是多数据源,也就是要有多个数据库,所以,我们创建两个测试数据库,分别是:【sp-demo01】和【sp-demo02】,如下图所示: 具体SQL代码: 创建【sp-demo01】数据库。 创建【sp-demo02】数据库。 MyBatis框架中,

    2024年02月09日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包