Spring Boot多数据源

maven 配置

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
     <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
 </dependencies>

application.properties 配置

配置两个数据源

## 数据源1
user.datasource.jdbc-url=jdbc:mysql://localhost:3306/test
user.datasource.username=root
user.datasource.password=root

## 数据源2
product.datasource.jdbc-url=jdbc:mysql://172.16.28.3:6606/test
product.datasource.username=root
product.datasource.password=meitu.com

数据实例

构建两个实例与两个数据源中的表格对应

user

@Entity
@Getter
@Setter
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
}    

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

product

@Entity
@Getter
@Setter
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
}

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

包结构

为了读取不同数据源的配置,根据包结构来对配置进行区分

src/main/java
    - com.wbl.springDemo
        - produce
            - data            
            - repo            
            - config
        - user
            - data
            - repo
            - config

ProductDao

@Repository
public interface ProductDao extends JpaRepository<Product, Integer> {
}                

UserDao

@Repository
public interface UserDao extends JpaRepository<User, Integer> {
}    

数据源配置

user配置

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "userEntityManagerFactory",
        transactionManagerRef = "userTransactionManager",
        basePackages = {
                "com.wbl.spingbootdemo.muldatasource.user.repo"
        }
)
public class UserConfig {
    @Primary
    @Bean("userDatasource")
    @ConfigurationProperties("user.datasource")
    public HikariDataSource userDatasource(){
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Primary
    @Bean("userEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("userDatasource")DataSource dataSource){
        return builder.dataSource(dataSource)
                .packages("com.wbl.spingbootdemo.muldatasource.user.data")
                .persistenceUnit("db1")
                .build();
    }

    @Primary
    @Bean("userTransactionManager")
    public PlatformTransactionManager userTransactionManager(@Qualifier("userEntityManagerFactory") EntityManagerFactory entityManagerFactory){
        return new JpaTransactionManager(entityManagerFactory);
    }
}

product 配置

@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "productEntityManagerFactory",
        transactionManagerRef = "productTransactionManager",
        basePackages = {
                "com.wbl.spingbootdemo.muldatasource.product.repo"
        }
)
public class ProductConfig {

    @Bean("productDatasource")
    @ConfigurationProperties(prefix = "product.datasource")
    public DataSource productDatasource(){
        return DataSourceBuilder.create().build();
    }

    @Bean("productEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean productEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("productDatasource")DataSource productDatasource){
        return builder.dataSource(productDatasource)
                .packages("com.wbl.spingbootdemo.muldatasource.product.data")
                .persistenceUnit("db2")
                .build();
    }

    @Bean(name = "productTransactionManager")
    public PlatformTransactionManager productTransactionManager(
            @Qualifier("productEntityManagerFactory") EntityManagerFactory productEntityManagerFactory
    ) {
        return new JpaTransactionManager(productEntityManagerFactory);
    }
}

其中@Primary的作用是,在对同一接口有几种不同实现时,告诉spring默认注入哪个实例

测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class MultipleDataSourcesProductTests {

    @Autowired
    ProductDao productDao;

    @Test
    @Transactional("productTransactionManager")
    public void testSaveProduct(){
        Product product = new Product();
        product.setName("product1");
        product = productDao.save(product);
        Assert.assertNotNull(productDao.findById(product.getId()));
    }
}        

@RunWith(SpringRunner.class)
@SpringBootTest
public class MultipleDataSourcesUserTests {
    @Autowired
    private UserDao userDao;

    @Test
//    @Transactional("userTransactionManager")
    public void testSaveUser(){
        User user = new User();
        user.setName("name");
        userDao.save(user);
    }
}

其中加入@Transactional注解,数据不会真正保存在数据库中

总结

spring boot 多数据源配置步骤总结

  1. 配置application.properties,填入数据源的详细信息
  2. 生成entity
  3. 生成entity对应的Repository
  4. 配置entityManager以及TransactionManager(事务管理)

Reprint please specify: wbl Spring Boot多数据源

Previous
Raft协议之Leader选举 Raft协议之Leader选举
Raft节点状态Raft协议的工作模式是一个Leader和多个Follower节点的模式。在Raft协议中,每个节点都维护了一个状态机,该状态机有3种状态,Leader,Follower,Candidate,在任意时间,集群中的任意节点都处
2019-03-30
Next
InfluxDB的RP与CQ InfluxDB的RP与CQ
Retention PolicyRP表示数据保留策略,策略包含数据保留时长,备份个数等信息。InfluxDB为每个database默认创建了一个默认的RP,名称为autogen,默认数据保留时间为永久。 查看RPshow retention
2019-03-16