> Java > java지도 시간 > springboot에서 여러 데이터 소스를 구성하는 방법

springboot에서 여러 데이터 소스를 구성하는 방법

无忌哥哥
풀어 주다: 2018-07-20 11:22:28
원래의
2364명이 탐색했습니다.

요약: 현재 프로젝트에 사용되는 지속성 프레임워크는 mybatis입니다. 분석 후에는 다중 데이터 소스 구성이 두 가지 문제를 해결해야 한다는 것을 어렵지 않게 찾을 수 있습니다. 하나는 원래 spring boot 방법으로 전환하는 것입니다. 여러 데이터 소스를 구성하려면? 많은 변화가 있었나요? 다른 하나는 여러 데이터 소스를 mybatis 구성과 연결하는 방법입니다.

머리말

최근 프로젝트 요구로 인해 저자는 springboot 다중 데이터 소스 구성 여행에 착수했습니다. 저자는 이전에 JDBC 템플릿을 사용하여 Spring의 동적 다중 데이터 소스 전환을 구성했습니다.

현재 프로젝트에 사용되는 지속성 프레임워크는 mybatis입니다. 분석 후 다중 데이터 소스 구성이 두 가지 문제를 해결해야 한다는 것을 어렵지 않게 찾을 수 있습니다. 하나는 원래 spring boot 방식으로 전환하는 것입니다. 여러 데이터 소스를 구성하시겠습니까? 많은 변화가 있었나요? 다른 하나는 여러 데이터 소스를 mybatis 구성과 연결하는 방법입니다.

먼저 단일 데이터 소스에서 mybatis를 구성하는 방법을 살펴보겠습니다.

단일 데이터 소스 예

우선, 프로젝트가 단일 데이터 소스에만 의존할 때 springboot가 대신 작업을 수행해도 괜찮다면 축하합니다. 문제가 발생하지 않습니다! 프로젝트 속성 파일에 데이터 소스의 관련 속성 구성을 추가하기만 하면 springboot가 "무료"용 데이터 소스를 제공합니다. 기본값은 tomcat jdbc 연결 풀입니다.

물론 springboot의 친절을 거부할 수 있습니다. 타사 연결 풀 기술에 의존하는 경우 자체 데이터 소스를 구성할 수 있습니다. 그러면 springboot는 사용자가 직접 DataSource를 정의한 것을 감지한 후 데이터 소스를 자동으로 구성하지 않습니다.

