首頁 > 軟體

Spring Boot整合持久層之JdbcTemplate多資料來源

2022-08-13 18:01:35

多資料來源

所謂多資料來源,就是一個 Java EE 專案中採用了不同資料庫範例中的多個庫,或者同一個資料庫範例中多個不同的庫。一般來說,採用 MyCat 等分散式資料庫中介軟體是比較好的解決方案,這樣可以把資料庫讀寫分離、分庫分表、備份等操作交給中介軟體去做,Java 程式碼只需要專注於業務即可。不過這並不意味著無法使用 Java 程式碼解決類似的問題,在 Spring Framework 中就可以設定多資料來源,Spring Boot 繼承其衣鉢,只不過設定方式有所變化。

JdbcTemplate 多資料來源

JdbcTemplate 多資料來源是比較簡單的,因為一個 JdbcTemplate 對應一個 DataSource,開發者只需要手動提供多個 DataSource ,再手動設定 JdbcTemplate 即可。

1. 建立資料庫

建立兩個資料庫:chapter05-1 和 chapter05-2.兩個庫中都建立 book 表,再各預設 1 條資料,指令碼如下

create database `chapter05-1` default character set utf8;
CREATE TABLE `chapter05-1`.`book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `author` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `chapter05-1`.`book`(`id`, `name`, `author`) VALUES (1, '水滸傳', '施耐庵');
create database `chapter05-2` default character set utf8;
CREATE TABLE `chapter05-2`.`book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `author` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `chapter05-2`.`book`(`id`, `name`, `author`) VALUES (1, '三國演義', '羅貫中');

2.建立專案

建立 Spring Boot Web 專案,新增如下依賴:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid-spring-boot-starter</artifactId>
  <version>1.1.10</version>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <scope>runtime</scope>
</dependency>

注意這裡新增的資料庫連線池依賴是 druid-spring-boot-starter 。druid-spring-boot-starter 可以幫助開發者在 Spring Boot 專案中輕鬆整合 Druid 資料庫連線池和監控。

3. 設定資料庫連線

在application.properties 中設定資料庫連線資訊

# 資料來源1
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.url=jdbc:mysql://localhost:3306/chapter05-1?useUnicode=true&characterEncoding=utf8&useSSL=true
spring.datasource.one.username=root
spring.datasource.one.password=root
# 資料來源2
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.url=jdbc:mysql://localhost:3306/chapter05-2?useUnicode=true&characterEncoding=utf8&useSSL=true
spring.datasource.two.username=root
spring.datasource.two.password=root

4. 設定資料來源

建立 DataSourceConfig 設定資料來源,根據 application.properties 中的設定生成兩個資料來源

@Configuration
public class DataSourceConfig {
    @Bean
    @ConfigurationProperties("spring.datasource.one")
    DataSource dsOne() {
        return DruidDataSourceBuilder.create().build();
    }
    @Bean
    @ConfigurationProperties("spring.datasource.two")
    DataSource dsTwo() {
        return DruidDataSourceBuilder.create().build();
    }
}

程式碼解釋:

  • DataSourceConfig 中提供了兩個資料來源:dsOne 和 dsTwo,預設方法名即範例名
  • @ConfigurationProperties 註解表示使用不同字首的組態檔來建立不同的 DataSource 範例

5. 設定 JdbcTemplate

在 5.1節 中得知,只要引入了 spring-jdbc 依賴,開發者沒有提供 JdbcTemplate 範例時,Spring Boot 預設會提供一個 JdbcTemplate 範例。現在設定多資料來源時,由開發者自己提供 JdbcTemplate 範例

@Configuration
public class JdbcTemplateConfig {
    @Bean
    JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    @Bean
    JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

程式碼解釋:

JdbcTemplateConfig 中提供兩個 JdbcTemplate 範例。每個 JdbcTemplate 範例都需要提供 DataSource,由於Spring 容器中有兩個 DataSource 範例,因此需要通過方法名查詢。@Qualifier 註解表示查詢不同名稱的 DataSource 範例注入進來

6. 建立BookController

建立實體類 Book 和 BookController 進行測試

public class Book {
    private Integer id;
    private String name;
    private String author;
    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", author='" + author + ''' +
                '}';
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
}
@RestController
public class BookController {
    @Resource(name = "jdbcTemplateOne")
    JdbcTemplate jdbcTemplate;
    @Autowired
    @Qualifier("jdbcTemplateTwo")
    JdbcTemplate jdbcTemplateTwo;
    @GetMapping("/test1")
    public void test1() {
        List<Book> books1 = jdbcTemplate.query("select * from book",
                new BeanPropertyRowMapper<>(Book.class));
        List<Book> books2 = jdbcTemplateTwo.query("select * from book",
                new BeanPropertyRowMapper<>(Book.class));
        System.out.println("books1:"+books1);
        System.out.println("books2:"+books2);
    }
}

簡單起見,這裡沒有新增 service 層,而是直接將 JdbcTemplate 注入到了 Controller 中。在Controller 中注入兩個不同的 JdbcTemplate 有兩種方式:一種是使用 @Resource 註解,並指明 name 屬性,即按 name 進行裝配,此時會根據範例名查詢相應的範例注入;另一種是使用 @Autowired 註解結合 @Qualifier 註解,效果等同於使用 @Resource 註解。

7. 測試

http://localhost:8081/test1,檢視列印紀錄檔

books1:[Book{id=1, name='水滸傳', author='施耐庵'}]
books2:[Book{id=1, name='三國演義', author='羅貫中'}]

到此這篇關於Spring Boot整合持久層之JdbcTemplate多資料來源的文章就介紹到這了,更多相關Spring Boot JdbcTemplate 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com