0

[Java Backend Zero to Hello] [Phase 4] BÀI 4.7: JPA/HIBERNATE CƠ BẢN

📚 Series: Java Backend Zero to Hello 📂 Phân đoạn: Phase 4: Database & SQL 📖 Nội dung: BÀI 4.7: JPA/HIBERNATE CƠ BẢN 💡 Khóa học lập trình Backend Java & Spring Boot chuẩn doanh nghiệp từ con số 0.


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 bài học

⭐ Hãy bookmark (clip) lại series để tiện theo dõi các bài học tiếp theo nhé!


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í