Bài 2: Mapping Entity với Hibernate
1. Tạo Entity cơ bản
Định nghĩa Entity trong Hibernate Entity là một lớp Java đại diện cho một bảng trong cơ sở dữ liệu. Trong Hibernate, chúng ta sử dụng các annotation để định nghĩa lớp này và các thuộc tính của nó.
Sử dụng các annotation cơ bản
@Entity: Đánh dấu một lớp là một entity.
@Table: Chỉ định tên bảng trong cơ sở dữ liệu mà entity này ánh xạ tới (nếu không chỉ định, mặc định sẽ là tên lớp).
@Id: Chỉ định khóa chính của bảng.
@Column: Chỉ định các cột trong bảng và các thuộc tính của chúng.
Ví dụ cụ thể Giả sử chúng ta có bảng users
trong cơ sở dữ liệu với các cột id
, username
, và password
. Chúng ta có thể định nghĩa entity User
như sau:
import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
// Getters and setters
}
Trong ví dụ này, chúng ta sử dụng annotation @Entity để đánh dấu lớp User
là một entity và @Table để chỉ định rằng lớp này ánh xạ tới bảng users
.
2. Mapping các kiểu dữ liệu
Mapping các kiểu dữ liệu cơ bản Hibernate hỗ trợ mapping các kiểu dữ liệu cơ bản như String
, int
, boolean
, Date
, v.v. Các annotation như @Column giúp chúng ta ánh xạ các thuộc tính của lớp Java tới các cột tương ứng trong bảng cơ sở dữ liệu.
Ví dụ cụ thể
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "age")
private int age;
@Column(name = "hire_date")
@Temporal(TemporalType.DATE)
private Date hireDate;
// Getters and setters
}
Trong ví dụ này, các kiểu dữ liệu String
, int
, và Date
được ánh xạ tới các cột name
, age
, và hire_date
trong bảng employees
. Annotation @Temporal được sử dụng để chỉ định rằng thuộc tính hireDate
nên được ánh xạ dưới dạng DATE
trong cơ sở dữ liệu.
Mapping các kiểu dữ liệu phức tạp Hibernate cũng hỗ trợ mapping các kiểu dữ liệu phức tạp như Enum
và Collection
.
Ví dụ về Enum
public enum EmployeeType {
FULL_TIME,
PART_TIME,
CONTRACTOR
}
@Entity
@Table(name = "employees")
public class Employee {
// Các trường khác
@Enumerated(EnumType.STRING)
@Column(name = "employee_type")
private EmployeeType employeeType;
// Getters and setters
}
Trong ví dụ này, thuộc tính employeeType
được ánh xạ tới cột employee_type
và được lưu dưới dạng STRING
trong cơ sở dữ liệu.
Ví dụ về Collection
@Entity
@Table(name = "departments")
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "department")
private Set<Employee> employees = new HashSet<>();
// Getters and setters
}
Trong ví dụ này, thuộc tính employees
là một tập hợp các đối tượng Employee
và được ánh xạ với quan hệ One-to-Many tới bảng employees
.
3. Quan hệ giữa các bảng
One-to-One Annotation @OneToOne được sử dụng để ánh xạ quan hệ One-to-One giữa hai bảng.
Ví dụ cụ thể
@Entity
@Table(name = "addresses")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "street")
private String street;
@Column(name = "city")
private String city;
@OneToOne(mappedBy = "address")
private User user;
// Getters and setters
}
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@OneToOne
@JoinColumn(name = "address_id")
private Address address;
// Getters and setters
}
Trong ví dụ này, bảng users
có một quan hệ One-to-One với bảng addresses
.
One-to-Many và Many-to-One Annotation @OneToMany và @ManyToOne được sử dụng để ánh xạ quan hệ One-to-Many và Many-to-One giữa hai bảng.
Ví dụ cụ thể
@Entity
@Table(name = "departments")
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "department")
private Set<Employee> employees = new HashSet<>();
// Getters and setters
}
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
// Getters and setters
}
Trong ví dụ này, bảng departments
có một quan hệ One-to-Many với bảng employees
và bảng employees
có một quan hệ Many-to-One với bảng departments
.
Many-to-Many Annotation @ManyToMany được sử dụng để ánh xạ quan hệ Many-to-Many giữa hai bảng.
Ví dụ cụ thể
@Entity
@Table(name = "students")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@ManyToMany
@JoinTable(
name = "student_courses",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private Set<Course> courses = new HashSet<>();
// Getters and setters
}
@Entity
@Table(name = "courses")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "title")
private String title;
@ManyToMany(mappedBy = "courses")
private Set<Student> students = new HashSet<>();
// Getters and setters
}
Trong ví dụ này, bảng students
có một quan hệ Many-to-Many với bảng courses
thông qua bảng trung gian student_courses
.
4. Ví dụ cụ thể về tạo và mapping Entity
Tạo các bảng User và Address với quan hệ One-to-Many
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@OneToMany(mappedBy = "user")
private Set<Address> addresses = new HashSet<>();
// Getters and setters
}
@Entity
@Table(name = "addresses")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "street")
private String street;
@Column(name = "city")
private String city;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
// Getters and setters
}
Trong ví dụ này, bảng users
có một quan hệ One-to-Many với bảng addresses
. Một đối tượng User
có thể có nhiều địa chỉ (addresses), nhưng một đối tượng Address
chỉ thuộc về một User
.
Mapping và truy vấn dữ liệu giữa hai bảng Để lưu một đối tượng User
và các đối tượng Address
liên quan, chúng ta có thể sử dụng Hibernate như sau:
public class Main {
public static void main(String[] args) {
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
User user = new User();
user.setUsername("j
ohndoe");
user.setPassword("password123");
Address address1 = new Address();
address1.setStreet("123 Main St");
address1.setCity("Hometown");
address1.setUser(user);
Address address2 = new Address();
address2.setStreet("456 Elm St");
address2.setCity("Big City");
address2.setUser(user);
user.getAddresses().add(address1);
user.getAddresses().add(address2);
session.save(user);
session.save(address1);
session.save(address2);
transaction.commit();
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
} finally {
session.close();
}
}
}
Đoạn mã trên tạo một đối tượng User
với hai địa chỉ (addresses) và lưu tất cả vào cơ sở dữ liệu. Quan hệ One-to-Many giữa User
và Address
được ánh xạ và quản lý bởi Hibernate.
Qua bài hướng dẫn này, bạn đã nắm được cách tạo và mapping các Entity trong Hibernate, cũng như cách ánh xạ các kiểu dữ liệu và quan hệ giữa các bảng. Những kiến thức này sẽ giúp bạn tiếp tục khám phá các tính năng mạnh mẽ hơn của Hibernate trong các bài hướng dẫn tiếp theo.