1. 程式人生 > >SpringBoot(6)

SpringBoot(6)

翻譯的官方文件,個人理解,僅供參考。

Spring框架為使用SQL資料庫提供了廣泛的支援。從使用JdbcTemplate直接以JDBC方式訪問到完全的Hibernate物件關係對映技術訪問。Spring Data提供了更多級別的功能,直接從介面建立Repository實現,並使用約定從方法名稱生成查詢。

1. 配置資料來源

java的javax.sql.DataSource介面提供一種使用資料庫連線的標準方法。傳統上,DataSource使用URL和一些憑據來建立資料庫連線。

1.1 嵌入式資料庫的支援

一般來說,使用記憶體型嵌入式資料庫開發應用程式是非常方便的。很明顯的,記憶體型資料庫不需要提供持久化儲存;需要在應用程式啟動時填充資料庫,並準備在應用程式結束時丟棄資料。

SpringBoot可以自動配置H2、HSQL和Derby嵌入式資料庫。我們不需要提供任何連線的URL,僅僅需要新增想要使用的嵌入式資料庫的依賴即可。

提示:如果在測試中使用此功能,整個測試過程中都會重複使用相同的資料庫,無論使用的應用程式上下文的數量如何。假如想要每個上下文都有各自的嵌入式資料庫,設定spring.datasource.generate-unique-name=true

示例:典型的POM依賴如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <scope>runtime</scope>
</dependency>

注:

  • 一般需要依賴spring-jdbc才能自動配置嵌入式資料庫。本例中spring-boot-starter-data-jpa自動添加了spring-jdbc依賴。
  • 如果由於某種原因,確實為嵌入式資料庫配置了連線URL,則應注意確保禁用資料庫的自動關閉。 如果使用H2,則應使用DB_CLOSE_ON_EXIT=FALSE來執行此操作。如果使用的是HSQLDB,則應確保不使用shutdown=true。 禁用資料庫的自動關閉,從而確保一旦不再需要訪問資料庫時,Spring Boot控制資料庫何時關閉。

1.2 連線到生產資料庫

生產資料庫可以使用資料來源連線池自動配置。以下是選擇特定實現的演算法:

  • 優先選擇Tomcat資料庫連線池,因為它的效能和併發性。
  • 第二選擇HikariCP
  • 第三選擇DBCP,但是SpringBoot不推薦在生產環境使用
  • 第四選擇DBCP2

假如使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa的starter,將會自動新增tomcat-jdbc依賴並且使用它。

提示:

  • 可以完全該演算法,並通過spring.datasource.type屬性指定要使用的連線池。如果在Tomcat容器中執行應用程式,則這一點尤其重要,因為預設情況下提供了tomcat-jdbc。
  • 可以手動配置其他連線池。 如果定義自己的DataSource bean,則不會進行自動配置。

資料來源配置由spring.datasource.*中的外部配置屬性控制。 例如,可以在application.properties中宣告以下部分:

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

提示:

  • 至少應該使用spring.datasource.url屬性指定url,否則Spring Boot將嘗試自動配置嵌入式資料庫。
  • 通常不需要指定驅動程式類名稱,因為Spring可以從URL中推斷出大多數資料庫。
  • 對於要建立的資料庫連線,SpringBoot在執行操作前檢查Driver類是否可用。例如,設定spring.datasource.driver-class-name=com.mysql.jdbc.Driver,那麼該類必須是可載入的。

檢視DataSourceProperties獲取更多選項。這些是標準的選項,不論實際的實現是什麼。也可以使用各自的字首(spring.datasource.tomcat.*,spring.datasource.hikari.*和spring.datasource.dbcp2.*)來微調特定實現的設定。

例如,如果使用的是Tomcat連線池,則可以自定義許多其他設定:

# 如果沒有可用的連線,則在丟擲異常之前要等待的ms數
spring.datasource.tomcat.max-wait=10000

# 可以同時從此池分配的最大活動連線數
spring.datasource.tomcat.max-active=50

# 在從池中獲取連線之前驗證連線
spring.datasource.tomcat.test-on-borrow=true

1.3 連線到JNDI資料來源

如果要將Spring Boot應用程式部署到Application Server,則可能需要使用Application Server內建功能配置和管理DataSource,並使用JNDI訪問它。

spring.datasource.jndi-name屬性可用作spring.datasource.url,spring.datasource.username和spring.datasource.password屬性的替代,以從特定JNDI位置訪問DataSource。 例如,application.properties中的以下部分顯示瞭如何訪問JBoss AS定義的資料來源:

spring.datasource.jndi-name=java:jboss/datasources/customers

2. 使用JdbcTemplate

Spring的JdbcTemplate和NamedParameterJdbcTemplate類被自動配置,可以在自己的bean中通過@Autowire註解直接使用。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {
    @Autowired
    private JdbcTemplate jdbcTemplate;
}

3. JPA和'Spring Data'

Java Persistence API(JPA)是一種標準技術,允許將物件“對映”到關係資料庫。spring-boot-starter-data-jpa POM提供一種快速開始的方式。它提供了以下關鍵的依賴:

  • Hibernate:最流行的JPA實現之一
  • Spring Data JPA:使實現基於JPA的儲存庫變得容易
  • Spring ORMS:Spring框架提供的核心ORM支援

提示:預設SpringBoot使用Hibernate5.0.x,也可以使用4.3.x or 5.2.x 。具體可以參考Hibernate4和Hibernate5.2的demo。

3.1 實體類

傳統上,JPA“實體”類在persistence.xml檔案中指定。 使用Spring Boot,此檔案不是必需的,而是使用“實體掃描”。 預設情況下,將搜尋主配置類下面的所有包(使用@EnableAutoConfiguration或@SpringBootApplication註釋的包)。

任何使用@Entity,@Embeddable或@MappedSuperclass註釋的類都將被考慮。 典型的實體類看起來像這樣:

package com.example.myapp.domain;

import java.io.Serializable;
import javax.persistence.*;

@Entity
public class City implements Serializable {
    @Id
    @GeneratedValue
    private Long id;
    @Column(nullable = false)
    private String name;
    @Column(nullable = false)
    private String state;

    // 其他成員屬性,通常包括@OneToMany對映
    protected City() {
        // JPA規範要求無參構造器,應該是protected,因為它不應該直接使用
    }
    public City(String name, String state) {
        this.name = name;
        this.country = country;
    }
    public String getName() {
        return this.name;
    }
    public String getState() {
        return this.state;
    }
    // ...
}

可以使用@EntityScan註釋自定義實體掃描位置。

3.2 Spring Data JPA Repositories

Spring Data JPA Repositories是可以定義以訪問資料的介面。 JPA查詢是根據方法名稱自動建立的。 例如,CityRepository介面可能會宣告一個findAllByState(String state)方法來查詢給定狀態中的所有城市。

對於更復雜的查詢,可以使用Spring Data Query註解對方法進行註釋。

Spring Data repositories 通常從Repository或CrudRepository介面擴充套件。 如果使用自動配置,則將從包含主配置類(使用@EnableAutoConfiguration或@SpringBootApplication註解的)的包中搜索。

下面是典型的Spring Data repository:

package com.example.myapp.domain;

import org.springframework.data.domain.*;
import org.springframework.data.repository.*;

public interface CityRepository extends Repository<City, Long> {
    Page<City> findAll(Pageable pageable);
    City findByNameAndCountryAllIgnoringCase(String name, String country);
}

3.3 建立和刪除JPA資料庫

預設情況下,僅當使用嵌入式資料庫(H2,HSQL或Derby)時,才會自動建立JPA資料庫。 可以使用spring.jpa.*屬性顯式配置JPA設定。 例如,要建立和刪除表,可以將以下內容新增到application.properties中:

spring.jpa.hibernate.ddl-auto=create-drop

注:Hibernate自己的內部屬性名稱是hibernate.hbm2ddl.auto。 可以使用spring.jpa.properties.*(在將它們新增到實體管理器之前剝離字首)來設定它以及其他Hibernate本機屬性。 例:

spring.jpa.properties.hibernate.globally_quoted_identifiers=true

將hibernate.globally_quoted_identifiers傳遞給Hibernate實體管理器。

