11/08/2018, 18:55

Hibernate many-to-one relationship với MySQL trên Eclipse

Hibernate – many-to-one relationship với MySQL trên Eclipse Hibernate – one-to-one relationship với MySQL trên Eclipse Hibernate – one-to-many relationship với MySQL trên Eclipse Hibernate – many-to-many relationship với MySQL trên Eclipse Mối quan hệ many-to-one ...

  • Hibernate – many-to-one relationship với MySQL trên Eclipse
  • Hibernate – one-to-one relationship với MySQL trên Eclipse
  • Hibernate – one-to-many relationship với MySQL trên Eclipse
  • Hibernate – many-to-many relationship với MySQL trên Eclipse

Mối quan hệ many-to-one trong Hibernate là loại kết hợp phổ biến nhất, nơi một đối tượng có thể được liên kết với nhiều đối tượng. Ví dụ một đối tượng address giống nhau có thể được kết hợp với nhiều đối tượng employee.

Các công nghệ được sử dụng trong ví dụ này:

  • Eclipse MARS 2
  • MySQL 5.0.11
  • JDK 1.8
  • Hibernate 3.6.3

Cấu trúc project

cau truc project many-to-one example

Các bước thực hiện

Trong ví dụ này của chúng ta một đối tượng address giống nhau có thể được kết hợp với nhiều đối tượng employee.

Định nghĩa các table trong MySQL

Tạo bảng EMPLOYEE để lưu trữ các nhân viên sẽ có cấu trúc sau:

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   address    INT NOT NULL,
   PRIMARY KEY (id)
);

Hơn nữa, nhiều nhân viên có thể có cùng địa chỉ, do đó mối liên kết này có thể được biểu diễn bằng cách sử dụng quan hệ many-to-one. Chúng ta sẽ lưu trữ thông tin liên quan đến địa chỉ trong bảng ADDRESS có cấu trúc sau:

create table ADDRESS (
   id INT NOT NULL auto_increment,
   street_name VARCHAR(40) default NULL,
   city_name VARCHAR(40) default NULL,
   state_name VARCHAR(40) default NULL,
   zipcode VARCHAR(10) default NULL,
   PRIMARY KEY (id)
);

Định nghĩa các lớp POJO

Tạo lớp POJO Address tương ứng với bảng ADDRESS

Address.java

import java.util.*;

public class Address{
   private int id;
   private String street;     
   private String city;     
   private String state;    
   private String zipcode; 

   public Address() {}
   public Address(String street, String city, 
                  String state, String zipcode) {
      this.street = street; 
      this.city = city; 
      this.state = state; 
      this.zipcode = zipcode; 
   }
   public int getId() {
      return id;
   }
   public void setId( int id ) {
      this.id = id;
   }
   public String getStreet() {
      return street;
   }
   public void setStreet( String street ) {
      this.street = street;
   }
   public String getCity() {
      return city;
   }
   public void setCity( String city ) {
      this.city = city;
   }
   public String getState() {
      return state;
   }
   public void setState( String state ) {
      this.state = state;
   }
   public String getZipcode() {
      return zipcode;
   }
   public void setZipcode( String zipcode ) {
      this.zipcode = zipcode;
   }
}

Tạo lớp POJO Employee được sử dụng để lưu trữ các đối tượng vào bảng EMPLOYEE và có một biến có kiểu dữ liệu là Address

File: Employee.java

import java.util.*;

public class Employee{
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;
   private Address address;

   public Employee() {}
   public Employee(String fname, String lname, 
                   int salary, Address address ) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
      this.address = address;
   }
   public int getId() {
      return id;
   }
   public void setId( int id ) {
      this.id = id;
   }
   public String getFirstName() {
      return firstName;
   }
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   public String getLastName() {
      return lastName;
   }
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   public int getSalary() {
      return salary;
   }
   public void setSalary( int salary ) {
      this.salary = salary;
   }

   public Address getAddress() {
      return address;
   }
   public void setAddress( Address address ) {
      this.address = address;
   }
}

Định nghĩa các Hibernate Mapping File

Chúng ta phải tạo các file mapping để hướng dẫn Hibernate làm thế nào để ánh xạ các lớp vào các bảng cơ sở dữ liệu. Phần tử <many-to-one> sẽ được sử dụng để xác định quy tắc để thiết lập mối quan hệ many-to-one giữa các EMPLOYEE và ADDRESS.

