详细分析Java中@DS注解,用于切换数据源
目录
- 前言
- 1. 基本知识
- 2. Demo
- 3. 实战
前言
Java项目中多个数据源,相应配置拿些方法哪些类访问
(图片来源网络,侵删)类似JDBC每个类都要写一遍会比较冗余,有没有集中式管理呢??
看这篇文章之前推荐阅读:
- java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
- jdbc从入门到精通(全)
1. 基本知识
本身该注解通过Java的切面,源于Spring,推荐阅读补充知识:Spring框架从入门到学精(全)
自定义 @DS 注解通常是为了在方法级别上指定数据源,实现动态数据源切换的功能
通过在不同的方法上标注不同的数据源,可以使得这些方法在执行时使用不同的数据库连接
作用:
- 实现动态数据源切换:允许在不同的方法中使用不同的数据库连接
- 简化配置:通过注解方式,避免了在每个方法中手动切换数据源的麻烦
使用方式
定义注解:首先需要定义 @DS 注解,指定它的元注解为 @Target 和 @Retention,以及定义它的属性
查看其源码:
package com.baomidou.dynamic.datasource.annotation; import java.lang.annotation.*; /** * The core Annotation to switch datasource. It can be annotate at class or method. * * @author TaoYu Kanyuxia * @since 1.0.0 */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DS { /** * groupName or specific database name or spring SPEL name. * * @return the database you want to switch */ String value(); }
-
@Target({ElementType.TYPE, ElementType.METHOD}):指定了注解 @DS 可以应用在哪些地方,指定了 @DS 注解可以应用在类和方法上
-
@Retention(RetentionPolicy.RUNTIME):指定了注解 @DS 在程序运行时保留,可以通过反射来访问并解析 @DS 注解的信息
-
@Documented:标记这个注解是应该被 javadoc 工具记录的,当生成 API 文档时,如果一个类用 @Documented 注解修饰,那么它的注解将出现在生成的文档中
-
String value();:属性,返回一个字符串,用于指定要切换到的数据库的名称
2. Demo
使用之前先引入依赖包:
com.github.vlvolad spring-dynamic-datasource ${spring-dynamic-datasource.version}
配置数据源:
spring: datasource: # 配置数据源 dynamic: # 数据源配置的一个自定义前缀,这个前缀是用于配置动态数据源,即可以在运行时动态切换数据源 primary: master # 指定了默认数据源的名称为 master strict: true # 指定了严格模式,意味着如果在代码中请求了一个不存在的数据源,将抛出异常 datasource: master: url: jdbc:mysql://localhost:3306/db_master username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver slave: url: jdbc:mysql://localhost:3307/db_slave username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver
并在方法上动态切换数据源:
@Service public class MyService { @DS("master") public void method1() { // 方法1的实现 } @DS("slave") public void method2() { // 方法2的实现 } }
除了上面用在方法上,也可直接用在类上,对于这个类的波动方法都用于某个数据库
3. 实战
以下实战与上述Demo类似,只不过用在了方法上 (与正常开发一样,只不过在此处添加了该注解)
@Service @DS("slave") @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) public class TemperatureAlarmHistServiceImpl implements ITemperatureAlarmHistService { @Resource private TemperatureAlarmHistMapper temperatureAlarmHistMapper; public boolean saveForList(List temperatureAlarmHistList) { return temperatureAlarmHistMapper.saveForList(temperatureAlarmHistList); } }
对应的数据源配置如下:
#数据源配置 spring: # 排除DruidDataSourceAutoConfigure autoconfigure: exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure datasource: dynamic: # 设置默认的数据源或者数据源组,默认值即为master primary: master datasource: master: url: jdbc:mysql://localhost:3306/db_master username: root password: root slave: url: jdbc:oracle:manong:@//localhost:1521/GIS username: root password: ROOTGPS1 ep: url: jdbc:sqlserver://localhost:1433;databaseName=manong username: root password: root
提供的配置中,exclude 属性指定了要排除的自动配置类 com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
这样做的目的是排除Druid连接池的自动配置,避免它与手动配置的数据源发生冲突
另外一种排除的方式:
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
前提是 上述这两种方式本身已经引入了该依赖包
com.alibaba druid-spring-boot-starter 1.2.1
-