Querying_And_Performance_Optimiz
1. JPQL & Criteria API
Viết JPQL Queries hiệu quả
Tránh SELECT : Chỉ chọn các cột cần thiết thay vì toàn bộ entity để giảm overhead.
Dùng
JOIN FETCH
: Khi cần lấy dữ liệu liên quan, dùngJOIN FETCH
thay vìJOIN
để tránh N+1 Query Problem.Dùng
COUNT(*)
riêng biệt: Nếu cần phân trang, hãy dùng một queryCOUNT(*)
riêng để tối ưu hiệu suất.
Khi nào nên dùng Criteria API thay vì JPQL?
Khi truy vấn động, không cố định điều kiện tìm kiếm.
Khi cần viết query theo cách type-safe thay vì string-based (giúp tránh lỗi cú pháp).
Khi query phức tạp và cần kết hợp nhiều điều kiện linh hoạt.
2. Specifications & QueryDSL
Cách sử dụng JpaSpecificationExecutor
Dùng
Specification<T>
để xây dựng truy vấn động.Kết hợp
CriteriaBuilder
để tạo điều kiện linh hoạt.Ví dụ tìm sản phẩm theo tên hoặc giá:
Sau đó kết hợp như sau:
QueryDSL là gì? So sánh với JPQL & Criteria API
QueryDSL là API giúp viết query type-safe, dễ đọc, hỗ trợ truy vấn động mạnh mẽ hơn Criteria API.
Ưu điểm:
Truy vấn ngắn gọn hơn Criteria API.
Có autocomplete trong IDE.
So sánh:
JPQL: Đơn giản, dễ dùng nhưng không linh hoạt khi query động.
Criteria API: Linh hoạt nhưng verbose, khó đọc.
QueryDSL: Linh hoạt, mạnh mẽ, dễ đọc hơn Criteria API.
3. Pagination & Sorting
Tối ưu Pagination khi dữ liệu lớn (Pageable
)
Dùng
PageRequest
vớiSort
:
Tránh
ORDER BY RAND()
vì tốn tài nguyên.
Offset Pagination vs Keyset Pagination
Offset Pagination (
LIMIT OFFSET
):Dễ dùng nhưng chậm khi offset lớn (phải duyệt qua nhiều dòng dữ liệu).
Keyset Pagination (
WHERE id > ? LIMIT ?
):Nhanh hơn vì dùng index, chỉ lấy phần tử tiếp theo thay vì duyệt toàn bộ bảng.
👉 Nên dùng Keyset Pagination khi xử lý danh sách lớn, như infinite scroll.
4. Projection & DTO Mapping
Cách sử dụng @Query
với JPQL & Native Queries để map kết quả vào DTO
Native Query với DTO:
Sau đó map kết quả vào DTO.
Khi nào dùng Interface Projection, Class Projection, hay Tuple?
Interface Projection: Dùng khi chỉ cần đọc dữ liệu đơn giản.
Class Projection: Khi cần xử lý dữ liệu trước khi trả về.
Tuple: Dùng khi cần query linh hoạt nhưng không muốn tạo DTO.
5. Cache & Performance Optimization
First-level Cache vs Second-level Cache
First-level Cache: Mặc định có trong Hibernate, cache theo session.
Second-level Cache: Dùng EhCache, Redis, Hazelcast để cache entity giữa các session. Sử dụng Redis Cache trong Spring Boot
Khi nào nên disable Hibernate auto-flush?
Cách batch insert, update, delete trong Spring Data JPA
Batch Insert:
Dùng JDBC batching thay vì JPA khi nào?
Khi cần hiệu suất cao, vì JPA có overhead quản lý entity.
Khi insert/update hàng loạt bản ghi.
Last updated