springboot 多数据源项目demo

背景: 公司要新建一个数据项目,因为要查询多个数据源的数据,且之前也没有做项目搭建的笔记,这次做一个记录。开箱即用,真香警告!

搭建过程中遇到了一些问题,会逐步说明。代码地址:https://gitee.com/aaron_qc/multi-datasource.git

  1. 先上主菜。多数据源配置步骤
    1. 引入依赖 tkmapper + druid + mysql + spring-boot-configuration-processor
      1. <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>2.1.5.RELEASE</version>
        </dependency>
        
        <!-- mysql and mybatis etc -->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        
        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
    2. 配置如下
      1. 启动类加上@EnableConfigurationProperties。
        1. OceanApplication
          /**
           * @author QuCheng on 2019-09-16.
           * EnableConfigurationProperties 使 @ConfigurationProperties 注解的类(需要加@Component)生效。
           */
          @EnableConfigurationProperties
          @SpringBootApplication
          public class OceanApplication {
              public static void main(String[] args) {
                  SpringApplication.run(OceanApplication.class, args);
              }
          }
      2. yml配置相应属性
        1. application.yml 属性自定义名称,只需要和对应java类对应即可
          druid:
            # 数据源配置
            user: root
            password: xxxx
            driverClass: com.mysql.cj.jdbc.Driver
            # 初始化 最小 最大
            initialSize: 5
            minIdle: 5
            maxActive: 20
            testOnBorrow: false
            urlIceberg: jdbc:mysql://106.12.176.120/iceberg?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false  # 设置时区
            urlOcean: jdbc:mysql://106.12.176.120/ocean?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false  # 设置时区
            urlAccount: jdbc:mysql://106.12.176.120/account?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false  # 设置时区 
      3. 自定义属性加载父类BaseProperty
        1. 映射yml配置 。 
          package com.hb.ocean.druid;
          
          import com.alibaba.druid.pool.DruidDataSource;
          import lombok.Data;
          import org.springframework.boot.context.properties.ConfigurationProperties;
          import org.springframework.stereotype.Component;
          
          import javax.sql.DataSource;
          
          /**
           * datasource base class
           * @author qucheng
           */
          @Data
          @ConfigurationProperties(prefix = "druid")
          @Component
          class BaseProperty {
          
              protected String user;
          
              protected String password;
          
              protected String driverClass;
          
              protected int initialSize;
          
              protected int maxActive;
          
              protected int minIdle;
          
              protected boolean testOnBorrow;
          
              protected String urlAccount;
          
              protected String urlOcean;
          
              protected String urlIceberg;
          
          
              DataSource createDataSource(String url) {
                  DruidDataSource dataSource = new DruidDataSource();
                  dataSource.setDriverClassName(driverClass);
                  dataSource.setUrl(url);
                  dataSource.setUsername(user);
                  dataSource.setPassword(password);
                  dataSource.setInitialSize(initialSize);
                  dataSource.setMaxActive(maxActive);
                  dataSource.setMinIdle(minIdle);
                  dataSource.setTestOnBorrow(testOnBorrow);
                  return dataSource;
              }
          }
      4. 各数据源配置自己的映射路径(mapper接口+xml文件)
        1. 配置路径 -- 此处省略2个其他配置
          package com.hb.ocean.druid;
          
          import org.apache.ibatis.session.SqlSessionFactory;
          import org.mybatis.spring.SqlSessionFactoryBean;
          import org.springframework.beans.factory.annotation.Qualifier;
          import org.springframework.context.annotation.Bean;
          import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
          import org.springframework.jdbc.datasource.DataSourceTransactionManager;
          import org.springframework.stereotype.Component;
          import tk.mybatis.spring.annotation.MapperScan;
          
          import javax.sql.DataSource;
          
          /**
           * account datasource
           * MapperScan(如果要使用表名映射实体使用tk)注解用于绑定扫描的包和指定的数据源,且指定目录下的mapper无需加注解处理
           *
           * @author qucheng
           */
          @Component
          @MapperScan(basePackages = "com.hb.ocean.mapper.account", sqlSessionFactoryRef = "accountSqlSessionFactory")
          public class AccountConfig extends BaseProperty {
          
              @Bean(name = "accountDataSource")
              public DataSource createDataSource() {
                  return createDataSource(urlAccount);
              }
          
              @Bean(name = "accountTransactionManager")
              public DataSourceTransactionManager accountTransactionManager() {
                  return new DataSourceTransactionManager(createDataSource());
              }
          
              @Bean(name = "accountSqlSessionFactory")
              public SqlSessionFactory masterSqlSessionFactory(@Qualifier("accountDataSource") DataSource accountDataSource)
                      throws Exception {
                  final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
                  sessionFactory.setDataSource(accountDataSource);
                  String mapperLocation = "classpath:mapper/account/*.xml";
                  sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                          .getResources(mapperLocation));
                  return sessionFactory.getObject();
              }
          }
      5. 创建相应目录下的文件。在启动项目时会加载。
        1. 结构如图
    3. 成功之后启动测试结果如下
      1. 测试代码
        package com.hb.ocean.controller;
        
        import com.hb.ocean.mapper.account.UserMapper;
        import com.hb.ocean.mapper.iceberg.ItemOrderMapper;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        
        import javax.annotation.Resource;
        
        /**
         * @author QuCheng on 2019-09-17.
         */
        @RestController
        @RequestMapping("/qc")
        public class TestView {
        
            /**
             * 不推荐直接在controller层引入Dao层。这里只做演示使用
             */
            @Resource
            private UserMapper userMapper;
            @Resource
            private ItemOrderMapper itemOrderMapper;
        
            @GetMapping("/test")
            public String test() {
                System.out.println("用户数:" + userMapper.selectCountUser(null, null));
                System.out.println("订单数:" + itemOrderMapper.selectCountSuccessOrder(null, null));
                return "ok";
            }
        }
      2. 测试结果

以上过程也出现的几个问题

  1. 多数据源共用了一个yml基础配置,除了数据源url地址不一致之外。
  2. 自定义yml属性配置项需要
    1. 引入spring-boot-configuration-processor。
    2. 启动类使用注解@EnableConfigurationProperties
    3. 解析类上面要引入3个注解@Data只是为了方便。@ConfigurationProperties(prefix = "druid")指明读取的是"druid"开始的属性。@Component表示由容器管理
  3. 配置类@MapperScan注解是使用的tk.mybatis.spring.annotation.MapperScan注解。org.mybatis.spring.annotation.MapperScan也可以用但是它不能配合使用@Table注解映射表。

springboot多数据源配置的过程如上。这是demo版本。实际应用数据中还涉及

  1. eureka的注册发现。启动类注解引入
  2. feign接口调用以及失败熔断
  3. 优雅停机简单处理
  4. swagger文档
  5. redis分布式事务

猜你喜欢

转载自www.cnblogs.com/nightOfStreet/p/11543768.html
今日推荐