File: Employee.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="vn.viettuts.hibernate.entity.Employee" table="EMPLOYEE">
        <meta attribute="class-description">
            Lớp này chưa thông tin chi tiết về employee.
        </meta>
        <id name="id" type="int" column="id">
            <generator class="native" />
        </id>
        <property name="firstName" column="first_name" type="string" />
        <property name="lastName" column="last_name" type="string" />
        <property name="salary" column="salary" type="int" />
        <many-to-one name="address" column="address" class="vn.viettuts.hibernate.entity.Address" not-null="true" />
    </class>
</hibernate-mapping>

File: Address.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="vn.viettuts.hibernate.entity.Address" table="ADDRESS">
        <meta attribute="class-description">
            Lớp này chưa thông tin chi tiết về adress.
        </meta>
        <id name="id" type="int" column="id">
            <generator class="native" />
        </id>
        <property name="street" column="street_name" type="string" />
        <property name="city" column="city_name" type="string" />
        <property name="state" column="state_name" type="string" />
        <property name="zipcode" column="zipcode" type="string" />
    </class>
</hibernate-mapping>

Chúng ta hãy xem chi tiết hơn về các phần tử của file mapping trong Hibernate như sau:

  • Tài liệu mapping là một tài liệu XML có <hibernate-mapping> là phần tử gốc chứa tất cả các phần tử <class>.
  • Các phần tử <class> được sử dụng để định nghĩa ánh xạ cụ thể từ các lớp Java sang các bảng cơ sở dữ liệu. Tên lớp Java được chỉ định sử dụng thuộc tính name của phần tử lớp và tên bảng cơ sở dữ liệu được chỉ định sử dụng thuộc tính table.
  • Phần tử <meta> là thành phần tùy chọn và có thể được sử dụng để tạo ra mô tả lớp.
  • Phần tử <id> ánh xạ thuộc tính ID duy nhất trong lớp tới khóa chính của bảng cơ sở dữ liệu. Thuộc tính name của id id đề cập đến thuộc tính trong lớp và thuộc tính column đề cập đến cột trong bảng cơ sở dữ liệu. Thuộc tính type giữ kiểu ánh xạ hibernate, các kiểu mapping này sẽ chuyển đổi từ kiểu dữ liệu Java sang SQL.
  • Phần tử <generator> bên trong phần tử id được sử dụng để tự động tạo giá trị cho khóa chính. Thiết lập thuộc tính class của phần tử generator được đặt là native để cho phép hibernate chọn identity, sequence hoặc hilo để tạo khoá chính tùy thuộc vào khả năng của cơ sở dữ liệu.
  • Phần tử <property> được sử dụng để ánh xạ một thuộc tính của lớp Java vào một cột trong bảng cơ sở dữ liệu. Thuộc tính name của phần tử đề cập đến thuộc tính trong lớp và thuộc tính column đề cập đến cột trong bảng cơ sở dữ liệu. Thuộc tính type giữ kiểu ánh xạ hibernate, các kiểu mapping này sẽ chuyển đổi từ kiểu dữ liệu Java sang SQL.
  • Phần tử <many-to-one> được sử dụng để thiết lập mối quan hệ giữa các thực thể EMPLOYEE VÀ ADDRESS. Thuộc tính name được sử dụng để định nghĩa biến trong lớp cha, trong trường hợp của chúng ta là address. Thuộc column được sử dụng để đặt tên cột trong bảng cha EMPLOYEE.

Tạo file cấu hình Hibernate

File cấu hình Hibernate được sử dụng để định nghĩa các thông tin kết nối database (trong ví dụ này là MySQL) và liên kết đến các file mapping.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">
            org.hibernate.dialect.MySQLDialect
        </property>
        <property name="hibernate.connection.driver_class">
            com.mysql.jdbc.Driver
        </property>

         
        <property name="hibernate.connection.url">
            jdbc:mysql://localhost/testdb
        </property>
        <property name="hibernate.connection.username">
            root
        </property>
        <property name="hibernate.connection.password">
            1234567890
        </property>

         
        <mapping resource="Employee.hbm.xml" />
        <mapping resource="Address.hbm.xml" />

    </session-factory>
</hibernate-configuration>

Tạo lớp ứng ụng

Cuối cùng, chúng ta sẽ tạo lớp chứa phương thức main () để chạy ứng dụng. Chúng ta sẽ sử dụng ứng dụng này để lưu các employee cùng với address của họ. Sau đó áp dụng các thao tác CRUD bản ghi đã tạo.

import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import vn.viettuts.hibernate.entity.Address;
import vn.viettuts.hibernate.entity.Employee;

public class ManageEmployee {
    private static SessionFactory factory;

