Hibernate 反應式簡介
1. 概述
響應式程式設計是一種強調非同步資料流和非阻塞操作原則的程式設計範式。主要目標是建立可以處理多個並發事件並即時處理它們的應用程式。
傳統上,在命令式程式設計中,我們會依序執行程式碼,一次一條指令。然而,在反應式程式設計中,我們可以同時處理多個事件,這使我們能夠創建更具響應性和可擴展性的應用程式。
本教學將介紹 Hibernate Reactive 編程,包括基礎知識、它與傳統命令式編程的區別,以及將 Hibernate Reactive 與 Spring Boot 結合使用的分步指南。
2. 什麼是 Hibernate 響應式?
Reactive Hibernate 是 Hibernate ORM 框架的擴展,廣泛用於將物件導向的程式設計模型對應到關聯式資料庫。此擴充功能將響應式程式設計概念融入 Hibernate,使 Java 應用程式能夠更有效率、更靈敏地與關聯式資料庫互動。透過整合非阻塞 I/O 和非同步資料處理等反應原理,Reactive Hibernate 允許開發人員在其 Java 應用程式中創建高度可擴展和響應靈敏的資料庫互動。
Hibernate Reactive 擴展了流行的 Hibernate ORM 框架以支援反應式程式設計範例。此擴充功能使開發人員能夠建立能夠處理大型資料集和高流量負載的反應式應用程式。 Hibernate Reactive 的一個顯著優勢是它能夠促進非同步資料庫訪問,確保應用程式可以同時處理多個請求,而不會產生瓶頸。
3. 有何特別之處
在傳統的資料庫互動中,當程式向資料庫發送請求時,它必須等待回應才能繼續下一個任務。此等待時間可能會增加,特別是在嚴重依賴資料庫的應用程式中。 Hibernate Reactive 引入了一種非同步處理資料庫互動的新方法。
這意味著程式可以在等待資料庫回應的同時執行其他任務,而不是等待每個資料庫操作完成後再繼續。
這個概念類似於在收銀員處理付款的同時能夠繼續購物。 Hibernate Reactive 允許程式在等待資料庫回應時執行其他任務,從而顯著提高應用程式的整體效率、效能、資源利用率和回應能力。
這在高流量電子商務網站等場景中尤其重要,其中應用程式必須處理許多並髮用戶或同時執行多個資料庫操作。
在這種情況下,Hibernate Reactive 在等待資料庫回應的同時繼續執行其他任務的能力可以極大地提高應用程式的效能和使用者體驗。 Hibernate Reactive 為開發人員提供了建構高度可擴展和響應式應用程式的工具。它使這些應用程式能夠在不犧牲效能的情況下處理繁重的資料庫工作負載。這展示了 Hibernate Reactive 在熟練開發人員手中的潛力。解釋這些要點有助於理解 Hibernate Reactive 與傳統資料庫互動有何不同,以及為什麼它有利於創建現代 Java 應用程式。但是,需要注意的是,Hibernate Reactive 可能不適合所有用例,尤其是那些需要嚴格事務一致性或具有複雜資料存取模式的用例。
4.Maven依賴
在開始之前,我們需要將Hibernate Reactive Core和Reactive Relational Database Connectivity (R2DBC)相依性新增至 pom.xml 檔案:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.reactive</groupId>
<artifactId>hibernate-reactive-core</artifactId>
</dependency>
5. 新增反應存儲庫
在傳統的 Spring Data 中,儲存庫同步處理資料庫互動。反應式儲存庫非同步執行這些操作,使它們更具響應性。
5.1.實體
實體與傳統應用程式中使用的傳統實體相同:
@Entity
public class Product {
@Id
private Long id;
private String name;
}
5.2.反應式儲存庫介面
反應式儲存庫是擴展R2dbcRepository
的專用接口,旨在支援關聯式資料庫(R2DBC)的反應式程式設計。 Hibernate 中的這些儲存庫提供了一系列為非同步操作量身定制的方法,包括保存、尋找、更新和刪除。這種非同步方法允許與資料庫進行非阻塞交互,使其非常適合高並發和高吞吐量的應用程式:
@Repository
public interface ProductRepository extends R2dbcRepository<Product, Long> {
}
響應式儲存庫會傳回響應式類型,例如Mono
(對於單一結果)或Flux
(對於多個結果),從而允許處理非同步資料庫互動。
6. 新增響應式服務
在 Spring Boot 中,反應式服務旨在利用反應式程式設計原理非同步處理業務邏輯,從而提高應用程式的回應能力和可擴展性。與服務類別同步執行業務邏輯的傳統 Spring 應用程式相比,反應式應用程式具有傳回反應式類型的服務方法,以有效管理非同步操作。這種方法可以更有效地利用資源並改善並發請求的處理:
@Service
public class ProductService {
private final ProductRepository productRepository;
@Autowired
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public Flux<Product> findAll() {
return productRepository.findAll();
}
public Mono<Product> save(Product product) {
return productRepository.save(product);
}
}
與儲存庫一樣,服務方法傳回Mono
或Flux
等響應式類型,允許它們執行非同步操作而不會阻塞應用程式。
7. 單元測試
反應式單元測試是軟體開發中的基本實踐,專注於單獨測試各個應用程式組件以確保其正常運作。特別是在反應式應用程式中,單元測試在驗證反應式元件(例如控制器、服務和儲存庫)的行為方面發揮著至關重要的作用。對於反應式服務,單元測試對於確保服務方法表現出預期的行為非常重要,包括管理非同步操作和正確處理錯誤情況。這些測試有助於確保應用中反應組件的可靠性和有效性:
public class ProductServiceUnitTest {
@Autowired
private ProductService productService;
@Autowired
private ProductRepository productRepository;
@BeforeEach
void setUp() {
productRepository.deleteAll()
.then(productRepository.save(new Product(1L, "Product 1", "Category 1", 10.0)))
.then(productRepository.save(new Product(2L, "Product 2", "Category 2", 15.0)))
.then(productRepository.save(new Product(3L, "Product 3", "Category 3", 20.0)))
.block();
}
@Test
void testSave() {
Product newProduct = new Product(4L, "Product 4", "Category 4", 24.0);
StepVerifier.create(productService.save(newProduct))
.assertNext(product -> {
assertNotNull(product.getId());
assertEquals("Product 4", product.getName());
})
.verifyComplete();
StepVerifier.create(productService.findAll())
.expectNextCount(4)
.verifyComplete();
}
@Test
void testFindAll() {
StepVerifier.create(productService.findAll())
.expectNextCount(3)
.verifyComplete();
}
}
八、結論
在本教程中,我們介紹了使用 Hibernate Reactive 和 Spring Boot 建立反應式應用程式的基礎知識。我們也討論了好處以及如何定義和實作反應式元件。我們還解決了反應組件的單元測試,強調創建現代、高效和可擴展應用程式的能力。與往常一樣,本教學的源代碼可在 GitHub 上取得。