11/08/2018, 18:49

Native SQL trong Hibernate

Hibernate – Criteria Queries Bạn có thể sử dụng Native SQL trong Hibernate để thực hiện các truy vấn cơ sở dữ liệu nếu bạn muốn sử dụng các tính năng cơ sở dữ liệu cụ thể như hint hoặc từ khoá CONNECT trong Oracle. Hibernate 3.x cho phép bạn chỉ định SQL viết tay, bao gồm các stored ...

Hibernate – Criteria Queries

Bạn có thể sử dụng Native SQL trong Hibernate để thực hiện các truy vấn cơ sở dữ liệu nếu bạn muốn sử dụng các tính năng cơ sở dữ liệu cụ thể như hint hoặc từ khoá CONNECT trong Oracle. Hibernate 3.x cho phép bạn chỉ định SQL viết tay, bao gồm các stored procedures, và tất cả các thao tác create, update, delete và select.

Bạn có thể tạo một truy vấn Native SQL từ session với phương thức createSQLQuery() trên interface Session:

public SQLQuery createSQLQuery(String sqlString) throws HibernateException

Các kiểu truy vấn Native SQL

Sau khi bạn truyền một chuỗi chứa truy vấn SQL đến phương thức createSQLQuery(), bạn phải liên kết kết quả trả về SQL cho thực thể Hibernate hiện có, một join, hoặc một kết quả vô hướng (scalar) sử dụng các phương thức addEntity(), addJoin() và addScalar() tương ứng.

1. Truy vấn vô hướng (Scalar)

Các truy vấn SQL cơ bản nhất là để có được một danh sách các vô hướng (giá trị) từ một hoặc nhiều bảng. Sau đây là cú pháp để sử dụng SQL gốc cho các giá trị vô hướng:

String sql = "SELECT first_name, salary FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();

2. Truy vấn Entity

Các truy vấn ở trên là về trả về các giá trị vô hướng từ resultset. Sau đây là cú pháp để có được các đối tượng Entity từ một truy vấn Native SQL thông qua addEntity().

String sql = "SELECT * FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
List results = query.list();

Truy vấn Entity với Named SQL

Sau đây là cú pháp để nhận các đối tượng thực thể từ truy vấn native sql thông qua addEntity() và sử dụng truy vấn Named SQL.

String sql = "SELECT * FROM EMPLOYEE WHERE id = :employee_id";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
query.setParameter("employee_id", 10);
List results = query.list();

Ví dụ về Native SQL trong Hibernate

Tạo lớp POJO

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

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   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;
   }
}

Tạo bảng EMPLOYEE để lưu trữ các đối tượng Employee

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,
   PRIMARY KEY (id)
);

Tạo file mapping 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="Employee" table="EMPLOYEE">
      <meta attribute="class-description">
         This class contains the employee detail. 
      </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"/>
   </class>
</hibernate-mapping>

Tạo lớp ụng dụng chứa hàm main() để thực hiện các câu truy vấn Native SQL

public class TestNativeSQL {
    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);
        }
        TestNativeSQL ME = new TestNativeSQL();

        // Add few employee records in database
        Integer empID1 = ME.addEmployee("Zara", "Ali", 2000);
        Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
        Integer empID3 = ME.addEmployee("John", "Paul", 5000);
        Integer empID4 = ME.addEmployee("Mohd", "Yasee", 3000);

        // List down employees and their salary using Scalar Query
        ME.listEmployeesScalar();

        // List down complete employees information using Entity Query
        ME.listEmployeesEntity();
    }

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

    // Method to READ all the employees using Scalar Query
    public void listEmployeesScalar() {
        Session session = factory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            String sql = "SELECT first_name, salary FROM EMPLOYEE";
            SQLQuery query = session.createSQLQuery(sql);
            query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
            List data = query.list();

            for (Object object : data) {
                Map row = (Map) object;
                System.out.print("First Name: " + row.get("first_name"));
                System.out.println(", Salary: " + row.get("salary"));
            }
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    // Method to READ all the employees using Entity Query
    public void listEmployeesEntity() {
        Session session = factory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            String sql = "SELECT * FROM EMPLOYEE";
            SQLQuery query = session.createSQLQuery(sql);
            query.addEntity(Employee.class);
            List employees = query.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());
            }
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

Kết quả run trên Eclipse

First Name: Zara, Salary: 2000
First Name: Daisy, Salary: 5000
First Name: John, Salary: 5000
First Name: Mohd, Salary: 3000
First Name: Zara  Last Name: Ali  Salary: 2000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 5000
First Name: Mohd  Last Name: Yasee  Salary: 3000

Download Source Code Eclipse

Bài tiếp theo: Bộ nhớ cache trong Hibernate
Hibernate – Criteria Queries
0