1. Home
  2. Lập Trình
  3. Multiple Databases in Spring Boot / JdbcTemplate
Nguyễn Tuấn 5 tháng trước

Multiple Databases in Spring Boot / JdbcTemplate

Bài viết dưới đây mình sẽ hướng dẫn các bạn Connect Multiple Databases in Spring Boot hoặc sử dụng với JdbcTemplate. Để có thể sử dụng Multiple Databases chúng ta cần config Multiple DataSource. Sau đó config Multiple JdbcTemplate và Multiple TransactionManager.

Thêm thư viện Spring

Vì mình vừa sử dụng JdbcTemplate và JPA nên mình sẽ thêm 2 thư viện sau:

// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc
implementation 'org.springframework.boot:spring-boot-starter-jdbc'

// https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

Cấu hình trên cho các bạn sử dụng Gradle đối với các bạn sử dụng maven thì lên mvnrepository lấy config nhé.

Multiple Databases in Spring Boot / JdbcTemplate

Cấu hình file .properties / .yaml

Trong file application.properties hoặc application.yaml chúng ta sẽ config multiple datasource tới database mà mình cần. Mình lấy ví dụ 2 database là : iss ass

# Cấu hình cơ sở dữ liệu thứ nhất
spring.datasource.iss.jdbcUrl=jdbc:mariadb://10.20.3.999:3306/db-iss?autoReconnect=true
spring.datasource.iss.username=root
spring.datasource.iss.password=root
spring.datasource.iss.driverClassName=org.mariadb.jdbc.Driver

# Cấu hình cơ sở dữ liệu thứ hai
spring.datasource.ass.jdbcUrl=jdbc:mariadb://10.20.3.998:3306/db-ass?autoReconnect=true
spring.datasource.ass.username=root
spring.datasource.ass.password=root
spring.datasource.ass.driverClassName=org.mariadb.jdbc.Driver
spring:
    datasource:
        # Cấu hình cơ sở dữ liệu thứ nhất
        iss:
            jdbcUrl: jdbc:mariadb://10.20.3.999:3306/db-iss?autoReconnect=true
            username: root
            password: root
            driverClassName: org.mariadb.jdbc.Driver
        # Cấu hình cơ sở dữ liệu thứ hai
        ass:
            jdbcUrl: jdbc:mariadb://10.20.3.998:3306/db-ass?autoReconnect=true
            username: root
            password: root
            driverClassName: org.mariadb.jdbc.Driver

Cấu hình Bean cho DatabaseConfig

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
public class DatabaseConfig {

    @Bean(name = "issDataSource")
    @ConfigurationProperties(preiss = "spring.datasource.iss")
    @Primary
    public DataSource issDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "assDataSource")
    @ConfigurationProperties(preiss = "spring.datasource.ass")
    public DataSource assDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "issJdbcTemplate")
    @Autowired
    public JdbcTemplate issJdbcTemplate(@Qualifier("issDataSource") DataSource issDataSource) {
        return new JdbcTemplate(issDataSource);
    }

    @Bean(name = "assJdbcTemplate")
    @Autowired
    public JdbcTemplate assJdbcTemplate(@Qualifier("assDataSource") DataSource assDataSource) {
        return new JdbcTemplate(assDataSource);
    }

    @Bean(name = "iss")
    public PlatformTransactionManager issTransactionManager(@Qualifier("issDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "ass")
    public PlatformTransactionManager assTransactionManager(@Qualifier("assDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

}

Trong đoạn mã trên, mình đang cấu hình các DataSource, JdbcTemplate, và PlatformTransactionManager cho hai cơ sở dữ liệu khác nhau (iss ass). Đây là cách hoạt động của cấu hình:

  1. @Configuration: Đây là một annotation dùng để đánh dấu lớp DatabaseConfig là một lớp cấu hình Spring. Điều này cho phép Spring Boot biết rằng bạn đang cấu hình các bean và phụ thuộc Spring trong lớp này.
  2. @Bean: Đây là một annotation dùng để đánh dấu các phương thức trong lớp DatabaseConfig là các phương thức tạo bean. Mỗi phương thức trả về một bean được quản lý bởi Spring Container.
  3. @ConfigurationProperties: Annotation này được sử dụng để liên kết các thuộc tính từ file cấu hình application.properties (hoặc application.yml) vào các đối tượng Java. Trong ví dụ này, bạn đang sử dụng @ConfigurationProperties để cấu hình DataSource dựa trên các thuộc tính cụ thể trong application.properties cho hai cơ sở dữ liệu: iss ass.
  4. @Primary: Đánh dấu issDataSource là bean chính (primary bean) nếu có nhiều DataSource beans cùng loại. Điều này đồng nghĩa với việc khi bạn injet một DataSource mà không chỉ định rõ tên bean, Spring sẽ sử dụng issDataSource làm giá trị mặc định.
  5. @Autowired@Qualifier: Trong phương thức issJdbcTemplate assJdbcTemplate, bạn đang injet các DataSource beans vào các JdbcTemplate beans. Annotation @Autowired cho biết rằng bạn muốn Spring tự động injet các DataSource beans tương ứng vào phương thức. Annotation @Qualifier được sử dụng để chỉ định rõ tên của DataSource bean được injet nếu có nhiều DataSource beans cùng loại.
  6. PlatformTransactionManager: Đây là một bean dùng để quản lý giao dịch cho cơ sở dữ liệu. Bạn đang cấu hình hai PlatformTransactionManager beans cho iss ass sử dụng DataSource beans tương ứng. Điều này cho phép bạn quản lý giao dịch cho hai cơ sở dữ liệu riêng biệt.

Tóm lại, đoạn mã trên định nghĩa các DataSource, JdbcTemplate, và PlatformTransactionManager cho hai cơ sở dữ liệu khác nhau, đồng thời xác định issDataSource là bean chính (primary bean) cho DataSource mặc định.

Sử dụng với Multiple JdbcTemplate

Inject đối tượng JDBCTemplate bằng cách sử dụng annotation @Qualifier.

@Component
@Log4j2
@RequiredArgsConstructor
public class Repository {

    @Qualifier("issJdbcTemplate")
    private final JdbcTemplate issJdbcTemplate;
	
	@Qualifier("assJdbcTemplate")
    private final JdbcTemplate assJdbcTemplate;
	
	@Transactional(transactionManager = "iss")
    public void update(String channelId) throws SQLException {
        String sql = "UPDATE multi SET channel_id=?";

        Object[] param = new Object[] {
                channelId
        };

        issJdbcTemplate.update(sql, param);
    }
	
	@Transactional(transactionManager = "ass")
    public void update(String channelId) throws SQLException {
        String sql = "UPDATE multi SET channel_id=?";

        Object[] param = new Object[] {
                channelId
        };

        assJdbcTemplate.update(sql, param);
    }
	
	
}

Sử dụng với Spring JPA

Định nghĩa các entity class tương ứng với hai bảng iss_share ass_share. Ví dụ:

import javax.persistence.*;

@Entity
@Table(name = "iss_share")
public class IssShare {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private double price;

    // Getters and setters
}

@Entity
@Table(name = "ass_share")
public class AssShare {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private double price;

    // Getters and setters
}

Tạo các repository interface để thực hiện các truy vấn dữ liệu từ các entity. Ví dụ:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface IssShareRepository extends JpaRepository<IssShare, Long> {
    // Các phương thức truy vấn dữ liệu từ bảng iss_share
}

@Repository
public interface AssShareRepository extends JpaRepository<AssShare, Long> {
    // Các phương thức truy vấn dữ liệu từ bảng ass_share
}

Bây giờ, bạn có thể sử dụng các repository này để thực hiện các truy vấn dữ liệu từ hai bảng iss_shareass_share. Ví dụ:

@Service
public class ShareService {
    private final IssShareRepository issShareRepository;
    private final AssShareRepository assShareRepository;

    @Autowired
    public ShareService(IssShareRepository issShareRepository, AssShareRepository assShareRepository) {
        this.issShareRepository = issShareRepository;
        this.assShareRepository = assShareRepository;
    }

    public List<IssShare> getAllIssShares() {
        return issShareRepository.findAll();
    }

    public List<AssShare> getAllAssShares() {
        return assShareRepository.findAll();
    }
}

Trong ví dụ trên, ShareService sử dụng IssShareRepository AssShareRepository để thực hiện các truy vấn dữ liệu từ hai bảng iss_share ass_share. Các phương thức getAllIssShares getAllAssShares lấy danh sách tất cả các bản ghi từ hai bảng tương ứng.

Nhớ kiểm tra và cấu hình spring.datasource.issspring.datasource.ass trong tệp application.properties hoặc application.yml của bạn để đảm bảo rằng DataSource đã được thiết lập đúng cách cho JPA.

Khi bạn sử dụng Spring Data JPA cùng với Spring Boot, JPA sẽ tự động quét các package và tìm kiếm các entity class để tạo bản đồ đối tượng-tương ứng (Object-Relational Mapping) dựa trên các cấu hình bạn đã cung cấp. Điều này có nghĩa là JPA sẽ sử dụng các thông tin về package và annotation để xác định entity class và ánh xạ chúng với các bảng trong cơ sở dữ liệu.

197 lượt xem | 0 bình luận
Đồng ý Cookie
Trang web này sử dụng Cookie để nâng cao trải nghiệm duyệt web của bạn và cung cấp các đề xuất được cá nhân hóa. Bằng cách chấp nhận để sử dụng trang web của chúng tôi