    public static void main(String[] args) {
        try {
            factory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Failed to create sessionFactory object." + ex);
            throw new ExceptionInInitializerError(ex);
        }
        ManageEmployee ME = new ManageEmployee();

        // Add new address in db
        Address address = ME.addAddress("Nguyen Trai", "Ha Noi", "", "100000");

        // Add new employee in db
        Integer empID1 = ME.addEmployee("Ho", "Van A", 4000, address);

        // Add another new employee in db
        Integer empID2 = ME.addEmployee("Vo", "Van B", 3000, address);

        // Show list all employees
        System.out.println("-----Show list all employees-----");
        ME.listEmployees();

        // Update employee's salary records
        System.out.println("-----Update employee 1-----");
        ME.updateEmployee(empID1, 5000);

        // Delete an employee from the database
        System.out.println("-----Delete employee 2-----");
        ME.deleteEmployee(empID2);

        // List down all the employees
        System.out.println("-----Show list all employees-----");
        ME.listEmployees();

    }

    // Method to add an address record in the database
    public Address addAddress(String street, String city, String state, String zipcode) {
        Session session = factory.openSession();
        Transaction tx = null;
        Integer addressID = null;
        Address address = null;
        try {
            tx = session.beginTransaction();
            address = new Address(street, city, state, zipcode);
            addressID = (Integer) session.save(address);
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
        return address;
    }

    // Method to add an employee record in the database
    public Integer addEmployee(String fname, String lname, int salary, Address address) {
        Session session = factory.openSession();
        Transaction tx = null;
        Integer employeeID = null;
        try {
            tx = session.beginTransaction();
            Employee employee = new Employee(fname, lname, salary, address);
            employeeID = (Integer) session.save(employee);
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
        return employeeID;
    }

    // Method to list all the employees detail
    public void listEmployees() {
        Session session = factory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            List employees = session.createQuery("FROM Employee").list();
            for (Iterator iterator = employees.iterator(); iterator.hasNext();) {
                Employee employee = (Employee) iterator.next();
                System.out.print("First Name: " + employee.getFirstName() + ", ");
                System.out.print("Last Name: " + employee.getLastName() + ", ");
                System.out.println("Salary: " + employee.getSalary());
                Address add = employee.getAddress();
                System.out.println("Address ");
                System.out.println("	Street: " + add.getStreet());
                System.out.println("	City: " + add.getCity());
                System.out.println("	State: " + add.getState());
                System.out.println("	Zipcode: " + add.getZipcode());
            }
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    // Method to update salary for an employee
    public void updateEmployee(Integer EmployeeID, int salary) {
        Session session = factory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Employee employee = (Employee) session.get(Employee.class, EmployeeID);
            employee.setSalary(salary);
            session.update(employee);
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    // Method to delete an employee from the records
    public void deleteEmployee(Integer EmployeeID) {
        Session session = factory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Employee employee = (Employee) session.get(Employee.class, EmployeeID);
            session.delete(employee);
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

Kết quả chạy trên Eclipse

-----Show list all employees-----
First Name: Ho, Last Name: Van A, Salary: 4000
Address 
	Street: Nguyen Trai
	City: Ha Noi
	State: 
	Zipcode: 100000
First Name: Vo, Last Name: Van B, Salary: 3000
Address 
	Street: Nguyen Trai
	City: Ha Noi
	State: 
	Zipcode: 100000
-----Update employee 1-----
-----Delete employee 2-----
-----Show list all employees-----
First Name: Ho, Last Name: Van A, Salary: 5000
Address 
	Street: Nguyen Trai
	City: Ha Noi
	State: 
	Zipcode: 100000

Download Source Code Eclipse

Hibernate kết nối đến các database khác

Để kết nối đến các database khác, các bạn chỉ cần thay đổi thông tin kết nối database trong file hibernate.cfg.xml. Dưới đây là ví dụ kết nối đến SQL Server

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">
            org.hibernate.dialect.SQLServerDialect
        </property>
        <property name="hibernate.connection.driver_class">
            com.microsoft.sqlserver.jdbc.SQLServerDriver
        </property>

         
        <property name="hibernate.connection.url">
            jdbc:sqlserver://[serverName[instanceName][:portNumber]];databaseName=<databaseName>
        </property>
        <property name="hibernate.connection.username">
            sa
        </property>
        <property name="hibernate.connection.password">
            12345678
        </property>

         
        <mapping resource="Employee.hbm.xml" />
        <mapping resource="Address.hbm.xml" />

    </session-factory>
</hibernate-configuration>
Bài tiếp theo: Hibernate one-to-one relationship với MySQL trên Eclipse
Interceptor trong Hibernate
0