mybatisplus快速实现动态数据源切换

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

1.背景
 

  通常一个系统只需要连接一个数据库就可以了。但是在企业应用的开发中往往会和其他子系统交互,特别是对于一些数据实时性要求比较高的数据,我们就需要做实时连接查询,而不是做同步。这个时候就需要用到多数据源。
 

  举个简单的例子某企业要做订单网上订单系统这里面就可以涉及到多个子系统的连接,比如:产品主数据的数据源,项目管理系统的数据源(项目可以产品订单)等多个不同数据库类似的数据源,他们可能是ORACLE,SQL SERVER,MYSQL等多种混合数据源。
 

  2.多数据源概述
 

  基于以上的背景,就会选择使用多个数据源,一个数据源用于读一个数据源用于写。或者不同的数据源混合使用。他的基本思想其实就是AOP。我们可以通过AOP的思想实现动态数据源切换,通过这个AOP思想可适用于多种场景、纯粹多库、读写分离、一主多从、混合模式等。

  动态数据源能进行自动切换的核心就是spring底层的AbstractRoutingDataSource进行数据源的路由,只要继承了这个类均可看作是一个数据源的实现。主要实现方法是determineCurrentLookupkey,该方法只需要返回数据源实例名称。
 

  3.mybatisplus多数据源
 

  我们在项目中用mybatisplus的使用用得比较多,这个动态数据源切换需要实现的话,比较麻烦,如果有现成的框架使用则最好不过了。恰好mybatiplus就能实现。文档地址如下:
 

  ```properties

  https://baomidou.com/pages/a61e1b/#%E6%96%87%E6%A1%A3-documentation

  https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611

  ```

  4.使用
 

  4.1介绍
 

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

  特性:

  -支持**数据源分组**,适用于多种场景纯粹多库读写分离一主多从混合模式。

  -支持数据库敏感配置信息**加密**ENC。

  -支持每个数据库独立初始化表结构schema和数据库database。

  -支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。

  -支持**自定义注解**,需继承DS3.2.0+。

  -提供并简化对Druid,HikariCp,BeeCp,Dbcp2的快速集成。

  -提供对Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等组件的集成方案。

  -提供**自定义数据源来源**方案(如全从数据库加载)。

  -提供项目启动后**动态增加移除数据源**方案。

  -提供Mybatis环境下的**纯读写分离**方案。

  -提供使用**spel动态参数**解析数据源方案。内置spel,session,header,支持自定义。

  -支持**多层数据源嵌套切换**。(ServiceA>>>ServiceB>>>ServiceC)。

  -提供**基于seata的分布式事务方案。

  -提供**本地多数据源事务方案。**
 

  4.2 约定
 

  1.本框架只做**切换数据源**这件核心的事情,并**不限制你的具体操作**,切换了数据源可以做任何CRUD。

  2.配置文件所有以下划线`_`分割的数据源**首部**即为组的名称,相同组名称的数据源会放在一个组下。

  3.切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换。

  4.默认的数据源名称为**master**,你可以通过`spring.datasource.dynamic.primary`修改。

  5.方法上的注解优先于类上注解。

  6.DS支持继承抽象类上的DS,暂不支持继承接口上的DS。
 

  4.3 使用
 

  4.3.1准备数据库

 docker run --name mysq -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql:5.7

  创建2个数据库

create database test1;
create database test2;


use test2;

-- auto-generated definition
create table tb_user
(
    id   int auto_increment
        primary key,
    name varchar(200) null
);

insert into tb_user values(1,"wangwu");


use test1;

-- auto-generated definition
create table tb_user
(
    id   int auto_increment
        primary key,
    name varchar(200) null
);
insert into tb_user values(1,"zhangsan");

  一个作为主库一个作为从库。
 

  4.3.2 springboot创建工程
 

  添加依赖:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima</groupId>
    <artifactId>dynamic</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

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

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

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

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>
    </dependencies>
