dynamic-datasource动态数据源学习

news2024/9/21 20:49:50

学习链接

spring整合mybatis的核心思路 & 数据源动态切换 & 多数据源事务控制 - 自己的链接(本篇文章的上篇)

Mybatisplus生成代码配置 & p6spy打印sql & mybatis日志打印 & mybatisplus用法

dynamic-datasource-spring-boot-starter 的gitee地址
dynamic-datasource官方文档(收费)(使用自己的qq登录即可)

SpringBoot多数据源

【Java多数据源实现教程】实现动态数据源、多数据源切换方式

springboot多数据源使用
SpringBoot实现多数据源(六)【dynamic-datasource 多数据源组件】
【Java多数据源实现教程】实现动态数据源、多数据源切换方式
Springboot多数据源配置详解
SpringBoot多数据源配置

基础介绍

简介

dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。

其支持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.x.x。

特性

  • 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
  • 支持数据库敏感配置信息 加密 ENC()。
  • 支持每个数据库独立初始化表结构schema和数据库database。
  • 支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。
  • 支持 自定义注解 ,需继承@DS(3.2.0+)。
  • 提供并简化对Druid,HikariCp,BeeCp,Dbcp2的快速集成。
  • 提供对Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等组件的集成方案。
  • 提供 自定义数据源来源 方案(如全从数据库加载)。
  • 提供项目启动后 动态增加移除数据源 方案。
  • 提供Mybatis环境下的 纯读写分离 方案。
  • 提供使用 spel动态参数 解析数据源方案。内置spel,session,header,支持自定义。
  • 支持 多层数据源嵌套切换 。(ServiceA >>> ServiceB >>> ServiceC)。
  • 提供 基于seata的分布式事务方案
  • 提供 本地多数据源事务方案(不能和原生spring事务混用)

约定

  • 本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
  • 配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称相同组名称的数据源会放在一个组下
  • 切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换
  • 默认的数据源名称为 master ,你可以通过 spring.datasource.dynamic.primary 修改。
  • 方法上的注解优先于类上注解
  • DS支持继承抽象类上的DS,暂不支持继承接口上的DS

使用方法

1. 引入dynamic-datasource-spring-boot-starter

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
  <version>${version}</version>
</dependency>

2. 配置数据源

以下会配置一个默认库master,一个组slave(组名)下有两个子库slave_1(组名为slave组下的数据源名称slave_1) 和 slave_2(组名为slave组下的数据源名称slave_2)

spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
        slave_1:
          url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_2:
          url: ENC(xxxxx) # 内置加密,使用请查看详细文档
          username: ENC(xxxxx)
          password: ENC(xxxxx)
          driver-class-name: com.mysql.jdbc.Driver
          
       #......省略

其它配置示例

# 多主多从                      纯粹多库(记得设置primary)                   混合配置
spring:                               spring:                               spring:
  datasource:                           datasource:                           datasource:
    dynamic:                              dynamic:                              dynamic:
      datasource:                           datasource:                           datasource:
        master_1:                             mysql:                                master:
        master_2:                             oracle:                               slave_1:
        slave_1:                              sqlserver:                            slave_2:
        slave_2:                              postgresql:                           oracle_1:
        slave_3:                              h2:                                   oracle_2:

3. 使用 @DS 切换数据源

@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解
在这里插入图片描述

@Service
@DS("slave")
public class UserServiceImpl implements UserService {

  @Autowired
  private JdbcTemplate jdbcTemplate;

  public List selectAll() {
    return  jdbcTemplate.queryForList("select * from user");
  }
  
  @Override
  @DS("slave_1")
  public List selectByCondition() {
    return  jdbcTemplate.queryForList("select * from user where age >10");
  }
}

数据源切换示例

简单演示下使用@DS注解,切换指定的数据源

准备数据库

准备2个数据库,一个m_db(作为主库),一个s_db(作为从库),这2个数据库中都有一张account表,表中仅有id和nick_name字段

CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nick_name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

pom.xml

导入mybatis-plus(不一定要用mybatis-plus,只是因为懒得自己写mapper.xml文件) 和 dynamic-datasource 的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

    <!--父工程-->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.8.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

    <!--项目GAV坐标-->
	<groupId>com.zzhua</groupId>
	<artifactId>sdynamic-datasource-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot-demo</name>
	<description>Demo project for Spring Boot</description>

    <!--版本-->
	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
        <!--web启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--mysql驱动-->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3</version>
        </dependency>

        <dependency>
            <groupId>p6spy</groupId>
            <artifactId>p6spy</artifactId>
            <version>3.9.1</version>
        </dependency>

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

        <!--swagger2依赖-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version> 2.7.0</version>
        </dependency>
        <!--swagger-ui第三方依赖-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.6</version>
        </dependency>


        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>


        <!--打开提示-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</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-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>
        </dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

application.yml

#spring:
#  datasource:
#    type: com.zaxxer.hikari.HikariDataSource
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://127.0.0.1:3306/m_db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
#    username: root
#    password: root

