Bài 2: Mapping Entity với Hibernate

·

6 min read

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ư EnumCollection.

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@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 UserAddress đượ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.