</project>

  启动类:

package com.itheima;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

  4.3.3配置yml

spring:
  datasource:
    dynamic:
      primary: master #设置默认的数据源或者数据源组,默认值即为master
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master:
          url: jdbc:mysql://192.168.211.253:3306/test1
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
        slave_1:
          url: jdbc:mysql://192.168.211.253:3306/test2
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        #......省略
        #以上会配置一个默认库master,一个组slave下有两个子库slave_1

  4.3.4使用注解来切换数据源
 

  使用**DS**切换数据源,使用方式如下:
 

  **DS**可以注解在方法上或类上,**同时存在就近原则方法上注解优先于类上注解**。

  |注解|结果|

  |-------------|----------------------------------------|

  |没有DS|默认数据源|

  |DS

"dsName"

|dsName可以为组名也可以为具体某个库的名称|
 

  例如:

@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");
  }
}

  4.3.5创建CSD

  po:

package com.itheima.po;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("tb_user")
public class User {
    @TableId(type = IdType.AUTO)
    private Integer id;
    @TableField("name")
    private String name;
}

  controller

package com.itheima.controller;

import com.itheima.po.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User get(@PathVariable(name="id")Integer id){
        return userService.getById(id);
    }
}

  service

  ```

  public interface UserService{

  User getById

Integer id

;

  }

  ```

package com.itheima.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.itheima.dao.UserDao;
import com.itheima.po.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@DS("slave_1")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Override
    public User getById(Integer id) {
        return userDao.selectById(id);
    }
}

  注意:如上:DS注解用于指定使用哪一个数据源。
 

  dao

package com.itheima.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.po.User;

public interface UserDao extends BaseMapper<User> {
}

  启动类:

@SpringBootApplication
@MapperScan(basePackages = "com.itheima.dao")
public class DynamicApplication {
    public static void main(String[] args) {
        SpringApplication.run(DynamicApplication.class,args);
    }
}

  4.3.6测试
 

  +当使用DS注解指定master的时候:

  ```

  Service

  DS

"master"

  public class UserServiceImpl implements UserService{

  Autowired

  private UserDao userDao;

  Override

  public User getById

Integer id

{

  return userDao.selectById

id

;

  }

  }

  ```

  重启项目,浏览器发送请求:http://localhost:8080/user/1
 

  得到结果:

  ```

  {"id":1,"name":"zhangsan"}

  ```

  +当使用DS注解指定slave_1的时候

  ```

  Service

  DS

"slave_1"

  public class UserServiceImpl implements UserService{

  Autowired

  private UserDao userDao;

  Override

  public User getById

Integer id

{

  return userDao.selectById

id

;

  }

  }

  ```

  重启项目,浏览器发送请求:http://localhost:8080/user/1
 

  得到结果:

{"id":1,"name":"wangwu"}

  测试成功。
 

  5.总结
 

  使用mybatisplus的动态数据源切换非常方便,只需添加依赖,并在yaml中配置数据源的名称和地址,并在service的实现类中使用注解来指定实现切换即可。下一章节我们来看看如何使用AOP来实现不需要修改代码就能动态切换数据源。
 

  +添加依赖

  +添加yaml配置

  +在业务方法上或者业务类上添加 DS注解文章来源地址https://www.toymoban.com/news/detail-459185.html

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

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

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

