+1

JPQL Spring Data JPA: Ghi chép cho người mới bắt đầu

Spring Data JPA – JPQL

Bài này mình viết theo kiểu vừa học vừa ghi chép, câu chữ đơn giản, đôi chỗ hơi ngô ngố một chút cho dễ nhớ 😅. Nếu bạn mới học JPA, đọc tới đâu hiểu tới đó là ok.


1. JPQL là cái gì vậy?

Nói ngắn gọn:

  • JPQL (Java Persistence Query Language) là ngôn ngữ truy vấn dành cho JPA.
  • giống SQL nhưng KHÔNG viết trên bảng (table) mà viết trên Entity (class Java).

👉 SQL: làm việc với bảng + cột trong database 👉 JPQL: làm việc với class Entity + thuộc tính

Ví dụ:

  • SQL: SELECT * FROM category
  • JPQL: SELECT c FROM Category c

Lúc đầu nhìn sẽ hơi ngược ngược, nhưng quen rồi thì thấy JPQL khá là “Java friendly”.


2. Vì sao không dùng SQL luôn cho nhanh?

Câu hỏi rất đời 😄

Dùng SQL được, nhưng JPQL có mấy cái lợi:

  • Không phụ thuộc DB (MySQL, PostgreSQL, Oracle… đổi DB ít đau đầu hơn)
  • Làm việc trực tiếp với Entity → trả về object Java luôn
  • Spring Data JPA hỗ trợ sẵn, code gọn hơn

👉 Hiểu đơn giản: JPQL sinh ra để nói chuyện với Entity, không phải với database.


3. JPQL thường được viết ở đâu?

Hay gặp nhất là trong @Query của Spring Data JPA.

Ví dụ:

@Query("SELECT c FROM Category c")
List<Category> findAllCategory();

Ở đây:

  • CategoryEntity
  • c là alias (đặt tên cho dễ gọi)

4. Ví dụ kinh điển: WHERE trong JPQL

Giả sử Entity Category có field name.

@Query("SELECT c FROM Category c WHERE c.name = :name")
List<Category> findByName(String name);

Giải thích kiểu bình dân:

  • c.name → thuộc tính name trong class Category
  • :name → tham số truyền từ method vào

5. JPQL + LIKE (tìm kiếm gần đúng)

Ví dụ tìm category có tên chứa chữ java:

@Query("SELECT c FROM Category c WHERE c.name LIKE %:name%")
List<Category> searchByName(String name);

Nếu sợ hoa – thường (Java, JAVA, java):

@Query("SELECT c FROM Category c WHERE LOWER(c.name) LIKE LOWER(CONCAT('%', :name, '%'))")
List<Category> searchIgnoreCase(String name);

👉 LOWER() cho chắc ăn, khỏi lăn tăn chữ hoa chữ thường.


6. Case hơi khó hiểu (nhưng gặp nhiều)

Ví dụ:

@Query("SELECT c FROM Category c WHERE :name IS NULL OR :name = '' OR LOWER(c.name) LIKE LOWER(CONCAT('%', :name, '%'))")
List<Category> filter(@Param("name") String name);

Đọc lần đầu là muốn bỏ chạy 😵‍💫 nhưng bóc ra từng ý thì rất hợp lý:

  • :name IS NULL → không truyền gì
  • :name = '' → truyền chuỗi rỗng
  • LIKE ... → có keyword thì tìm theo keyword

👉 Hiểu đơn giản:

Nếu không nhập gì → trả về tất cả Nếu có nhập → lọc theo tên

Cái này hay dùng cho search + filter trong admin.


7. JPQL SELECT những gì?

7.1. SELECT Entity (hay dùng nhất)

SELECT c FROM Category c

→ trả về Category

7.2. SELECT một vài field

SELECT c.name FROM Category c

→ trả về List<String>

Hoặc:

SELECT new com.example.dto.CategoryDTO(c.id, c.name)
FROM Category c

→ trả về DTO (xịn hơn chút 😎)


8. JPQL vs SQL (so nhanh cho dễ nhớ)

SQL JPQL
Table Entity
Column Field
SELECT * SELECT alias
JOIN bảng JOIN Entity

👉 Nhớ câu này là đủ:

JPQL không biết bảng là gì, nó chỉ biết Entity.


9. Lỗi người mới hay gặp (mình dính đủ rồi 😭)

  • ❌ Viết tên bảng thay vì tên Entity
  • ❌ Viết tên cột DB thay vì field trong class
  • ❌ Quên alias (c)
  • ❌ Sai package khi dùng new DTO()

10. Kết bài (viết cho chính mình đọc lại)

JPQL ban đầu nhìn hơi khó chịu, nhưng thực ra:

  • Nó chỉ là SQL phiên bản nói chuyện với Java
  • Hiểu Entity → hiểu JPQL
  • Viết nhiều, debug nhiều là quen

Bài này mình viết để sau này quên còn có cái mà đọc lại. Nếu bạn đọc tới đây mà thấy "à à, hóa ra là thế" thì coi như bài viết này đã hoàn thành nhiệm vụ rồi 👍.


Tip nhỏ: học JPQL đừng học chay, cứ viết API search/filter là hiểu rất nhanh.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí