Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring Boot2.x 动态数据源配置

Spring Boot2.x 动态数据源配置

原创
作者头像
壹言
修改于 2020-03-01 23:43:54
修改于 2020-03-01 23:43:54
1.4K00
代码可运行
举报
文章被收录于专栏:WorldhelloWorldhello
运行总次数:0
代码可运行

原文链接:Spring Boot2.x 动态数据源配置

基于 Spring Boot 2.x、Spring Data JPA、druid、mysql 的动态数据源配置Demo,适合用于数据库的读写分离等应用场景。通过在Service层方法上添加自定义注解实现读写不同的数据库。

配置文件已配置好druid监控相关属性,监控页面链接:ip:8080/druid。账号:admin,密码:123456。详情查看 application.yml 文件。

配置 pom.xml 文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
      <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
配置application.yml文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring:
  datasource:
    druid:
      primary:
        driverClassName: com.mysql.cj.jdbc.Driver
        username: root
        password: root
        url: jdbc:mysql://localhost:3306/primary?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
        filters: stat,wall
      local:
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: root
        url: jdbc:mysql://localhost:3306/local?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
        filters: stat,wall
      stat-view-servlet:
        enabled: true
        login-username: admin
        login-password: 123456
        reset-enable: false
        url-pattern: /druid/*
      web-stat-filter:
        enabled: true
        # 添加过滤规则
        url-pattern: /*
        # 忽略过滤格式
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
  jpa:
    database: MYSQL
    hibernate:
      show_sql: true
      format_sql: true
      primary-dialect: org.hibernate.dialect.MySQL5InnoDBDialect
      secondary-dialect: org.hibernate.dialect.MySQL5InnoDBDialect
      # 打开后会自动在主库生成表
      # ddl-auto: update
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    # 打开后会自动在主库生成表
    # generate-ddl: true
项目目录结构

目录结构

DataSource.java
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package dynamic.data.annotation;

import dynamic.data.common.ContextConst;

import java.lang.annotation.*;
/**
 * @Author: ChangXuan
 * @Decription:
 * @Date: 22:25 2020/2/23
 **/
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    ContextConst.DataSourceType value() default ContextConst.DataSourceType.PRIMARY;
}
DynamicDataSourceAspect.java
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package dynamic.data.aspect;

import dynamic.data.common.ContextConst;
import dynamic.data.datasource.DataSourceContextHolder;
import dynamic.data.annotation.DataSource;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
/**
 * @Author: ChangXuan
 * @Decription:
 * @Date: 22:28 2020/2/23
 **/
@Component
@Aspect
public class DynamicDataSourceAspect {
    @Before("execution(* dynamic.data.service..*.*(..))")
    public void before(JoinPoint point){
        try {
            DataSource annotationOfClass = point.getTarget().getClass().getAnnotation(DataSource.class);
            String methodName = point.getSignature().getName();
            Class[] parameterTypes = ((MethodSignature) point.getSignature()).getParameterTypes();
            Method method = point.getTarget().getClass().getMethod(methodName, parameterTypes);
            DataSource methodAnnotation = method.getAnnotation(DataSource.class);
            methodAnnotation = methodAnnotation == null ? annotationOfClass:methodAnnotation;
            ContextConst.DataSourceType dataSourceType = methodAnnotation != null && methodAnnotation.value() !=null ? methodAnnotation.value() :ContextConst.DataSourceType.PRIMARY ;
            DataSourceContextHolder.setDataSource(dataSourceType.name());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    @After("execution(* dynamic.data.service..*.*(..))")
    public void after(JoinPoint point){
        DataSourceContextHolder.clearDataSource();
    }
}
ContextConst.java
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package dynamic.data.common;

/**
 * @Author: ChangXuan
 * @Decription:
 * @Date: 22:17 2020/2/23
 **/
public interface ContextConst {
    enum DataSourceType{
        PRIMARY,LOCAL
    }
}
DataSourceContextHolder .java
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package dynamic.data.datasource;

/**
 * @Author: ChangXuan
 * @Decription:
 * @Date: 22:23 2020/2/23
 **/
public class DataSourceContextHolder {

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

    public static void setDataSource(String dbType){
        System.out.println("切换到["+dbType+"]数据源");
        contextHolder.set(dbType);
    }

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

    public static void clearDataSource(){
        contextHolder.remove();
    }
}
DynamicDataSource.java
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package dynamic.data.datasource;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * @Author: ChangXuan
 * @Decription:
 * @Date: 22:22 2020/2/23
 **/
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSource();
    }
}
MutiplyDataSource.java
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package dynamic.data.datasource;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import dynamic.data.common.ContextConst;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
/**
 * @Author: ChangXuan
 * @Decription:
 * @Date: 22:15 2020/2/23
 **/
