Apache Derby Bài 42: Tích hợp Apache Derby vào hệ sinh thái Spring Boot (Spring Data JPA)
1. Mảnh ghép cuối cùng của kiến trúc Backend hiện đại
Ở Bài 41, chúng ta đã dùng Hibernate để loại bỏ việc viết câu lệnh SQL thủ công. Tuy nhiên, bạn vẫn phải tự tay viết các đoạn mã khởi tạo SessionFactory, mở Session, và kiểm soát Transaction (try-catch-rollback) một cách thủ công.
Trong các dự án doanh nghiệp hiện nay, Spring Boot kết hợp cùng Spring Data JPA là tiêu chuẩn "vàng". Khi nhúng Apache Derby vào Spring Boot, bạn sẽ nhận được 3 đặc quyền to lớn:
-
Tự động cấu hình (Auto-configuration): Không cần file
hibernate.cfg.xml. Cấu hình được tập trung vàoapplication.properties. -
HikariCP có sẵn: Spring Boot mặc định sử dụng HikariCP (Bài 40) làm Connection Pool.
-
Spring Data Repository: Viết các thao tác CRUD và tìm kiếm nâng cao mà không cần viết bất kỳ dòng code thực thi (implementation) nào.
-
Quản lý giao dịch khai báo: Chỉ cần gắn annotation
@Transactional, Spring sẽ tự động xử lýcommitvàrollback(Bài 30) phía sau hậu trường.
2. Khai báo thư viện (pom.xml)
Tạo một dự án Spring Boot mới (thông qua Spring Initializr) và đảm bảo bạn có các thư viện sau:
XML
<dependencies>
<!-- Cung cấp Spring Data JPA và tự động kéo theo Hibernate, HikariCP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Thư viện tạo RESTful API (Tùy chọn) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Thư viện Client của Apache Derby (Kết nối Network Server) -->
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.17.1.0</version>
</dependency>
</dependencies>
3. Cấu hình ứng dụng (application.properties)
Spring Boot giúp việc cấu hình CSDL trở nên vô cùng gọn nhẹ. Mở tệp src/main/resources/application.properties và khai báo kết nối tới máy chủ Derby Network Server của bạn:
Properties
# 1. Thông tin kết nối JDBC (Tương tự cấu hình HikariCP ở Bài 40)
spring.datasource.url=jdbc:derby://localhost:1527/my_company_db;create=true
spring.datasource.username=admin
spring.datasource.password=MatKhauSieuKho123
spring.datasource.driver-class-name=org.apache.derby.jdbc.ClientDriver
# 2. Tối ưu cấu hình HikariCP (Tùy chọn, Spring Boot đã có mặc định rất tốt)
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.connection-timeout=30000
# 3. Cấu hình Hibernate qua Spring JPA
# Chỉ định phương ngữ SQL của Derby
spring.jpa.database-platform=org.hibernate.dialect.DerbyDialect
# Hiển thị SQL ra console để debug
spring.jpa.show-sql=true
# Tự động cập nhật bảng (DDL) dựa trên Entity
spring.jpa.hibernate.ddl-auto=update
4. Xây dựng Repository: Phép thuật của Spring Data
Tái sử dụng lớp Thực thể NhanVien (có các annotation @Entity, @Id, @GeneratedValue(strategy = GenerationType.IDENTITY)) từ Bài 41.
Thay vì phải tự viết các hàm session.persist() hay session.get(), bạn chỉ cần tạo một Interface kế thừa từ JpaRepository.
Java
package com.hieu.derby.repository;
import com.hieu.derby.entity.NhanVien;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface NhanVienRepository extends JpaRepository<NhanVien, Integer> {
// Bạn chỉ cần khai báo TÊN HÀM theo chuẩn, Spring sẽ TỰ ĐỘNG sinh ra mã SQL!
// Tìm nhân viên theo Chức vụ
List<NhanVien> findByChucVu(String chucVu);
// Tìm nhân viên có lương lớn hơn một mức nào đó
List<NhanVien> findByLuongGreaterThan(Double mucLuong);
}
Ghi chú: Phía dưới hậu trường, khi bạn gọi findByChucVu("Backend"), Spring Data JPA sẽ dịch nó thành lệnh SELECT * FROM nhan_vien WHERE chuc_vu = 'Backend' để thực thi trên Derby.
5. Xây dựng Service với @Transactional
Tầng Service là nơi chứa logic nghiệp vụ. Chức năng quản lý Transaction mạnh mẽ nhất của Spring nằm ở Annotation @Transactional.
Java
package com.hieu.derby.service;
import com.hieu.derby.entity.NhanVien;
import com.hieu.derby.repository.NhanVienRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class NhanVienService {
@Autowired
private NhanVienRepository repository;
/**
* @Transactional sẽ tự động mở giao dịch.
* Nếu hàm chạy xong không có lỗi -> tự động COMMIT.
* Nếu có RuntimeException văng ra -> tự động ROLLBACK.
*/
@Transactional
public NhanVien tiepNhanNhanVienMoi(NhanVien nv) {
System.out.println("Đang lưu nhân viên mới vào Derby...");
return repository.save(nv); // Gọi hàm save() có sẵn của JpaRepository
}
@Transactional
public void tangLuongHangLoat(String chucVu, Double soTienTang) {
List<NhanVien> ds = repository.findByChucVu(chucVu);
for (NhanVien nv : ds) {
nv.setLuong(nv.getLuong() + soTienTang);
repository.save(nv);
}
// Giả sử có lỗi chia cho 0 ở đây, toàn bộ quá trình tăng lương sẽ bị Rollback
// int x = 10 / 0;
}
}
6. Trải nghiệm thực tế qua REST Controller
Để hoàn thiện, hãy đưa Service ra ngoài qua một API đơn giản:
Java
package com.hieu.derby.controller;
import com.hieu.derby.entity.NhanVien;
import com.hieu.derby.service.NhanVienService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/nhan-vien")
public class NhanVienController {
@Autowired
private NhanVienService service;
@PostMapping
public NhanVien create(@RequestBody NhanVien nv) {
return service.tiepNhanNhanVienMoi(nv);
}
}
Chạy ứng dụng Spring Boot (SpringApplication.run):
-
Ứng dụng khởi động, tự động kết nối tới Derby Network Server qua HikariCP.
-
Hibernate tự động kiểm tra xem bảng
nhan_vienđã có chưa, nếu chưa sẽ sinh ra lệnhCREATE TABLE. -
Bạn dùng Postman gửi request
POST /api/nhan-vien, dữ liệu sẽ được lưu an toàn xuống CSDL với sự bảo vệ của Spring Transaction.
7. Tổng kết
Tích hợp Apache Derby vào Spring Boot là minh chứng rõ ràng nhất cho sức mạnh của chuẩn JDBC và JPA. Chỉ bằng việc thay đổi vài dòng application.properties, bạn đã đưa Derby vào một hệ sinh thái mạnh mẽ nhất của Java, biến nó thành một Database thực thụ phục vụ cho các dịch vụ Microservices hoặc Web App.
Tuy nhiên, sức mạnh lớn nhất của Apache Derby so với MySQL hay PostgreSQL trong hệ sinh thái Java không chỉ nằm ở khả năng chạy Network Server. Đặc sản thực sự của Derby là khả năng khởi tạo một CSDL hoàn toàn "Tạm thời" trong bộ nhớ RAM, phục vụ hoàn hảo cho việc kiểm thử tự động (Unit/Integration Test) trong Spring Boot.
Bài tiếp theo sẽ trình bày kỹ thuật đỉnh cao này: Apache Derby Bài 43: Sử dụng Derby In-Memory Mode cho Unit/Integration Test trong Spring Boot.
All rights reserved