CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Trang chủHướng dẫnTìm hiểu JPA Annotations và Hibernate Annotations với ví dụ thực tế
Java

Tìm hiểu JPA Annotations và Hibernate Annotations với ví dụ thực tế

CyStack blog 5 phút để đọc
CyStack blog30/08/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 5 minutes

Các annotation trong JPA được sử dụng để ánh xạ các đối tượng Java sang các bảng, cột trong cơ sở dữ liệu, v.v. Hibernate là một trong những ứng dụng phổ biến nhất của đặc tả JPA và cung cấp thêm một số annotations. Hôm nay chúng ta sẽ tìm hiểu về JPA Annotations và Hibernate Annotations  kèm theo một vài đoạn code minh họa ngắn.

JPA Annotations và Hibernate Annotations

JPA Annotations và Hibernate Annotations

Java annotation là một dạng siêu dữ liệu được thêm vào mã nguồn Java. Java annotations có thể được đọc từ các tệp nguồn. Nó cũng có thể được nhúng vào và đọc từ các tệp class do trình biên dịch tạo ra. Điều này cho phép các annotations được giữ lại bởi JVM trong suốt quá trình chạy. JPA annotations không phải là một phần của JDK tiêu chuẩn, vì vậy bạn sẽ nhận được nó khi bạn thêm bất kỳ framework ứng dụng nào. Ví dụ: sự phụ thuộc maven của hibernate dưới đây cũng sẽ cung cấp cho bạn JPA annotations.

<dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.1-api</artifactId>
    <version>1.0.0.Final</version>
</dependency>

JPA Annotations để ánh xạ java object tới database table

Hãy cùng xem một vài JPA annotations quan trọng. Lưu ý rằng các annotations này có trong gói javax.persistence.

  1. javax.persistence.Entity: Chỉ định rằng một class là một entity. Annotation này có thể được áp dụng trên Class, Interface hoặc Enums.
import javax.persistence.Entity;

@Entity
public class Employee implements Serializable {
}
  1. @Table: Chỉ định table trong database mà entity này được ánh xạ tới. Trong ví dụ bên dưới, dữ liệu sẽ được lưu trữ trong table “employee”. Thuộc tính name của annotation @Table được dùng để chỉ định tên table.
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "employee")
public class Employee implements Serializable {
}
  1. @Column: Chỉ định ánh xạ column bằng cách sử dụng annotation @Column. Thuộc tính name của annotation này được dùng để chỉ định tên column của table.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "employee")
public class Employee implements Serializable {

  @Column(name = "employee_name")
  private String employeeName;
}
  1. @Id: Annotation này chỉ định khóa chính của entity.
import javax.persistence.*;

@Entity
@Table(name = "employee")
public class Employee implements Serializable {
  @Id
  @Column(name = "id")
  private int id;
}
  1. @GeneratedValue: Annotation này chỉ định các chiến lược tạo giá trị cho các khóa chính.
import javax.persistence.*;

@Entity
@Table(name = "employee")
public class Employee implements Serializable {
  
  @Id
  @Column(name = "id")
  @GeneratedValue(strategy=SEQUENCE, generator="ID_SEQ")
  private int id;
}

  1. @Version: Chúng ta có thể kiểm soát phiên bản hoặc concurrency bằng cách sử dụng annotation này.
import javax.persistence.*;

@Entity
@Table(name = "employee")
public class Employee implements Serializable {
  @Version
  @Column(name = "version")
  private Date version;
}

  1. @OrderBy: Sắp xếp dữ liệu của bạn bằng cách sử dụng annotation @OrderBy. Trong ví dụ bên dưới, nó sẽ sắp xếp tất cả employees_address theo id của chúng theo thứ tự tăng dần.
@OrderBy("id asc")
private Set employee_address;
  1. @Transient: Mọi thuộc tính non staticnon-transient của một entity đều được coi là persistent (bền vững), trừ khi bạn chú thích nó là @Transient.
@Transient
Private int employeePhone;

  1. @Lob: Các Large objects được khai báo với @Lob.
@Lob
public String getEmployeeAddress() {
    return employeeAddress;
}

Tập hợp annotations trên là những JPA annotations được sử dụng phổ biến nhất để xác định một entity.

Hibernate Annotations để ánh xạ giữa các Tables

Chúng ta có một tập hợp các annotations khác được dùng để chỉ định ánh xạ liên kết giữa các tables và entities khác nhau. Chúng ta sẽ lấy một ví dụ xem xét tình huống được đề cập dưới đây.

  • Các tables ’employee’ và ’employeeDetail’ có mối liên kết một-một (one-to-one association) và chúng dùng chung khóa chính.
  • Các tables ‘communication’ và ‘communicationDetail’ được liên kết bằng một foreign key (khóa ngoại). Nó cũng là một liên kết một-một.
  • Các tables ‘communication’ và ’employee’ được liên kết bằng cách sử dụng một foreign key trong một liên kết nhiều-một với communication là chủ sở hữu.
  • Các tables ’employee’ và ’employeeStatus’ được liên kết thông qua một foreign key trong liên kết nhiều-một với employee là chủ sở hữu.

