当前位置: 代码网 > it编程>编程语言>Java > Java实现动态数据源切换的实践指南

Java实现动态数据源切换的实践指南

2025年03月06日 Java 我要评论
1、简述在 java 开发中,许多场景需要访问多个数据库,例如多租户系统或读写分离架构。为了灵活高效地管理这些场景,动态数据源切换(dynamic-datasource) 技术应运而生。本文介绍如何在

1、简述

在 java 开发中,许多场景需要访问多个数据库,例如多租户系统或读写分离架构。为了灵活高效地管理这些场景,动态数据源切换(dynamic-datasource) 技术应运而生。

本文介绍如何在 spring boot 项目中集成 dynamic-datasource 并实现动态切换功能,最后通过示例演示实际应用。

2、什么是 dynamic-datasource?

dynamic-datasource 是一种可以根据业务需求动态切换数据源的技术。常见的使用场景包括:

  • 读写分离:读请求路由到只读数据源,写请求路由到主数据源。
  • 多租户系统:根据租户 id 动态选择数据库。
  • 分库分表:根据分片键路由到对应的数据源。

通过动态数据源切换,可以避免手动管理多个 datasource,提升开发效率。dynamic-datasource 基于 spring 的 abstractroutingdatasource 实现。核心思想是:

  • 定义多个数据源(如主库和从库)。
  • 使用线程上下文(threadlocal)保存当前使用的数据源标识。
  • 根据上下文动态选择数据源。

3、集成 dynamic-datasource

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

  • 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
  • 支持数据库敏感配置信息 加密(可自定义) enc()。
  • 支持每个数据库独立初始化表结构schema和数据库database。
  • 支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。
  • 提供并简化对druid,hikaricp,beecp,dbcp2的快速集成。

提供对mybatis-plus,quartz,shardingjdbc,p6sy,jndi等组件的集成方案。

3.1 maven引用

在使用 dynamic-datasource之前,需要添加其依赖。以下是 dynamic-datasource的 maven 依赖:

<!-- mybatis-plus -->
<dependency>
    <groupid>com.baomidou</groupid>
    <artifactid>mybatis-plus-boot-starter</artifactid>
    <version>3.3.1</version>
</dependency>
<!-- mysql -->
<dependency>
    <groupid>mysql</groupid>
    <artifactid>mysql-connector-java</artifactid>
    <version>8.0.19</version>
</dependency>
<dependency>
    <groupid>com.baomidou</groupid>
    <artifactid>dynamic-datasource-spring-boot-starter</artifactid>
    <version>4.3.0</version>
</dependency>

3.2 配置多数据源

在 application.yml 文件中配置多个数据源:

server:
  port: 9001

spring:
  datasource:
    dynamic:
      primary: master
      strict: false
      datasource:
        master:
          url: jdbc:mysql://192.168.25.181:3306/shop_admin?useunicode=true&characterencoding=utf-8&usessl=false&servertimezone=asia/shanghai
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.driver
        slave_1:
          url: jdbc:mysql://192.168.25.181:3306/slave_db?useunicode=true&characterencoding=utf-8&usessl=false&servertimezone=asia/shanghai
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.driver

3.3 编写动态数据源切换逻辑

dynamic-datasource starter 提供了注解和 aop 的支持,可以简化数据源切换逻辑。在需要动态切换数据源的地方添加 @ds 注解:

import com.baomidou.dynamic.datasource.annotation.ds;
import com.baomidou.mybatisplus.extension.service.impl.serviceimpl;
import com.lm.shop.shopeureka.entry.sysuserentity;
import com.lm.shop.shopeureka.mapper.sysusermapper;
import org.springframework.stereotype.service;

import javax.annotation.resource;

@service
public class userservice extends serviceimpl<sysusermapper, sysuserentity> {

    @resource
    private sysusermapper sysusermapper;

    @ds("master")
    public void insertuser(sysuserentity user) {
        sysusermapper.insert(user);
    }

    @ds("slave_1")
    public sysuserentity getuserbyid(long id){
        return sysusermapper.selectbyid(id);
    }
}

sysusermapper:

import com.baomidou.mybatisplus.core.mapper.basemapper;
import com.lm.shop.shopeureka.entry.sysuserentity;

public interface sysusermapper extends basemapper<sysuserentity> {
}

sysuserentity:

package com.lm.shop.shopeureka.entry;

import com.baomidou.mybatisplus.annotation.tablefield;
import com.baomidou.mybatisplus.annotation.tableid;
import com.baomidou.mybatisplus.annotation.tablename;
import lombok.data;

import java.io.serializable;
import java.util.date;

@data
@tablename("sys_user")
public class sysuserentity  implements serializable {
    private static final long serialversionuid = 1l;

    /**
     * 用户id
     */
    @tableid(value = "user_id")
    private long userid;

    /**
     * 用户名
     */
    @tablefield("username")
    private string username;

    /**
     * 密码
     */
    @tablefield("password")
    private string password;

    /**
     * 盐
     */
    @tablefield("salt")
    private string salt;

    /**
     * 邮箱
     */
    @tablefield("email")
    private string email;

    /**
     * 手机号
     */
    @tablefield("mobile")
    private string mobile;

    /**
     * 状态  0:禁用   1:正常
     */
    @tablefield("status")
    private integer status;

    /**
     * 创建者id
     */
    @tablefield("create_user_id")
    private long createuserid;

    /**
     * 创建时间
     */
    @tablefield("create_time")
    private date createtime;
}

在controller控制层添加测试用例:

import com.lm.shop.shopeureka.entry.sysuserentity;
import com.lm.shop.shopeureka.service.userservice;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.restcontroller;

import java.util.date;

@restcontroller
@requestmapping("/user")
public class usercontroller {

    @autowired
    private userservice userservice;

    @getmapping("/getuserbyid")
    public sysuserentity getuserbyid(@requestparam long id) {
        return userservice.getuserbyid(id);
    }

    @getmapping("/insert")
    public sysuserentity insert(@requestparam long id) {
        sysuserentity sysuserentity = new sysuserentity();
        sysuserentity.setemail("admin@admin.com");
        sysuserentity.setpassword("123456");
        sysuserentity.setusername("adminmaster");
        sysuserentity.setcreatetime(new date());
         userservice.insertuser(sysuserentity);
         return sysuserentity;
    }
}

在启动类中添加mapper映射路径:

@springbootapplication
@mapperscan("com.lm.shop.shopeureka.mapper")
public class shopeurekaapplication {
    public static void main(string[] args) {
        springapplication.run(shopeurekaapplication.class, args);
    }
}

4、总结

dynamic-datasource 提供了一种高效、简洁的多数据源管理方式,非常适合多租户系统、读写分离等复杂场景。本文通过配置和实际案例展示了如何集成和使用 dynamic-datasource,帮助开发者快速实现动态数据源切换功能。

通过动态数据源技术,可以显著提高系统的灵活性和扩展性。如果你的项目中涉及多个数据库的管理,dynamic-datasource 将是一个强大的工具。

以上就是java实现动态数据源切换的实践指南的详细内容,更多关于java动态数据源切换的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com