spring:
  datasource:
    dynamic:
      primary: master
      strict: true
      datasource:
        master:
          url: jdbc:mysql://127.0.0.1:3306/m_db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver
          hikari:
            min-idle: 2
            max-pool-size: 5
        # 使用下划线, 下划线前面的是组名,整个为数据源标识(若@DS中使用组名, 则会负载均衡该组名下的所有数据源)
        slave_1:
          url: jdbc:mysql://127.0.0.1:3306/s_db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath:mapper/**.xml

SpringbootDemoApplication

开启mybatis的mapper接口扫描

@SpringBootApplication
@MapperScan("com.zzhua.mapper")
public class SpringbootDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootDemoApplication.class, args);
	}

}

AccountController

@RestController
@RequestMapping("/account")
public class AccountController {

    @Autowired
    private IAccountService accountService;

    @RequestMapping("createAccount")
    public Object createAccount(@RequestParam("nickName") String nickName) {
        Account account = new Account();
        account.setNickName(nickName);
        accountService.addAccount(account);
        return "ok";
    }

    @RequestMapping("getAccounts")
    public List<Account> getAccounts() {
        return accountService.findAll();
    }


}

IAccountService

public interface IAccountService extends IService<Account> {

    void addAccount(Account account);

    List<Account> findAll();

}

AccountServiceImpl

@DS("master") // 方法中的@DS注解优先
@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements IAccountService {


    @Override
    public void addAccount(Account account) {
        this.save(account);
    }

    @Override
    @DS("slave") // 填写组名, 会负载均衡
    // @DS("slave_1")
    public List<Account> findAll() {
        return this.list();
    }


}

AccountMapper

public interface AccountMapper extends BaseMapper<Account> {

}

AccountMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzhua.mapper.AccountMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.zzhua.entity.Account">
        <id column="id" property="id" />
        <result column="nick_name" property="nickName" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, nick_name
    </sql>

</mapper>

测试

访问:http://localhost:8080/account/createAccount?nickName=m1,发现数据插入到了m_db数据库中
访问:http://localhost:8080/account/getAccounts,发现查询的是s_db数据库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/594380.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEWCompactRIO 开发指南第六章44 同步模块

同步模块 某些应用&#xff08;如振动或声音测量&#xff09;需要通道之间的高电平&#xff08;低于100nS&#xff09;同步。本节讨论基于增量Σ的模块和扫描&#xff08;SAR&#xff09;模块的时序和同步。任何未被归类为三角积分的NIC系列I/O模块都被归类为SAR。 同步增量西…

ThreadLocal源码

介绍 ThreadLocal是一个线程的本地变量&#xff0c;也就意味着这个变量是线程独有的&#xff0c;是不能与其他线程共享的。这样就可以避免资源竞争带来的多线程的问题。 但是&#xff0c;这种解决多线程安全问题的方式和加锁方式&#xff08;synchronized、Lock) 是有本质的区…

过来人建议:强烈安利本科生都去学Java编程!现在转行还不晚!

为什么标题这么说呢&#xff0c;因为Java的工资香啊&#xff0c;刚入门的小白就有 1w&#xff0c;转正后更多&#xff0c;而且越老越吃香&#xff01; 我们学一门技术在身&#xff0c;走到哪里都不怕&#xff0c;java是技术岗&#xff0c;不带销售性质&#xff0c;加班要分公司…

unity与oculus quest开发设置流程

目录 预准备quest项目的构建PC运行参考文章 版本&#xff1a; unity&#xff1a;2021 adb&#xff08;保证用USB连接PC和头显的时候能允许调试和数据访问&#xff09; macOS 当USB连接之后&#xff0c;需要带上头显将是否允许数据调试和访问的对话框选择允许。 文件中assets放…

2.6 Hello World 及简单语法规则

2.6 Hello World 及简单语法规则 新建文件夹&#xff0c;用于存放代码 新建一个Java文件 早期我们只是会建立txt文本文件&#xff0c;或者word&#xff0c;Java文件的后缀名是.java 新建Hello.java文件 // 输入Java代码public class Hello{public static void main(String[…

Vue3 小兔鲜:Pinia入门

Vue3 小兔鲜&#xff1a;Pinia入门 Date: May 11, 2023 Sum: Pinia概念、实现counter、getters、异步action、storeToRefs保持响应式解构 什么是Pinia Pinia 是 Vue 的专属状态管理库&#xff0c;可以实现跨组件或页面共享状态&#xff0c;是 vuex 状态管理工具的替代品&…

PHP7 连接数据库 MySQL8.0 报错 Call to undefined function mysqli_connect() 的解决方法

前提 如题所示使用的是PHP7的版本&#xff0c;连接MYSQL8.0数据库遇到的问题&#xff0c;提供我个人的解决办法。 我的报错是&#xff1a;Call to undefined function mysqli_connect() 首先明确 保证PHP与MySQL可以正常使用 访问localhost:80【或者你设置的端口号】是有页面…

shell编程之SNAT与DNAT的应用

SNAT与DNAT的应用 一、SNAT的介绍1.SNAT概述2.SNAT源地址转换过程二、SNAT转换 三、DNAT的介绍1.DNAT概述2.DNAT转换前提条件 四、DNAT的转换五、防火墙规则的备份和还原六、tcpdump抓包工具的运用 一、SNAT的介绍 SNAT&#xff08;SNAT&#xff09;一般指源地址转换 1.SNAT概…

