Spring Boot应用中集成与使用多数据源

Spring Boot应用中集成与使用多数据源

1. 前言

通过定义和使用多个数据源,能在Spring Boot应用中实现更复杂的数据管理场景,比如读写分离、数据冗余等。

2. 准备工作
  • 环境准备:确保已经准备好Spring Boot的开发环境。
  • 数据库准备:在本地或云服务上创建两个数据库,如下文所示。

3. 创建Spring Boot项目
  1. 使用Spring Initializr创建项目:https://start.spring.io/。
  2. 在pom.xml中添加必要的依赖,包括JPA、Spring Boot Parent、数据库驱动等。

4. 配置多数据源

在application.yml或application.properties中配置:

yaml 复制代码
# application.yml
spring:
  datasource:
    primary:
      url: jdbc:mysql://localhost:3306/db1
      username: user
      password: password
      driver-class-name: com.mysql.jdbc.Driver
      hikari:
        connection-timeout: 30000
        maximum-pool-size: 20

    secondary:
      url: jdbc:mysql://localhost:3306/db2
      username: user
      password: password
      driver-class-name: com.mysql.jdbc.Driver
      hikari:
        connection-timeout: 30000
        maximum-pool-size: 20

5. 创建实体类及Repository

Entity Class - User (For Primary Database):

java 复制代码
package com.example.multidatasource.entity;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "users")
public class User {
    @Id
    private Long id;
    private String name;
    private String email;

    // getter, setter, constructors
}

Entity Class - Product (For Secondary Database):

java 复制代码
package com.example.multidatasource.entity;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "products")
public class Product {
    @Id
    private Long id;
    private String name;
    private int price;

    // getter, setter, constructors
}

Repository (Primary):

java 复制代码
package com.example.multidatasource.repository;

import com.example.multidatasource.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

Repository (Secondary):

java 复制代码
package com.example.multidatasource.repository;

import com.example.multidatasource.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
}
6. 服务层配置与使用多数据源
java 复制代码
package com.example.multidatasource.service;

import com.example.multidatasource.entity.Product;
import com.example.multidatasource.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

    private final ProductRepository productRepository;

    @Autowired
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public Product createProduct(String name, int price) {
        Product product = new Product();
        product.setName(name);
        product.setPrice(price);
        return productRepository.save(product);
    }
}

服务层同样应当遵循具体数据源的配置,确保通过合适的数据源进行持久化操作。

7. 事务与多数据源管理

针对跨数据源的事务操作,需要在@Service中配置@Transactional注解:

java 复制代码
@Service
public class MultiDataSourceTransactionService {

    private final UserRepository userRepository;
    private final ProductRepository productRepository;

    @Autowired
    public MultiDataSourceTransactionService(UserRepository userRepository, ProductRepository productRepository) {
        this.userRepository = userRepository;
        this.productRepository = productRepository;
    }

    // So that it's only using the primary dataSource
    @Transactional(propagation = Propagation.REQUIRED)
    public void performCreateUserAndProduct() {
        userRepository.save(new User("John Doe", "john@example.com"));
        productRepository.save(new Product("Widget", 1000));
    }
}

通过这种方式,可以确保同一个请求中的所有操作,要么全部成功,要么全部回滚。

8. 配置及测试

确保所有的Bean和配置类被正确注解,测试应用是否能够启动,数据源是否能够正确读写数据。

相关推荐
实名上网宋凯宣9 小时前
Django
后端·python·django
天河归来10 小时前
第三方接口不稳定,如何让核心任务继续完成
java·大数据
Knight_AL10 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
利威尔xu10 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
逃逸线LOF11 小时前
Ribbon负载均衡原理(Irule组件、源码分析)
后端·spring cloud·ribbon
砚底藏山河11 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
慢云智慧空间11 小时前
从设备智能到空间理解,空间智能终端解决方案商如何重新定义行业标准
后端
利威尔xu12 小时前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
猿究院_夏燊12 小时前
MySQL 的四种隔离级别
java·数据库·mysql
薛定谔的猫-菜鸟程序员12 小时前
软件架构设计师开发资料大全(从入门到精通)
后端·python·系统架构·flask·架构设计师