저자는 springboot의 친절을 거부할 수 없어서 프로젝트의 application.properties에 다음 속성만 추가했습니다.

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
spring.datasource.validation-query=SELECT 1
spring.datasource.test-on-borrow=false
spring.datasource.test-while-idle=true
spring.datasource.time-between-eviction-runs-millis=18800
然后笔者创建了一个专门用于配置mybatis的类,如下:
@Configuration
public class MybatisSpringConfig {
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setTypeAliasesPackage("demo.model");
return factoryBean.getObject();
}
[[[@Bean](http://my.oschina.net/bean)](http://my.oschina.net/bean)](http://my.oschina.net/bean)
public MapperScannerConfigurer mapperScannerConfigurer() {
    MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
    mapperScannerConfigurer.setBasePackage("demo.repository");
    return mapperScannerConfigurer;
}
}
로그인 후 복사

没错,mybatis在spring中就是可以通过如此的简练配置进而正常工作起来。你无需刻意地去创建mybatis的配置文件,无需刻意地去注册mapper接口及指定对应xml文件的位置,这完全得益于mybatis-spring,它就像一个“粘合剂”,可以很方便地将mybatis和spring“粘合”在一起。

MyBatis-Spring的配置步骤

不妨先来说下mybatis-spring配置的一般步骤:

  1. 配置数据源DataSource的Bean。

  2. 使用DataSource配置事务管理器。

  3. 使用DataSource配置SqlSessionFactory的Bean。

  4. 配置MapperScannerConfigurer的Bean。

这里要求配置事务管理器和SqlSessionFactory的数据源必须是同一个,否则事务管理不起作用。配置MapperScannerConfigurer的目的是自动扫描mapper接口所在的包,自动帮你将mapper接口注册为Bean(代理生成接口的实现类),你就可以直接拿来依赖注入了,建议将mapper接口及其对应的xml文件放在同一个包下,这样的话你无需在SqlSessionFactory里指定xml文件的位置了。

OK,到此对比我上面贴出的配置类内容,你可能会发现笔者怎么少了几步?感谢springboot,因为它自动配置了一个DataSource,同时它还自动配置了一个事务管理器。所以笔者只配置了SqlSessionFactory和MapperScannerConfigurer。

当然如果看到这里你仍然“执意”要配置自己的数据源,参照下面的多数据源配置说明,抽出来多个中的一个就可以实现自定义单数据源的配置了。

多数据源示例

经过上面单数据源的示例,可以说当我们切换到springboot的方式下写代码时,springboot为我们带来了很大的便利,还不影响我们自定义,所以笔者认为,没用使用springboot之前,无论你使用spring怎样的配置,使用springboot之后,不会有阻碍,甚至会比原来更快!

简单说下需要多数据源的场景,笔者参照了一下其他的文章,绝大部分的需要来自于数据库主从方式或读写分离。那么就按照master和slave两个数据源,直接贴出数据源的配置类。

  • application.properties

datasource.master.url=jdbc:mysql://localhost:3306/master
datasource.master.username=root
datasource.master.password=root
datasource.master.driver-class-name=com.mysql.jdbc.Driver
datasource.master.max-idle=10
datasource.master.max-wait=10000
datasource.master.min-idle=5
datasource.master.initial-size=5
datasource.master.validation-query=SELECT 1
datasource.master.test-on-borrow=false
datasource.master.test-while-idle=true
datasource.master.time-between-eviction-runs-millis=18800
datasource.slave.url=jdbc:mysql://localhost:3306/slave
datasource.slave.username=root
datasource.slave.password=root
datasource.slave.driver-class-name=com.mysql.jdbc.Driver
datasource.slave.max-idle=10
datasource.slave.max-wait=10000
datasource.slave.min-idle=5
datasource.slave.initial-size=5
datasource.slave.validation-query=SELECT 1
datasource.slave.test-on-borrow=false
datasource.slave.test-while-idle=true
datasource.slave.time-between-eviction-runs-millis=18800
로그인 후 복사

  • 네, 마이바티스는 이렇게 간단한 구성으로 봄에도 정상적으로 작동할 수 있습니다. 의도적으로 mybatis의 구성 파일을 생성하고 매퍼 인터페이스를 등록하고 해당 xml 파일의 위치를 ​​지정할 필요가 없습니다. 이는 전적으로 Mybatis와 spring을 쉽게 연결할 수 있는 "접착제"와 같은 mybatis-spring 덕분입니다. 서로 "접착"되어 있습니다.

    MyBatis-Spring 구성 단계
먼저 mybatis-spring 구성의 일반적인 단계에 대해 이야기해 보겠습니다.

데이터 소스 DataSource의 Bean을 구성합니다.
  • DataSource를 사용하여 트랜잭션 관리자를 구성합니다.

DataSource를 사용하여 SqlSessionFactory Bean을 구성합니다.

MapperScannerConfigurer Bean을 구성합니다.

구성된 트랜잭션 관리자와 SqlSessionFactory의 데이터 소스가 동일해야 합니다. 그렇지 않으면 트랜잭션 관리가 작동하지 않습니다. MapperScannerConfigurer를 구성하는 목적은 매퍼 인터페이스가 있는 패키지를 자동으로 스캔하고 매퍼 인터페이스를 Bean(에이전트 생성 인터페이스의 구현 클래스)으로 등록하여 종속성에 직접 사용할 수 있도록 자동으로 도와주는 것입니다. 주입 매퍼 인터페이스와 해당 xml 파일을 동일한 패키지에 배치하는 것이 좋습니다. 따라서 SqlSessionFactory에서 xml 파일의 위치를 ​​지정할 필요가 없습니다.

좋아, 위에 게시한 구성 내용과 비교하면 내가 왜 몇 단계를 놓쳤는지 알 수 있을까요? springboot 덕분에 DataSource를 자동으로 구성하기 때문에 트랜잭션 관리자도 자동으로 구성합니다. 그래서 작성자는 SqlSessionFactory와 MapperScannerConfigurer만 구성했습니다.
  • 물론, 이 내용을 보신 후에도 여전히 자신만의 데이터 소스 구성을 고집하신다면, 아래의 다중 데이터 소스 구성 지침을 참조하시고 다중 데이터 소스 중 하나를 추출하여 맞춤형 단일 데이터 소스 구성을 구현하시기 바랍니다.

  • 다중 데이터 소스 예제
  • 위의 단일 데이터 소스 예제에 이어 springboot로 전환하여 코드를 작성할 때 springboot는 우리에게 큰 편리함을 제공하고 사용자 정의에 영향을 미치지 않는다고 말할 수 있으므로 작성자는 사용하기 전에 springboot, spring을 사용하는 구성에 관계없이 springboot를 사용한 후에는 장애물이 없으며 이전보다 훨씬 더 빨라질 것입니다!

  • 여러 데이터 소스가 필요한 시나리오에 대해 간단히 이야기해 보겠습니다. 저자는 다른 기사를 참조하여 대부분의 요구 사항이 데이터베이스 마스터-슬레이브 방식 또는 읽기-쓰기 분리에서 나온다는 것을 발견했습니다. 그런 다음 마스터와 슬레이브의 두 데이터 소스에 따라 데이터 소스의 구성 클래스를 직접 게시합니다.
  • 🎜application.properties🎜🎜🎜🎜🎜
    @Configuration
    public class MasterConfig {
    [[[@Primary](http://my.oschina.net/primary)](http://my.oschina.net/primary)](http://my.oschina.net/primary)
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "datasource.master")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
    로그인 후 복사
    🎜🎜🎜마스터 데이터 소스🎜🎜🎜
    @Primary
    @Bean(name = "masterTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
        }
    }
    로그인 후 복사
    🎜🎜
    @Configuration
    public class SlaveConfig {
        @Bean(name = "slaveDataSource")
        @ConfigurationProperties(prefix = "datasource.slave")
        public DataSource dataSource() {
            return DataSourceBuilder.create().build(){
        }
        @Bean(name = "slaveTransactionManager")
        public DataSourceTransactionManager transactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    }
    로그인 후 복사
    🎜 🎜🎜🎜🎜슬레이브 데이터 소스🎜🎜🎜🎜🎜
    @Configuration
    @MapperScan(basePackages = {"demo.repository.master"}, sqlSessionFactoryRef = "masterSqlSessionFactory")
    public class MasterConfig {
        @Primary
        @Bean(name = "masterDataSource")
        @ConfigurationProperties(prefix = "datasource.master")
        public DataSource dataSource() {
            return DataSourceBuilder.create().build();
        }
    @Primary
    @Bean(name = "masterTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    @Primary
    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setTypeAliasesPackage("demo.model");
        return factoryBean.getObject();
    }
    }
    로그인 후 복사
    로그인 후 복사
    🎜 🎜🎜두 데이터 소스의 구성 단계를 보는 것은 어렵지 않습니다. 🎜🎜🎜🎜속성 파일에서 두 데이터 소스에 필요한 속성 값을 구성하고 접두사 이름에 주의하세요. 🎜🎜🎜🎜두 개의 데이터 소스에 대한 구성 클래스를 빌드할 필요는 없습니다. 이를 하나의 구성 클래스에 스택하는 것은 나쁜 생각이 아닙니다. 🎜🎜🎜🎜구성 클래스에서 DataSource의 Bean을 구성하고 식별할 수 있는 이름을 지정하는 것을 기억하세요! 🎜🎜🎜🎜두 데이터 소스에 해당하는 트랜잭션 관리자를 구성하세요. 너무 번거롭게 작업하지 마세요. 그렇지 않으면 식별할 수 있는 이름을 지정하는 것을 잊지 마세요. 🎜
  • 配置DataSource时,利用@ConfigurationProperties(prefix = "xxx.xxx")可以依靠指定的前缀,在诸多的属性值中“挑选”出数据源依赖的属性,进而完成数据源的构建。

    当自己定义了DataSource后,springboot就会取消自动配置的动作了。为了各司其职,为每个数据源配置各自的事务管理器,springboot自然也会取消自动配置事务管理器的动作。由于是多个数据源和多个事务管理器,都是一个类型的,你要是不起个区别的名字,任谁都分辨不出来吧?

    @Primary 有什么作用呢?简单地说,当有两个同一类型的Bean,依赖注入时你没有指定name,正常情况下会报错,有两个你要的Bean,识别不了。但是 @Primary 相当于指定这个Bean为默认的,如果你没有指定name,就采用 @Primary 标识的Bean。

    OK,两个数据源的配置配好了,还需要配置各自的Mybatis来进行持久化的操作。

    MyBatis-Spring相关配置

    • mybatis for master

    @Configuration
    @MapperScan(basePackages = {"demo.repository.master"}, sqlSessionFactoryRef = "masterSqlSessionFactory")
    public class MasterConfig {
        @Primary
        @Bean(name = "masterDataSource")
        @ConfigurationProperties(prefix = "datasource.master")
        public DataSource dataSource() {
            return DataSourceBuilder.create().build();
        }
    @Primary
    @Bean(name = "masterTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    @Primary
    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setTypeAliasesPackage("demo.model");
        return factoryBean.getObject();
    }
    }
    로그인 후 복사
    로그인 후 복사

    • mybatis for slave

    @Configuration
    @MapperScan(basePackages = {"demo.repository.slave"}, sqlSessionFactoryRef = "slaveSqlSessionFactory")
    public class SlaveConfig {
    @Bean(name = "slaveDataSource")
    @ConfigurationProperties(prefix = "datasource.slave")
    public DataSource dataSource() {
    return DataSourceBuilder.create().build();
    }
    @Bean(name = "slaveTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
    }
    @Bean(name = "slaveSqlSessionFactory")
    public SqlSessionFactory basicSqlSessionFactory(@Qualifier("slaveDataSource") DataSource basicDataSource) throws Exception {
    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    factoryBean.setDataSource(basicDataSource);
    factoryBean.setTypeAliasesPackage("demo.model");
    return factoryBean.getObject();
    }
    }
    로그인 후 복사

    这里需要强调几个地方:

    1. 细心人会发现上面的配置类中,少了MapperScannerConfigurer的Bean配置,改用了@MapperScan注解。其实两者的作用是一样的,但是@MapperScan比较新,稍后会做解释为什么它比较新。

    2. 由于两个数据源的原因,引出了两套SqlSessionFactory的配置,所以@MapperScan中需要指明依赖的是哪个SqlSessionFactory,“sqlSessionFactoryRef”对应就是SqlSessionFactory的name属性。

    3. @MapperScan会将扫描的mapper接口代理生成实现类,并自动注册为Bean。由于两个数据源的配置类中都有@MapperScan注解,为了避免造成冲突和排错时的困扰,猛烈提醒,两个数据源的配置,mybatis对应的mapper接口及对应xml文件也构建两套,最好接口名上也做些区分。model类使用同一套倒是没什么影响。所以你会看到上面的配置中,@MapperScan中basePackages指向的是两个包路径。

    好了,来解释下@MapperScan为何比较新,并且笔者推荐使用@MapperScan。

    首先@MapperScan要求的mybatis-spring版本比较新,说明它是新推出的特性。

    其次@MapperScan要比配置MapperScannerConfigurer的Bean要简练的多,代码量上就看得出来。

    最后,@MapperScan中的basePackageClasses属性是MapperScannerConfigurer所没有的。并且笔者用到了这个basePackageClasses属性,所以这里强力推荐使用@MapperScan注解。

    多聊一些,描述下笔者为何会用到@MapperScan中的basePackageClasses属性吧,况且与上述示例中的basePackages有何区别呢?

    上面提到了多数据源的一般场景,笔者的不同。笔者的项目中划分了n个子模块,每个子模块有各自的数据库,现在需要每个子模块共享一个公共信息的数据库。

    从代码上来说,由于各个子模块依赖的公共信息数据库-数据源、mapper接口和xml映射文件是相同的,笔者希望将这些类和文件抽离到maven的一个公共module(最后会打包为一个jar文件)中,供其他n个子模块依赖使用,这样可以避免重复代码嘛。

    笔者这么做之后,发现配置MapperScannerConfigurer的basePackages找不到mapper接口所在的包路径,因为笔者是在子模块中配置的MapperScannerConfigurer,它自然会在子模块的结构中去寻找指定的包路径,是mapper接口被笔者放到了公共的module中,所以是找不到的!

    不过还好在@MapperScan中发现了basePackageClasses属性,它会“接受”你指定的mapper接口的全名。再次提醒,记得把xml映射文件和mapper接口放在一起,mybatis-spring会帮你做关联。

    위 내용은 springboot에서 여러 데이터 소스를 구성하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    원천:php.cn
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    인기 튜토리얼
    더>
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