相关文章

  • 【Spring AOP + 自定义注解 + 动态数据源 实现主从库切换&读写分离】—— 案例实战

                                                 💧 S p r i n g A O P + 主从数据源切换 + 读写分离 + 自定义注解案例实战! color{#FF1493}{Spring AOP + 主从数据源切换 + 读写分离 + 自定义注解 案例实战!} Sp r in g A OP + 主从数据源切换 + 读写分离 + 自定义注解案例

    2024年02月15日
    浏览(27)
  • springboot整合多数据源的配置以及动态切换数据源,注解切换数据源

    在许多应用程序中,可能需要使用多个数据库或数据源来处理不同的业务需求。Spring Boot提供了简便的方式来配置和使用多数据源,使开发人员能够轻松处理多个数据库连接。如果你的项目中可能需要随时切换数据源的话,那我这篇文章可能能帮助到你 ℹ️:这里对于pom文件

    2024年02月10日
    浏览(42)
  • Spring Boot + MyBatis-Plus 实现 MySQL 主从复制动态数据源切换

    MySQL 主从复制是一种常见的数据库架构,它可以提高数据库的性能和可用性。 动态数据源切换则可以根据业务需求,在不同场景下使用不同的数据源,比如在读多写少的场景下,可以通过切换到从库来分担主库的压力 。 在本文中,我们将介绍如何在 Spring Boot 中实现 MySQL 动

    2024年02月19日
    浏览(42)
  • springboot dynamic-datasource 实现动态切换数据源-多租户-配置文件切换-基于dynamic-datasource

    1、实现动态切换数据源 2、实现配置多数据源 3、实现读写分离也可以用多数据源方式 4、选择 dynamic-datasource集成了很多ORM的框架,其中,使用比较多的是druid,但有一些东西开始收费了 druid也可以自行配置,配置多了点 目前版本只支持单一位置加载数据源(只能从配置文件或

    2024年02月09日
    浏览(42)
  • SpringBoot——动态数据源(多数据源自动切换)

    日常的业务开发项目中只会配置一套数据源,如果需要获取其他系统的数据往往是通过调用接口, 或者是通过第三方工具比如kettle将数据同步到自己的数据库中进行访问。 但是也会有需要在项目中引用多数据源的场景。比如如下场景: 自研数据迁移系统,至少需要新、老两

    2024年02月16日
    浏览(31)
  • SpringBoot动态切换数据源

      Spring提供一个DataSource实现类用于动态切换数据源—— AbstractRoutingDataSource pom.xml 大概的项目结构 注意:这两个事务管理器,并不能处理分布式事务 链接:https://pan.baidu.com/s/1ymxeKYkI-cx7b5nTQX0KWQ  提取码:6bii  --来自百度网盘超级会员V4的分享                

    2024年02月06日
    浏览(39)
  • SpringBoot从数据库读取数据数据源配置信息,动态切换数据源

            首先准备多个数据库,主库smiling-datasource,其它库test1、test2、test3         接下来,我们在主库smiling-datasource中,创建表databasesource,用于存储多数据源相关信息。表结构设计如下         创建好表之后,向表databasesource中存储test1、test2、test3三个数据库的相关配置

    2024年01月16日
    浏览(51)
  • springboot使用DynamicDataSource来动态切换数据源

    DynamicDataSource是一个数据源路由器,可以根据上下文动态选择数据源。可以在每个请求或线程中将数据源设置为当前需要使用的数据. 创建一个 DynamicDataSource 类,它继承自 AbstractRoutingDataSource 。在该类中重写**determineCurrentLookupKey()**方法,该方法返回一个字符串,用于指示当前

    2024年02月05日
    浏览(32)
  • 实例讲解Spring boot动态切换数据源

    摘要: 本文模拟一下在主库查询订单信息查询不到的时候,切换数据源去历史库里面查询。 本文分享自华为云社区《springboot动态切换数据源》,作者:小陈没烦恼 。 在公司的系统里,由于数据量较大,所以配置了多个数据源,它会根据用户所在的地区去查询那一个数据库

    2024年02月06日
    浏览(32)
  • SpringBoot整合多数据源,并支持动态新增与切换(详细教程)

    推荐文章:     1、springBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表;     2、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据;     3、java后端接口API性能优化技巧     4、SpringBoot+MyBatis流式查询,处理大规模数据,提高系统的性能和响应能力。 一

    2024年02月10日
    浏览(33)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包