乐趣区

关于springboot:Spring-Boot连接多个数据库

微服务架构流行的明天,应用服务与数据库的对应关系通常是一个微服务对应一个数据库。

在一个电商零碎中,用户信息存储在用户数据库中,订单信息存储在订单数据库中,如果一次申请须要获取订单相干信息,则须要将订单信息和下单的用户信息一起查问进去。

在订单服务中获取用户数据不会间接调用用户数据库,而是通过调用用户治理服务的接口。

这种架构在大型零碎中劣势很显著,在业务上能够解耦,防止一个服务对用多个数据库,导致业务凌乱,系统维护艰难。也能够进步数据库的安全性。

利用场景

然而在些 B 端的管理系统,架构通常没有这么简单(单体架构),只有一个服务。
这种利用也有连贯多个数据库的需要,例如同步数据库。

Spring Boot 连贯数据库默认配置

这里应用 Spring Boot 和 Mybatis。

因为 Spring boot 的易用性,默认状况下,咱们只须要在 application 配置文件中,

  • 配置好数据源的信息
  • Mybtis 的 Mapper 扫描门路,
  • 以及在 Configuration 类中配置 MapperScan 配置对应 Mapper 类的包门路
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
    username: root
    password:  12345
mybatis: 
  mapper-locations: /mapper/**.xml
@SpringBootApplication
@MapperScan("icu.daydream.demo.mybatisdemo.mapper")
public class MybatisDemoApplication {public static void main(String[] args) {SpringApplication.run(MybatisDemoApplication.class, args);
    }

}

实现以上三个配置,不须要再创立 DataSource 对象,以及 SqlSessionFactory 对象,即可使利用主动连贯上数据库。体现了 Spring Boot 约定大于配置 的个性。

在 Spring Boot 中利用中如何同时连贯多个数据库呢?

当初咱们的需要是同时连贯两个数据库,Spring Boot 的默认配置曾经满足不了需要,因而就须要手动的去配置数据源信息。

在 application.yaml 中配置两个自定义的数据源属性

创立 DataSource 对象和 SqlSessionFactory 对象

先创立连贯数据库 1 的 须要的对象。

@Configuration
@MapperScan(basePackages = DataSourceConfig1.PACKAGE,sqlSessionFactoryRef = "sqlSessionFactory1")
public class DataSourceConfig1 {
    // 数据库 1 扫描的 Mapper 类门路
    final static String PACKAGE = "test.mapper.db1";

    @Bean(name = "dataSource1")
    // 将 yaml 文件中的 datasource1 下的属性 注入到 DataSource 对象中
    @ConfigurationProperties(prefix = "datasource1")
    public DataSource businessDbDataSource() {return new DruidDataSource();
    }

    @Bean(name = "sqlSessionFactory1")
    public SqlSessionFactory sqlSessionFactory1(@Qualifier("dataSource1") DataSource dataSource ) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource); 
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/db1/*.xml"));
        return factoryBean.getObject();}
    
} 

默认配置下这两个 Bean 对象是主动创立的,当初显式创立后,Spring Boot 的默认配置对象就不会再创立了,application.yaml 中 mybatis 下的一些配置也跟着生效了。须要显式创立 Myabtis 的 Configuration 配置对象。这个前面再讲。

目前曾经配置好了数据库 1 的连贯,同样地,再创立一个连贯数据库 2 的对象。

@Configuration
@MapperScan(basePackages = DataSourceConfig2.PACKAGE,sqlSessionFactoryRef = "sqlSessionFactory2")
public class DataSourceConfig2 {
    // 数据库 1 扫描的 Mapper 类门路
    final static String PACKAGE = "test.mapper.db2";

    @Bean(name = "dataSource2")
    // 将 yaml 文件中的 datasource1 下的属性 注入到 DataSource 对象中
    @ConfigurationProperties(prefix = "datasource2")
    public DataSource businessDbDataSource() {return new DruidDataSource();
    }

    @Bean(name = "sqlSessionFactory2")
    public SqlSessionFactory sqlSessionFactory1(@Qualifier("dataSource2") DataSource dataSource ) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/db2/*.xml"));
        return factoryBean.getObject();} 
} 

包构造如下:

以上多数据源就配置实现了,db1 下的 mapper 查问会连贯数据库 1,db2 下的 mapper 连贯数据库 2 .

注解阐明

  • @Bean:在 @Configuration 类中应用,作用在办法上,办法的返回值为 创立 Bean 对象,并注入到 Spring 容器中。属性 name 为 Bean 对象的名称,不加则办法名为 Bean 对象名称。
  • @MapperScan:用于扫描 Mapper 对象的包门路
  • @Qualifier:作用在办法参数上,依据 Bean 对象名称注入 Bean 对象

Mybatis 显示配置数据源,application 的 mybatis 相干配置生效

在配置连个数据源后,application 中 mybatis 下的相干配置生效了。例如将 SQL 查问的字段名从下划线转为小驼峰,通常在 application 中这么配置:

mybatis:
  configuration:
    map-underscore-to-camel-case: true

在创立多个数据源后,该配置生效了,因为 Mybatis 中的 Configuration 没有被创立,在多个数据源的状况下,Mybatis 也不晓得要将该配置配置在哪个数据源下。

因而须要手动创立 Configuration Bean 对象,并注入到 SqlSessionFactoryBean 对象中。

①创立 Bean 对象

@Bean("customSessionConfiguration")
@ConfigurationProperties(prefix = "mybatis.configuration")
public org.apache.ibatis.session.Configuration configuration(){return new org.apache.ibatis.session.Configuration();
}

② 更改 sqlSessionFactory1 的办法,将 Configuration 对象注入进去

@Bean(name = "sqlSessionFactory1")
public SqlSessionFactory sqlSessionFactory1(@Qualifier("dataSource1") DataSource dataSource , @Qualifier("customSessionConfiguration") org.apache.ibatis.session.Configuration configuration) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    factoryBean.setDataSource(dataSource);
    factoryBean.setConfiguration(configuration);
    factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
            .getResources("classpath:mapper/db1/*.xml"));
    return factoryBean.getObject();} 

如果感觉文章对你有帮忙,就请作者喝杯 Java 吧!我是白日梦。

退出移动版