@OneToOne: Các entities EmployeeEmployeeDetail dùng chung khóa chính và chúng ta có thể liên kết chúng bằng cách sử dụng @OneToOne@PrimaryKeyJoinColumn. Trong trường hợp này, thuộc tính id của EmployeeDetail không được chú thích với @GeneratedValue. Giá trị id của Employee sẽ được sử dụng cho id của EmployeeDetail.

@Entity
@Table(name = "employee")
public class Employee implements Serializable {

  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;

  @OneToOne(cascade = CascadeType.MERGE)
  @PrimaryKeyJoinColumn
  private EmployeeDetail employeeDetail;
}

@Entity
@Table(name = "employeeDetail")
public class EmployeeDetail implements Serializable {

  @Id
  @Column(name = "id")
  private int id;
}

Lưu ý:

  • @PrimaryKeyJoinColumn nên được sử dụng cho các entities liên kết chia sẻ cùng một khóa chính.
  • @JoinColumn & @OneToOne nên được mappedBy attribute khi khóa ngoại được giữ bởi một trong các entities.

Communication và CommunicationDetail được liên kết thông qua một khóa ngoại, vì vậy annotations @OneToOne và @JoinColumn có thể được sử dụng. Trong đoạn mã được đề cập dưới đây, id được tạo cho Communication sẽ được ánh xạ tới column ‘communication_id’ của table CommunicationDetail. @MapsId được sử dụng cho mục đích này.

@Entity
@Table(name = "communicationDetail")
public class CommunicationDetail implements Serializable {

  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;

  @OneToOne
  @MapsId
  @JoinColumn(name = "communicationId")
  private Communication communication;
}

@Entity
@Table(name = "communication")
public class Communication implements Serializable {

  @Id
  @Column(name = "ID")
  @GeneratedValue
  private Integer id;

  @OneToOne(mappedBy = "communication", cascade = CascadeType.ALL)
  private CommunicationDetail communicationDetail;
}

@ManyToOne: Nhiều nhân viên có thể dùng chung một trạng thái. Vì vậy, mối quan hệ employee với employeeStatus là mối quan hệ nhiều-một. Annotation @ManyToOne có thể được sử dụng cho mục đích này.

@Entity
@Table(name = "employee")
public class Employee implements Serializable {
 
  @ManyToOne
  @JoinColumn(name = "statusId")
  private EmployeeStatus status;
}

@OneToMany: Employee tới Communication sẽ là một mối quan hệ một-nhiều. Chủ sở hữu của mối quan hệ này là Communication, vì vậy, chúng ta sẽ sử dụng thuộc tính mappedBy trong Employee để biến nó thành một mối quan hệ hai chiều.

@Entity
@Table(name = "employee")
public class Employee implements Serializable {

  @OneToMany(mappedBy = "employee", fetch = FetchType.EAGER)
  @OrderBy("firstName asc")
  private Set communications;
}

@PrimaryKeyJoinColumn: Annotation này được dùng để liên kết các entities dùng chung khóa chính.

@Entity
@Table(name = "employee")
public class Employee implements Serializable {

  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;

  @OneToOne(cascade = CascadeType.MERGE)
  @PrimaryKeyJoinColumn
  private EmployeeDetail employeeDetail;
}

@JoinColumn: Annotation @JoinColumn được sử dụng cho các liên kết một-một hoặc nhiều-một khi khóa ngoại được giữ bởi một trong các entities.

@ManyToOne
@JoinColumn(name = "statusId")
private EmployeeStatus status;

@JoinTable: @JoinTablemappedBy nên được sử dụng cho các entities được liên kết thông qua một association table (bảng liên kết).

@OneToOne
@MapsId
@JoinColumn(name = "communicationId")
private Communication communication;

Hibernate Annotations cho ánh xạ Inheritance

Bây giờ chúng ta hãy cố gắng hiểu annotation ánh xạ inheritance (kế thừa) trong Hibernate. Hibernate hỗ trợ ba chiến lược ánh xạ inheritance cơ bản:

  • table per class hierarchy
  • table per subclass
  • table per concrete class

Chúng ta sẽ xem xét ví dụ cho từng loại.

  1. Table per class hierarchy – chiến lược một bảng cho mỗi phân cấp class (single table per Class Hierarchy Strategy).
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="cartype", discriminatorType=DiscriminatorType.STRING )

@DiscriminatorValue("Car")
public class Car {  }

@Entity
@DiscriminatorValue("BMW")
public class BMW extends Car {  }
  1. Table per class/subclass – joined subclass Strategy.
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Ship implements Serializable {}

@Entity
@PrimaryKeyJoinColumn
public class Titanic extends Ship {}
  1. Table per concrete class.
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Aeroplane implements Serializable {}
  1. @DiscriminatorColumn: Như tên gọi, column này là discriminator và annotation này chỉ định discriminator column cho các chiến lược ánh xạ inheritance SINGLE_TABLE và JOINED.
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="cartype", discriminatorType=DiscriminatorType.STRING )

Đó là tất cả về JPA và Hibernate annotations. Tham khảo: JSR 338, Hibernate API Docs.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất