详细分析Java中@DS注解,用于切换数据源

2024-05-14 1016阅读

目录

  • 前言
  • 1. 基本知识
  • 2. Demo
  • 3. 实战

    前言

    Java项目中多个数据源,相应配置拿些方法哪些类访问

    详细分析Java中@DS注解,用于切换数据源
    (图片来源网络,侵删)

    类似JDBC每个类都要写一遍会比较冗余,有没有集中式管理呢??

    看这篇文章之前推荐阅读:

    1. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
    2. 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
        
        
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]