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。