Java实现动态数据源切换的实践指南
目录
- 1、简述
- 2、什么是 Dynamic-DataSource?
- 3、集成 Dynamic-DataSource
- 3.1 Maven引用
- 3.2 配置多数据源
- 3.3 编写动态数据源切换逻辑
- 4、总结
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&serjavascriptverTimezone=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.jsentry.SysUserEntity; import com.lm.shop.shopeureka.mapper.SysUserMapper; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class UserService extends ServicandroideImpl<SysUserMapper, SysUserEntity> { @Reshttp://www.devze.comource 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; /** * 手机号 */ @javascriptTableField("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动态数据源切换的资料请关注编程客栈(www.devze.com)其它相关文章!
精彩评论