@Configuration
public class MutiplyDataSource {
    @Bean(name = "dataSourcePrimary")
    @ConfigurationProperties(prefix = "spring.datasource.druid.primary")
    public DataSource primaryDataSource(){
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "dataSourceLocal")
    @ConfigurationProperties(prefix = "spring.datasource.druid.local")
    public DataSource localDataSource(){
        return DruidDataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        //配置默认数据源
        dynamicDataSource.setDefaultTargetDataSource(primaryDataSource());

        //配置多数据源
        HashMap<Object, Object> dataSourceMap = new HashMap();
        dataSourceMap.put(ContextConst.DataSourceType.PRIMARY.name(),primaryDataSource());
        dataSourceMap.put(ContextConst.DataSourceType.LOCAL.name(),localDataSource());
        dynamicDataSource.setTargetDataSources(dataSourceMap);
        return dynamicDataSource;
    }

    /**
     * 配置@Transactional注解事务
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dynamicDataSource());
    }
}
使用

在 DynamicDataSourceAspect.java 中配置的service下使用注解的方式指定执行的方法使用哪个数据库。示例参考下方代码:

使用示例

primary数据库数据
primary数据库数据
local 数据库数据
local 数据库数据

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring Boot + Mybatis 实现动态数据源
在很多具体应用场景的时候,我们需要用到动态数据源的情况,比如多租户的场景,系统登录时需要根据用户信息切换到用户对应的数据库。又比如业务A要访问A数据库,业务B要访问B数据库等,都可以使用动态数据源方案进行解决。接下来,我们就来讲解如何实现动态数据源,以及在过程中剖析动态数据源背后的实现原理。
朝雨忆轻尘
2019/06/18
1.7K0
Springboot之多数据源的配置使用
现在的企业服务逐渐地呈现出数据的指数级增长趋势,无论从数据库的选型还是搭建,大多数的团队都开始考虑多样化的数据库来支撑存储服务。例如分布式数据库、Nosql数据库、内存数据库、关系型数据库等等。再到后端开发来说,服务的增多,必定需要考虑到多数据源的切换使用来兼容服务之间的调用。为解决这一难题,今天就来分享一个关于多数据源的切换使用配置。
23号杂货铺
2019/09/26
1.6K0
SpringBoot 实现动态数据源切换
Spring Boot + Mybatis Plus + Druid + MySQL 实现动态数据源切换及动态 SQL 语句执行。
默存
2022/06/24
2.1K0
(43). Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】
在上一篇我们介绍了多数据源,但是我们会发现在实际中我们很少直接获取数据源对象进行操作,我们常用的是jdbcTemplate或者是jpa进行操作数据库。那么这一节我们将要介绍怎么进行多数据源动态切换。添加本文实现的代码之后,只需要配置要数据源就可以直接通过注解使用,在实际使用的时候特别的简单。那么本章主要分以下几个步骤进行实战。
用户1225216
2019/05/26
9390
基于自定义注解和Aop动态数据源配置
基于自定义注解和Aop动态数据源配置         在实际项目中,经常会因为需要增强数据库并发能力而设计分库分表或者读写分离等策略,每在旧项目中引进新技术的时候都会带来一系列的问题,我们的目的就是去解决问题,带着思考方式去重构系统,从中找到乐趣,对应引进自定义注解和Aop动态数据源配置技术带来的问题,我会在文章末尾介绍,也希望大神给予正确的引导,我们当时的需求就是:有一个XXX旧系统,我们在这个旧系统的基础上开发一个PC端的程序用于收银;对方提供他们的数据库文档和对接人员,旧系统代码他们不给,我们只能通过
秋日芒草
2018/05/15
1.5K0
Spring Boot从入门到精通-mybatis多数据源
启动项目,调用controller中的接口,从控制台的输出可以看到数据源已经实现了动态切换。
我的小熊不见了丶
2019/05/22
5150
Spring Boot:实现MyBatis动态数据源
在很多具体应用场景中,我们需要用到动态数据源的情况,比如多租户的场景,系统登录时需要根据用户信息切换到用户对应的数据库。又比如业务A要访问A数据库,业务B要访问B数据库等,都可以使用动态数据源方案进行解决。接下来,我们就来讲解如何实现动态数据源,以及在过程中剖析动态数据源背后的实现原理。
朝雨忆轻尘
2019/06/19
2K0
Spring Boot:实现MyBatis动态数据源
Spring Boot2.x-09 基于Spring Boot 2.1.2 + Mybatis使用自定义注解实现数据库切换
之前总结过一篇基于Spring的 数据库切换的文章:Spring-基于Spring使用自定义注解及Aspect实现数据库切换 ,新的项目一般都直接采用SpringBoot开发了,那我们也用Spring Boot来整一版吧。
小小工匠
2021/08/17
7250
spring-boot使用aop进行多数据源切换
创建一个spring boot项目,并引入druid mysql aop等相关依赖
earthchen
2020/09/24
1.2K0
springboot动态多数据源
参考文章:https://www.cnblogs.com/hehehaha/p/6147096.html
用户1225216
2019/05/25
9930
Spring Boot MyBatis 动态数据源切换、多数据源,读写分离
项目地址: https://github.com/helloworlde/SpringBoot-DynamicDataSource
JAVA葵花宝典
2019/06/11
2K0
Spring boot 整合dynamic实现多数据源
项目git地址:git 准备工作 # 创建数据库db1 CREATE DATABASE `db1`CHARACTER SET utf8 COLLATE utf8_bin # 创建user表 CREATE TABLE `user` ( `id` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 # 添加数据 INSERT INTO `db1`.`user` (`id`,
Jacob丶
2020/08/05
1.6K0
Spring boot 整合dynamic实现多数据源
【详解】JavaSpringMVC+MyBitis+多数据源切换
在企业级应用开发中,经常需要处理来自不同数据库的数据。为了满足这一需求,我们可以通过配置多个数据源来实现对不同数据库的访问。本文将介绍如何在Spring MVC框架下结合MyBatis实现多数据源的动态切换。
大盘鸡拌面
2025/01/19
1700
Spring Boot中实现多数据源连接和切换的方案
在Spring Boot中,通过AbstractRoutingDataSource实现多数据源连接是一种常见的做法。这种技术允许你在运行时动态地切换数据源,从而支持对多个数据库的操作。Spring Boot中配置和使用AbstractRoutingDataSource来实现多数据源连接。
公众号:码到三十五
2024/11/04
6910
Spring Boot 中 Druid 连接池与多数据源切换的方法
❃博主首页 : 「码到三十五」 ,同名公众号 :「码到三十五」,wx号 : 「liwu0213」 ☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基
公众号:码到三十五
2024/11/18
2390
spring boot多数据源的代码实现
SpringBootDynamicDatasourceStartedApplication
MickyInvQ
2020/09/27
5610
Mybatis多数据源动态切换,原来这么简单!
首先需要建立两个库进行测试,我这里使用的是master_test和slave_test两个库,两张库都有一张同样的表(偷懒),表名 t_user
Bug开发工程师
2019/09/25
14.1K1
Mybatis多数据源动态切换,原来这么简单!
使用springboot + druid + mybatisplus完成多数据源配置「建议收藏」
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说使用springboot + druid + mybatisplus完成多数据源配置「建议收藏」,希望能够帮助大家进步!!!
Java架构师必看
2022/02/10
4.2K0
使用springboot + druid + mybatisplus完成多数据源配置「建议收藏」
SpringBoot系列-- Mybatis配合AOP和注解实现动态数据源切换配置
随着应用用户数量的增加,相应的并发请求的数量也会跟着不断增加,慢慢地,单个数据库已经没有办法满足我们频繁的数据库操作请求了。
田维常
2020/02/13
1.1K0
SpringBoot系列-- Mybatis配合AOP和注解实现动态数据源切换配置
Spring多数据源事务
接着上一篇文章Spring事务基础,本文主要是关于Spring多数据源的情况下如何保证事务正常回滚。这里也是使用大家广泛使用的jta-atomikos进行,我只是做一些总结方便以后自己直接拿来用。
用户3467126
2020/01/13
1K0
Spring多数据源事务
推荐阅读
相关推荐
Spring Boot + Mybatis 实现动态数据源
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验