預設情況下,DDL執行(或校驗)將延遲到ApplicationContext啟動。 還有一個spring.jpa.generate-ddl標誌,但如果Hibernate autoconfig處於活動狀態,則不會使用它,因為ddl-auto設定更精細。

3.4 Open EntityManager in View

如果正在執行Web應用程式,Spring Boot將預設註冊OpenEntityManagerInViewInterceptor以應用“Open EntityManager in View”模式,即允許在Web檢視中進行延遲載入。 如果不想要此行為,則應在application.properties中將spring.jpa.open-in-view設定為false。

4. 使用H2的web控制檯

H2資料庫提供了一個基於瀏覽器的控制檯,Spring Boot可以為您自動配置。 滿足以下條件時,將自動配置控制檯:

  • 開發一個web應用程式
  • com.h2database:h2在classpath下
  • 使用SpringBoot的developer tools

注:如果沒有使用Spring Boot的developer tools,但仍想使用H2的控制檯,那麼可以通過配置spring.h2.console.enabled=true屬性來實現。H2控制檯僅用於開發期間,因此應注意確保spring.h2.console.enabled在生產中未設定為true。

4.1 改變H2控制檯的路徑

預設情況下,控制檯將在/h2-console上可用。可以使用spring.h2.console.path屬性自定義控制檯的路徑。

4.2 確保H2控制檯的安全

當Spring Security在類路徑上並啟用基本身份驗證時,H2控制檯將使用基本身份驗證自動保護。 以下屬性可用於自定義安全性配置:

  • security.user.role
  • security.basic.authorize-mode
  • security.basic.enabled

5. 使用jOOQ

Java面向物件查詢(jOOQ)是Data Geekery的一個流行產品,它從您的資料庫生成Java程式碼,並允許您通過其流暢的API構建型別安全的SQL查詢。 商業版和開源版都可以與Spring Boot一起使用。

5.1 程式碼生成

要使用jOOQ型別安全查詢,需要從資料庫模式生成Java類。 可以按照jOOQ使用者手冊中的說明進行操作。 如果您使用的是jooq-codegen-maven外掛(並且還使用了spring-boot-starter-parent“父POM”),則可以安全地省略外掛的<version>標記。 還可以使用Spring Boot定義的版本變數(例如h2.version)來宣告外掛的資料庫依賴性。 這是一個例子:

<plugin>
    <groupId>org.jooq</groupId>
    <artifactId>jooq-codegen-maven</artifactId>
    <executions>
        ...
    </executions>
    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <jdbc>
            <driver>org.h2.Driver</driver>
            <url>jdbc:h2:~/yourdatabase</url>
        </jdbc>
        <generator>
            ...
        </generator>
    </configuration>
</plugin>

5.2 使用DSLContext

jOOQ提供的流暢API通過org.jooq.DSLContext介面啟動。 Spring Boot會將DSLContext自動配置為Spring Bean並將其連線到應用程式DataSource。 要使用DSLContext,只需@Autowire:

@Component
public class JooqExample implements CommandLineRunner {
    private final DSLContext create;
    @Autowired
    public JooqExample(DSLContext dslContext) {
        this.create = dslContext;
    }
}

然後可以使用DSLContext構建查詢:

public List<GregorianCalendar> authorsBornAfter1980() {
    return this.create.selectFrom(AUTHOR)
        .where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
        .fetch(AUTHOR.DATE_OF_BIRTH);
}

5.3 自定義jOOQ

可以通過在application.properties中設定spring.jooq.sql-dialect來自定義jOOQ使用的SQL方言。 例如,要指定Postgres,需要新增:

spring.jooq.sql-dialect=Postgres

通過定義自己的@Bean定義可以實現更高階的自定義,這些定義將在建立jOOQ配置時使用。 可以為以下jOOQ型別定義bean:

  • ConnectionProvider
  • TransactionProvider
  • RecordMapperProvider
  • RecordListenerProvider
  • ExecuteListenerProvider
  • VisitListenerProvider

如果要完全控制jOOQ配置,還可以建立自己的org.jooq.Configuration @Bean。