VMware安装Centos7图形化GUI系统全过程

1、打开vmware&#xff0c;点击文件然后新建虚拟机 2、然后自定义直接下一步 3、下一步 4、这里我们稍后安装操作系统&#xff0c;继续下一步 5、随后选择Centos7 64位&#xff0c;继续下一步 6、选择你所需要安装的虚拟机存放的位置&#xff0c;虚拟机名字看自己来设置&#x…

docker-安装minio集群

目录 1.服务器列表 2.NTP时间同步 1.服务端 minio_01配置 2.客户端配置-minio_02、minio_03、minio_04配置 3.Minio集群 1.在对应的主机执行对应的语句 2.创建文件夹 3.创建容器 4.访问 5.查看集群 4.nginx代理集群192.168.1.3 1.nginx安装 2.访问代理 1.服务器列…

[web]关于过滤器Filter

前言 为了避免在没有登录的情况下也可以通过路径访问到所有页面&#xff0c; 如果在每一个需要请求的资源里面都通过Session去判断有没有登录的用户对象就需要书写大量的判断代码&#xff0c;此时就可以用到Filter过滤器 作用 让请求的某些资源在之前或之后经过过滤器&#xff…

uni-app路由配置使用和页面跳转传参

uni-app路由配置使用和页面跳转传参 uni-app路由配置使用和页面跳转传参 文章目录 uni-app路由配置使用和页面跳转传参前言一、组件式路由跳转传参二、函数式路由跳转传参总结 前言 UNI-APP学习系列之路由配置使用和页面跳转传参 一、组件式路由跳转传参 组件式路由跳转 示例…

Java设计模式(一)

系列文章目录 单一职责原则 接口隔离原则 依赖倒转原则 文章目录 系列文章目录前言一、单一职责原则1.单一职责原则注意事项和细节 二、接口隔离原则1.接口隔离原则基本介绍(Interface Segregation Principle)2.应传统方法的问题和使用接口隔离原则改进 三、依赖倒转原则1.依赖…

【Linux】——调试器-gdb的使用

序言&#xff1a; 本期&#xff0c;我将带领大家学习的关于linux下的调试器gdb的使用&#xff0c;废话不多说跟着我一起去看看吧&#xff01;&#xff01; 目录 前言 &#xff08;一&#xff09;背景介绍 1、debug模式和release模式 2、为什么Release不能调试但DeBug可以调…

nDreams CEO:是时候打破市场对VR游戏的错误认知了

自Quest系列头显问世以来&#xff0c;VR游戏市场仿佛被注入了一剂强心针&#xff0c;发展速度远超Rift时代。从Quest 1到现在&#xff0c;已经过去4年左右&#xff0c;现在VR游戏市场又走到了哪呢&#xff1f;在GDC 2023上&#xff0c;资深VR游戏工作室和发行商nDreams公布了一…

django-vue-admin-pro 使用

地址&#xff1a; GitHub - dvadmin-pro/django-vue-admin-pro 一、准备工作 Python > 3.8.0 (推荐3.9版本) nodejs > 14.0 (推荐最新) Mysql > 5.7.0 (可选&#xff0c;默认数据库sqlite3&#xff0c;推荐8.0版本) Redis(可选&#xff0c;最新版)项目运行及部署 |…

Android crash 流程详解(一):JE

源码基于&#xff1a;Android R 0. 前言 App crash(全称为 Application crash)&#xff0c;又分 java crash 和 native crash&#xff0c;又称 java layer exception(JE) 和 native layer exception(NE)。对于 crash 在开发过程中或多或少都会遇到&#xff0c;本文将整理总结 …

Shell脚本攻略:shell函数应用

目录 一、理论 1.shell函数 2.函数传参 3.函数变量的作用范围 4.递归 5.函数位置变量与脚本位置变量区别 6.创建库 二、实验 1.实验一 一、理论 1.shell函数 &#xff08;1&#xff09;概念 将命令序列按格式写在一起&#xff0c;可方便重复使用命令序列。 ① 避免…

JetBrains的Java集成开发环境IntelliJ 2023版本在Win10系统的下载与安装配置教程

目录 前言一、IntelliJ 安装二、使用配置总结 前言 IntelliJ IDEA Ultimate是一款功能强大的Java集成开发环境&#xff08;IDE&#xff09;。它提供了丰富的功能和工具&#xff0c;可以帮助开发人员更高效地编写、调试和部署Java应用程序。 IntelliJ IDEA Ultimate的主要特点…

Benewake(北醒) 快速实现TFmini-Plus-IIC与电脑通信的操作说明

目录 1. 概述2. 测试准备2.1 工具准备2.2通讯协议转换 3. IIC通讯测试3.1 引脚说明3.2 测试步骤3.2.1 TFmini-Plus-IIC 与 PC 建立连接3.2.2 获取测距值3.2.3 更改 slave 地址 1. 概述 通过本文档的概述&#xff0c;能够让初次使用测试者快速了解测试 IIC 通信协议需要的工具以…