[Java Backend Zero to Hello] BÀI 4.7: JPA/HIBERNATE CƠ BẢN
📚 Bài viết thuộc series Java Backend Zero to Hello 📌 Phần: Phase 4: Database & SQL | Bài 42/86
BÀI 4.7: JPA/HIBERNATE CƠ BẢN
Mục tiêu
- Hiểu ORM và JPA
- Tạo Entity class
- Sử dụng EntityManager
- Thực hiện CRUD với JPA
1. ORM LÀ GÌ?
ORM (Object-Relational Mapping) ánh xạ giữa object Java và bảng trong database.
Java Object Database Table
┌──────────────┐ ┌──────────────┐
│ User │ │ users │
│ - id: Long │ ←→ │ - id: BIGINT │
│ - name: Str │ │ - name: VARCHAR│
│ - email: Str │ │ - email: VARCHAR│
└──────────────┘ └──────────────┘
Lợi ích
- Code Java thuần, ít SQL
- Tự động map field ↔ column
- Quản lý transaction
- Cache, lazy loading
JPA vs Hibernate
- JPA: Specification (chuẩn)
- Hibernate: Implementation phổ biến nhất
2. DEPENDENCY
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.3.0.Final</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.1.0</version>
</dependency>
3. ENTITY CLASS
import jakarta.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "full_name", nullable = false, length = 100)
private String name;
@Column(unique = true, nullable = false)
private String email;
@Column(name = "user_age")
private Integer age;
@Column(name = "created_at", updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt = new Date();
// Constructors, getters, setters
}
3.1 Các Annotation chính
| Annotation | Mô tả |
|---|---|
@Entity |
Đánh dấu class là entity |
@Table |
Tên bảng |
@Id |
Khóa chính |
@GeneratedValue |
Tự tăng |
@Column |
Cấu hình cột |
@Transient |
Không lưu vào DB |
@Enumerated |
Enum |
@Temporal |
Kiểu ngày |
3.2 GenerationType
| Type | Mô tả |
|---|---|
IDENTITY |
Auto increment (MySQL) |
SEQUENCE |
Sequence (PostgreSQL, Oracle) |
AUTO |
Tự động chọn |
TABLE |
Dùng bảng riêng |
4. PERSISTENCE.XML
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
version="2.2">
<persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/mydb"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="password"/>
<property name="javax.persistence.jdbc.driver"
value="com.mysql.cj.jdbc.Driver"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
5. ENTITYMANAGER
5.1 Tạo EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPU");
EntityManager em = emf.createEntityManager();
5.2 CRUD Operations
CREATE
EntityTransaction tx = em.getTransaction();
tx.begin();
User user = new User();
user.setName("An");
user.setEmail("an@example.com");
user.setAge(25);
em.persist(user); // Insert
tx.commit();
READ
// Find by ID
User user = em.find(User.class, 1L);
// Find all
List<User> users = em.createQuery("SELECT u FROM User u", User.class)
.getResultList();
// Find with condition
List<User> adults = em.createQuery(
"SELECT u FROM User u WHERE u.age >= 18", User.class)
.getResultList();
UPDATE
tx.begin();
User user = em.find(User.class, 1L);
user.setName("An Nguyễn");
em.merge(user); // Hoặc không cần - managed entity tự update
tx.commit();
DELETE
tx.begin();
User user = em.find(User.class, 1L);
em.remove(user);
tx.commit();
6. JPQL (JAVA PERSISTENCE QUERY LANGUAGE)
Ngôn ngữ truy vấn hướng object, tương tự SQL nhưng dùng tên class/field.
6.1 Cú pháp
// SELECT
TypedQuery<User> query = em.createQuery(
"SELECT u FROM User u WHERE u.email = :email", User.class);
query.setParameter("email", "an@example.com");
User user = query.getSingleResult();
6.2 Các loại query
// WHERE
"SELECT u FROM User u WHERE u.age > :age"
// ORDER BY
"SELECT u FROM User u ORDER BY u.name ASC"
// GROUP BY
"SELECT u.department, COUNT(u) FROM User u GROUP BY u.department"
// JOIN
"SELECT o FROM Order o JOIN o.user u WHERE u.id = :userId"
// UPDATE
"UPDATE User u SET u.age = :age WHERE u.id = :id"
// DELETE
"DELETE FROM User u WHERE u.age < :age"
6.3 Named Query
@Entity
@NamedQuery(name = "User.findByEmail",
query = "SELECT u FROM User u WHERE u.email = :email")
public class User { ... }
// Sử dụng
User user = em.createNamedQuery("User.findByEmail", User.class)
.setParameter("email", "an@example.com")
.getSingleResult();
7. ENTITY STATES
┌─────────┐ persist() ┌─────────┐ commit/flush ┌─────────┐
│ New │ ──────────→ │ Managed │ ─────────────→ │Removed │
└─────────┘ └─────────┘ └─────────┘
│ │
│ │ detach()/clear()
│ ↓
│ ┌─────────┐
└────────────────→ │Detached │
└─────────┘
| State | Mô tả |
|---|---|
| New/Transient | Mới tạo, chưa liên kết với DB |
| Managed | Đang được quản lý bởi EntityManager |
| Removed | Đánh dấu xóa |
| Detached | Không còn được quản lý |
8. CRUD REPOSITORY VỚI JPA
public class UserRepository {
private EntityManager em;
public UserRepository(EntityManager em) {
this.em = em;
}
public void save(User user) {
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit();
}
public Optional<User> findById(Long id) {
return Optional.ofNullable(em.find(User.class, id));
}
public List<User> findAll() {
return em.createQuery("SELECT u FROM User u", User.class)
.getResultList();
}
public void update(User user) {
em.getTransaction().begin();
em.merge(user);
em.getTransaction().commit();
}
public void delete(Long id) {
em.getTransaction().begin();
User user = em.find(User.class, id);
if (user != null) em.remove(user);
em.getTransaction().commit();
}
}
9. BÀI TẬP THỰC HÀNH
Bài 1: Entity User
Tạo entity User với các field: id, name, email, age, createdAt.
Bài 2: Repository
Tạo UserRepository với đầy đủ CRUD.
Bài 3: JPQL Queries
Viết các query:
- Tìm user theo email
- Đếm user theo độ tuổi
- Top 10 user mới nhất
10. TÓM TẮT
| Khái niệm | Mô tả |
|---|---|
| ORM | Ánh xạ Object ↔ Table |
| JPA | Specification |
| Hibernate | Implementation |
| Entity | Class ánh xạ bảng |
| EntityManager | Quản lý entity |
| JPQL | Query language |
| @Entity, @Id, @Column | Annotation chính |
Bài tiếp theo: 4.8 Quan hệ trong JPA
🧭 Điều Hướng Series
⬅️ Bài trước: BÀI 4.6: CONNECTION POOL
📋 Lộ trình tổng quan: Xem Toàn Bộ Series
➡️ Bài tiếp theo: BÀI 4.8: QUAN HỆ TRONG JPA
All rights reserved