Hibernate - Hướng dẫn nhanh

JDBC là gì?

JDBC là viết tắt của Java Database Connectivity. Nó cung cấp một bộ API Java để truy cập cơ sở dữ liệu quan hệ từ chương trình Java. Các API Java này cho phép các chương trình Java thực thi các câu lệnh SQL và tương tác với bất kỳ cơ sở dữ liệu tuân thủ SQL nào.

JDBC cung cấp một kiến ​​trúc linh hoạt để viết một ứng dụng độc lập với cơ sở dữ liệu có thể chạy trên các nền tảng khác nhau và tương tác với các DBMS khác nhau mà không cần bất kỳ sửa đổi nào.

Ưu và nhược điểm của JDBC

Ưu điểm của JDBC Nhược điểm của JDBC

Xử lý SQL sạch sẽ và đơn giản

Hiệu suất tốt với dữ liệu lớn

Rất tốt cho các ứng dụng nhỏ

Cú pháp đơn giản nên dễ học

Phức tạp nếu nó được sử dụng trong các dự án lớn

Chi phí lập trình lớn

Không đóng gói

Khó thực hiện khái niệm MVC

Truy vấn dành riêng cho DBMS

Tại sao lại lập bản đồ quan hệ đối tượng (ORM)?

Khi chúng ta làm việc với một hệ thống hướng đối tượng, có sự không phù hợp giữa mô hình đối tượng và cơ sở dữ liệu quan hệ. RDBMS biểu thị dữ liệu ở định dạng bảng trong khi các ngôn ngữ hướng đối tượng, chẳng hạn như Java hoặc C # biểu thị nó dưới dạng một đồ thị liên kết với nhau của các đối tượng.

Hãy xem xét Lớp Java sau với các hàm tạo thích hợp và hàm công khai được liên kết:

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public String getFirstName() {
      return first_name;
   }
   
   public String getLastName() {
      return last_name;
   }
   
   public int getSalary() {
      return salary;
   }
}

Hãy xem xét các đối tượng trên sẽ được lưu trữ và truy xuất vào bảng RDBMS 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,
   PRIMARY KEY (id)
);

Vấn đề đầu tiên, nếu chúng ta cần sửa đổi thiết kế cơ sở dữ liệu của mình sau khi đã phát triển một vài trang hoặc ứng dụng của chúng ta thì sao? Thứ hai, việc tải và lưu trữ các đối tượng trong cơ sở dữ liệu quan hệ khiến chúng ta gặp phải năm vấn đề không khớp sau:

Sr.No. Mô tả & Không khớp
1

Granularity

Đôi khi bạn sẽ có một mô hình đối tượng, có nhiều lớp hơn số lượng bảng tương ứng trong cơ sở dữ liệu.

2

Inheritance

RDBMS không định nghĩa bất cứ điều gì tương tự như Thừa kế, là một mô hình tự nhiên trong ngôn ngữ lập trình hướng đối tượng.

3

Identity

RDBMS xác định chính xác một khái niệm về 'sự giống nhau': khóa chính. Tuy nhiên, Java xác định cả danh tính đối tượng (a == b) và bình đẳng đối tượng (a.equals (b)).

4

Associations

Các ngôn ngữ hướng đối tượng đại diện cho các liên kết bằng cách sử dụng các tham chiếu đối tượng trong khi một RDBMS biểu thị một liên kết như một cột khóa ngoại.

5

Navigation

Cách bạn truy cập các đối tượng trong Java và trong RDBMS về cơ bản là khác nhau.

Các Object-Rphấn chấn Mapping (ORM) là giải pháp để xử lý tất cả các trường hợp không khớp trở kháng trên.

ORM là gì?

ORM là viết tắt của Object-Rphấn chấn Mapping (ORM) là một kỹ thuật lập trình để chuyển đổi dữ liệu giữa cơ sở dữ liệu quan hệ và các ngôn ngữ lập trình hướng đối tượng như Java, C #, v.v.

Hệ thống ORM có những ưu điểm sau so với JDBC thuần túy:

Sr.No. Ưu điểm
1 Hãy mã nghiệp vụ truy cập các đối tượng hơn là các bảng DB.
2 Ẩn chi tiết của các truy vấn SQL khỏi logic OO.
3 Dựa trên JDBC 'under the hood.'
4 Không cần phải xử lý việc triển khai cơ sở dữ liệu.
5 Các thực thể dựa trên các khái niệm kinh doanh hơn là cấu trúc cơ sở dữ liệu.
6 Quản lý giao dịch và tạo khóa tự động.
7 Phát triển ứng dụng nhanh chóng.

Giải pháp ORM bao gồm bốn thực thể sau:

Sr.No. Các giải pháp
1 Một API để thực hiện các hoạt động CRUD cơ bản trên các đối tượng của các lớp liên tục.
2 Một ngôn ngữ hoặc API để chỉ định các truy vấn tham chiếu đến các lớp và thuộc tính của các lớp.
3 Một cơ sở có thể định cấu hình để chỉ định siêu dữ liệu ánh xạ.
4 Một kỹ thuật tương tác với các đối tượng giao dịch để thực hiện kiểm tra bẩn, tìm nạp liên kết lười biếng và các chức năng tối ưu hóa khác.

Các khung công tác Java ORM

Có một số khuôn khổ và tùy chọn ORM liên tục trong Java. Khung liên tục là một dịch vụ ORM lưu trữ và truy xuất các đối tượng vào cơ sở dữ liệu quan hệ.

  • Doanh nghiệp JavaBeans Entity Beans
  • Đối tượng dữ liệu Java
  • Castor
  • TopLink
  • Xuân DAO
  • Hibernate
  • Và nhiều thứ khác nữa

Hibernate là một Object-Rphấn chấn Mgiải pháp ứng dụng (ORM) cho JAVA. Nó là một khuôn khổ bền vững mã nguồn mở được tạo ra bởi Gavin King vào năm 2001. Nó là một dịch vụ Truy vấn và Kiên trì Quan hệ Đối tượng mạnh mẽ, hiệu suất cao cho bất kỳ Ứng dụng Java nào.

Hibernate ánh xạ các lớp Java tới các bảng cơ sở dữ liệu và từ kiểu dữ liệu Java sang kiểu dữ liệu SQL và giúp nhà phát triển giải tỏa 95% các tác vụ lập trình liên quan đến tính bền vững dữ liệu phổ biến.

Hibernate nằm giữa các đối tượng Java truyền thống và máy chủ cơ sở dữ liệu để xử lý tất cả các công việc trong việc duy trì các đối tượng đó dựa trên các cơ chế và mẫu O / R thích hợp.

Ưu điểm của Hibernate

  • Hibernate chăm sóc ánh xạ các lớp Java tới các bảng cơ sở dữ liệu bằng cách sử dụng tệp XML và không cần viết bất kỳ dòng mã nào.

  • Cung cấp các API đơn giản để lưu trữ và truy xuất các đối tượng Java trực tiếp đến và từ cơ sở dữ liệu.

  • Nếu có thay đổi trong cơ sở dữ liệu hoặc trong bất kỳ bảng nào, thì bạn chỉ cần thay đổi các thuộc tính tệp XML.

  • Tóm tắt các kiểu SQL không quen thuộc và cung cấp một cách để làm việc với các Đối tượng Java quen thuộc.

  • Hibernate không yêu cầu máy chủ ứng dụng hoạt động.

  • Thao tác các liên kết phức tạp của các đối tượng trong cơ sở dữ liệu của bạn.

  • Giảm thiểu truy cập cơ sở dữ liệu bằng các chiến lược tìm nạp thông minh.

  • Cung cấp khả năng truy vấn dữ liệu đơn giản.

Cơ sở dữ liệu được hỗ trợ

Hibernate hỗ trợ hầu hết tất cả các RDBMS chính. Sau đây là danh sách một số công cụ cơ sở dữ liệu được hỗ trợ bởi Hibernate:

  • Công cụ cơ sở dữ liệu HSQL
  • DB2/NT
  • MySQL
  • PostgreSQL
  • FrontBase
  • Oracle
  • Cơ sở dữ liệu Microsoft SQL Server
  • Máy chủ SQL Sybase
  • Máy chủ động Informix

Công nghệ được hỗ trợ

Hibernate hỗ trợ nhiều công nghệ khác, bao gồm -

  • XDoclet Spring
  • J2EE
  • Các trình cắm thêm của Eclipse
  • Maven

Hibernate có kiến ​​trúc phân lớp giúp người dùng vận hành mà không cần biết các API cơ bản. Hibernate sử dụng cơ sở dữ liệu và dữ liệu cấu hình để cung cấp các dịch vụ liên tục (và các đối tượng liên tục) cho ứng dụng.

Sau đây là một chế độ xem rất cao của Kiến trúc Ứng dụng Hibernate.

Sau đây là một cái nhìn chi tiết về Kiến trúc ứng dụng Hibernate với các lớp cốt lõi quan trọng của nó.

Hibernate sử dụng các API Java hiện có khác nhau, như JDBC, API Giao dịch Java (JTA), Giao diện Đặt tên và Thư mục Java (JNDI). JDBC cung cấp một mức độ trừu tượng thô sơ của chức năng phổ biến đối với cơ sở dữ liệu quan hệ, cho phép hầu hết mọi cơ sở dữ liệu có trình điều khiển JDBC đều được Hibernate hỗ trợ. JNDI và JTA cho phép Hibernate được tích hợp với các máy chủ ứng dụng J2EE.

Phần sau mô tả ngắn gọn về từng đối tượng lớp liên quan đến Kiến trúc ứng dụng Hibernate.

Đối tượng cấu hình

Đối tượng Cấu hình là đối tượng Hibernate đầu tiên bạn tạo trong bất kỳ ứng dụng Hibernate nào. Nó thường chỉ được tạo một lần trong quá trình khởi tạo ứng dụng. Nó đại diện cho một cấu hình hoặc tệp thuộc tính được yêu cầu bởi Hibernate.

Đối tượng Cấu hình cung cấp hai thành phần khóa:

  • Database Connection- Điều này được xử lý thông qua một hoặc nhiều tệp cấu hình được hỗ trợ bởi Hibernate. Những tệp này làhibernate.propertieshibernate.cfg.xml.

  • Class Mapping Setup - Thành phần này tạo kết nối giữa các lớp Java và các bảng cơ sở dữ liệu.

Đối tượng SessionFactory

Đối tượng cấu hình được sử dụng để tạo một đối tượng SessionFactory mà lần lượt cấu hình Hibernate cho ứng dụng bằng cách sử dụng tệp cấu hình được cung cấp và cho phép khởi tạo đối tượng Session. SessionFactory là một đối tượng an toàn của luồng và được sử dụng bởi tất cả các luồng của một ứng dụng.

SessionFactory là một đối tượng nặng; nó thường được tạo trong quá trình khởi động ứng dụng và được giữ lại để sử dụng sau này. Bạn sẽ cần một đối tượng SessionFactory cho mỗi cơ sở dữ liệu bằng cách sử dụng một tệp cấu hình riêng biệt. Vì vậy, nếu bạn đang sử dụng nhiều cơ sở dữ liệu, thì bạn sẽ phải tạo nhiều đối tượng SessionFactory.

Đối tượng phiên

Phiên được sử dụng để có được kết nối vật lý với cơ sở dữ liệu. Đối tượng Session có trọng lượng nhẹ và được thiết kế để khởi tạo mỗi khi cần tương tác với cơ sở dữ liệu. Các đối tượng cố định được lưu và truy xuất thông qua một đối tượng Session.

Các đối tượng phiên không nên được mở trong một thời gian dài vì chúng thường không an toàn cho luồng và chúng phải được tạo và hủy chúng khi cần thiết.

Đối tượng giao dịch

Giao dịch đại diện cho một đơn vị công việc với cơ sở dữ liệu và hầu hết các RDBMS hỗ trợ chức năng giao dịch. Các giao dịch trong Hibernate được xử lý bởi một người quản lý giao dịch cơ bản và giao dịch (từ JDBC hoặc JTA).

Đây là một đối tượng tùy chọn và các ứng dụng Hibernate có thể chọn không sử dụng giao diện này, thay vào đó quản lý các giao dịch trong mã ứng dụng của riêng chúng.

Đối tượng truy vấn

Các đối tượng truy vấn sử dụng chuỗi SQL hoặc Hibernate Query Language (HQL) để truy xuất dữ liệu từ cơ sở dữ liệu và tạo đối tượng. Một cá thể Truy vấn được sử dụng để ràng buộc các tham số truy vấn, giới hạn số lượng kết quả được trả về bởi truy vấn và cuối cùng để thực thi truy vấn.

Đối tượng tiêu chí

Đối tượng tiêu chí được sử dụng để tạo và thực hiện các truy vấn tiêu chí hướng đối tượng để truy xuất đối tượng.

Chương này giải thích cách cài đặt Hibernate và các gói liên quan khác để chuẩn bị môi trường cho các ứng dụng Hibernate. Chúng tôi sẽ làm việc với cơ sở dữ liệu MySQL để thử nghiệm với các ví dụ Hibernate, vì vậy hãy đảm bảo rằng bạn đã có thiết lập cho cơ sở dữ liệu MySQL. Để biết thêm chi tiết về MySQL, bạn có thể xem Hướng dẫn sử dụng MySQL của chúng tôi .

Tải xuống Hibernate

Giả định rằng bạn đã cài đặt phiên bản Java mới nhất trên hệ thống của mình. Sau đây là các bước đơn giản để tải xuống và cài đặt Hibernate trên hệ thống của bạn -

  • Hãy chọn xem bạn muốn cài đặt Hibernate trên Windows hay Unix, sau đó tiến hành bước tiếp theo để tải xuống tệp .zip cho windows và tệp .tz cho Unix.

  • Tải xuống phiên bản Hibernate mới nhất từ http://www.hibernate.org/downloads.

  • Tại thời điểm viết hướng dẫn này, tôi đã tải xuống hibernate-distribution3.6.4.Final và khi bạn giải nén tệp đã tải xuống, nó sẽ cung cấp cho bạn cấu trúc thư mục như trong hình sau

Cài đặt Hibernate

Khi bạn đã tải xuống và giải nén phiên bản mới nhất của tệp Cài đặt Hibernate, bạn cần thực hiện hai bước đơn giản sau. Đảm bảo rằng bạn đang đặt biến CLASSPATH đúng cách, nếu không bạn sẽ gặp sự cố khi biên dịch ứng dụng của mình.

  • Bây giờ, hãy sao chép tất cả các tệp thư viện từ /lib vào CLASSPATH của bạn và thay đổi biến classpath của bạn để bao gồm tất cả các JAR -

  • Cuối cùng, sao chép hibernate3.jargửi vào CLASSPATH của bạn. Tệp này nằm trong thư mục gốc của cài đặt và là JAR chính mà Hibernate cần để thực hiện công việc của nó.

Điều kiện tiên quyết ở chế độ ngủ đông

Sau đây là danh sách các gói / thư viện được yêu cầu bởi Hibernate và bạn nên cài đặt chúng trước khi bắt đầu với Hibernate. Để cài đặt các gói này, bạn sẽ phải sao chép các tệp thư viện từ/lib vào CLASSPATH của bạn và thay đổi biến CLASSPATH của bạn cho phù hợp.

Sr.No. Gói / Thư viện
1

dom4j

Phân tích cú pháp XML www.dom4j.org/

2

Xalan

Bộ xử lý XSLT https://xml.apache.org/xalan-j/

3

Xerces

Trình phân tích cú pháp Java Xerces https://xml.apache.org/xerces-j/

4

cglib

Các thay đổi phù hợp đối với các lớp Java trong thời gian chạy http://cglib.sourceforge.net/

5

log4j

Ghi nhật ký Faremwork https://logging.apache.org/log4j

6

Commons

Ghi nhật ký, Email, v.v. https://jakarta.apache.org/commons

7

SLF4J

Logging Facade cho Java https://www.slf4j.org

Hibernate yêu cầu bạn phải biết trước - nơi tìm thông tin ánh xạ xác định cách các lớp Java của bạn liên quan đến các bảng cơ sở dữ liệu. Hibernate cũng yêu cầu một bộ cài đặt cấu hình liên quan đến cơ sở dữ liệu và các thông số liên quan khác. Tất cả thông tin như vậy thường được cung cấp dưới dạng tệp thuộc tính Java tiêu chuẩn được gọi làhibernate.propertieshoặc dưới dạng tệp XML có tên hibernate.cfg.xml.

Tôi sẽ xem xét tệp định dạng XML hibernate.cfg.xmlđể chỉ định các thuộc tính Hibernate bắt buộc trong các ví dụ của tôi. Hầu hết các thuộc tính lấy giá trị mặc định của chúng và không bắt buộc phải chỉ định chúng trong tệp thuộc tính trừ khi nó thực sự được yêu cầu. Tệp này được giữ trong thư mục gốc của classpath của ứng dụng của bạn.

Thuộc tính Hibernate

Sau đây là danh sách các thuộc tính quan trọng, bạn sẽ được yêu cầu cấu hình cho cơ sở dữ liệu trong tình huống độc lập -

Sr.No. Thuộc tính & Mô tả
1

hibernate.dialect

Thuộc tính này làm cho Hibernate tạo ra SQL thích hợp cho cơ sở dữ liệu đã chọn.

2

hibernate.connection.driver_class

Lớp trình điều khiển JDBC.

3

hibernate.connection.url

URL JDBC đến phiên bản cơ sở dữ liệu.

4

hibernate.connection.username

Tên người dùng cơ sở dữ liệu.

5

hibernate.connection.password

Mật khẩu cơ sở dữ liệu.

6

hibernate.connection.pool_size

Giới hạn số lượng kết nối đang chờ trong nhóm kết nối cơ sở dữ liệu Hibernate.

7

hibernate.connection.autocommit

Cho phép chế độ tự động gửi được sử dụng cho kết nối JDBC.

Nếu bạn đang sử dụng cơ sở dữ liệu cùng với máy chủ ứng dụng và JNDI, thì bạn sẽ phải định cấu hình các thuộc tính sau:

Sr.No. Thuộc tính & Mô tả
1

hibernate.connection.datasource

Tên JNDI được xác định trong ngữ cảnh máy chủ ứng dụng mà bạn đang sử dụng cho ứng dụng.

2

hibernate.jndi.class

Lớp InitialContext cho JNDI.

3

hibernate.jndi.<JNDIpropertyname>

Chuyển bất kỳ thuộc tính JNDI nào bạn thích vào JNDI InitialContext .

4

hibernate.jndi.url

Cung cấp URL cho JNDI.

5

hibernate.connection.username

Tên người dùng cơ sở dữ liệu.

6

hibernate.connection.password

Mật khẩu cơ sở dữ liệu.

Ngủ đông với Cơ sở dữ liệu MySQL

MySQL là một trong những hệ thống cơ sở dữ liệu mã nguồn mở phổ biến nhất hiện nay. Hãy để chúng tôi tạohibernate.cfg.xmltập tin cấu hình và đặt nó trong thư mục gốc của classpath của ứng dụng của bạn. Bạn sẽ phải đảm bảo rằng bạn cótestdb cơ sở dữ liệu có sẵn trong cơ sở dữ liệu MySQL của bạn và bạn có một người dùng test có sẵn để truy cập cơ sở dữ liệu.

Tệp cấu hình XML phải tuân theo DTD Cấu hình Hibernate 3, có sẵn tại http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd.

<?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>
      
      <!-- Assume test is the database name -->
      
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
      
      <property name = "hibernate.connection.username">
         root
      </property>
      
      <property name = "hibernate.connection.password">
         root123
      </property>
      
      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>
      
   </session-factory>
</hibernate-configuration>

Tệp cấu hình trên bao gồm <mapping> liên quan đến tệp ánh xạ ngủ đông và chúng ta sẽ xem trong chương tiếp theo chính xác tệp ánh xạ ngủ đông là gì và cách thức và lý do chúng ta sử dụng tệp này?

Sau đây là danh sách các cơ sở dữ liệu quan trọng kiểu thuộc tính phương ngữ -

Sr.No. Thuộc tính Cơ sở dữ liệu & Phương thức
1

DB2

org.hibernate.dialect.DB2Dialect

2

HSQLDB

org.hibernate.dialect.HSQLDialect

3

HypersonicSQL

org.hibernate.dialect.HSQLDialect

4

Informix

org.hibernate.dialect.InformixDialect

5

Ingres

org.hibernate.dialect.IngresDialect

6

Interbase

org.hibernate.dialect.InterbaseDialect

7

Microsoft SQL Server 2000

org.hibernate.dialect.SQLServerDialect

số 8

Microsoft SQL Server 2005

org.hibernate.dialect.SQLServer2005Dialect

9

Microsoft SQL Server 2008

org.hibernate.dialect.SQLServer2008Dialect

10

MySQL

org.hibernate.dialect.MySQLDialect

11

Oracle (any version)

org.hibernate.dialect.OracleDialect

12

Oracle 11g

org.hibernate.dialect.Oracle10gDialect

13

Oracle 10g

org.hibernate.dialect.Oracle10gDialect

14

Oracle 9i

org.hibernate.dialect.Oracle9iDialect

15

PostgreSQL

org.hibernate.dialect.PostgreSQLDialect

16

Progress

org.hibernate.dialect.ProgressDialect

17

SAP DB

org.hibernate.dialect.SAPDBDialect

18

Sybase

org.hibernate.dialect.SybaseDialect

19

Sybase Anywhere

org.hibernate.dialect.SybaseAnywhereDialect

Phiên được sử dụng để có được kết nối vật lý với cơ sở dữ liệu. Đối tượng Session có trọng lượng nhẹ và được thiết kế để khởi tạo mỗi khi cần tương tác với cơ sở dữ liệu. Các đối tượng cố định được lưu và truy xuất thông qua một đối tượng Session.

Các đối tượng phiên không nên được mở trong một thời gian dài vì chúng thường không an toàn cho luồng và chúng phải được tạo và hủy chúng khi cần thiết. Chức năng chính của Session là cung cấp, tạo, đọc và xóa các thao tác cho các trường hợp của các lớp thực thể được ánh xạ.

Các phiên bản có thể tồn tại ở một trong ba trạng thái sau tại một thời điểm nhất định -

  • transient - Một phiên bản mới của lớp liên tục, không được liên kết với Session và không có đại diện trong cơ sở dữ liệu và không có giá trị định danh nào được coi là tạm thời bởi Hibernate.

  • persistent- Bạn có thể làm cho một phiên bản tạm thời tồn tại lâu dài bằng cách liên kết nó với một Phiên. Một cá thể liên tục có một đại diện trong cơ sở dữ liệu, một giá trị định danh và được liên kết với một Phiên.

  • detached - Khi chúng ta đóng Phiên ngủ đông, phiên bản liên tục sẽ trở thành một phiên bản tách rời.

Một cá thể Session có thể tuần tự hóa nếu các lớp liên tục của nó có thể tuần tự hóa. Một giao dịch điển hình nên sử dụng thành ngữ sau:

Session session = factory.openSession();
Transaction tx = null;

try {
   tx = session.beginTransaction();
   // do some work
   ...
   tx.commit();
}

catch (Exception e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
} finally {
   session.close();
}

Nếu Phiên ném một ngoại lệ, giao dịch phải được khôi phục và phiên phải bị hủy.

Phương thức giao diện phiên

Có một số phương pháp được cung cấp bởi Sessionnhưng tôi sẽ chỉ liệt kê một vài phương pháp quan trọng mà chúng tôi sẽ sử dụng trong hướng dẫn này. Bạn có thể kiểm tra tài liệu Hibernate để biết danh sách đầy đủ các phương pháp được liên kết vớiSessionSessionFactory.

Sr.No. Phương pháp & Mô tả phiên
1

Transaction beginTransaction()

Bắt đầu một đơn vị công việc và trả về đối tượng Giao dịch được liên kết.

2

void cancelQuery()

Hủy việc thực thi truy vấn hiện tại.

3

void clear()

Hoàn toàn xóa phiên.

4

Connection close()

Kết thúc phiên bằng cách giải phóng kết nối JDBC và dọn dẹp.

5

Criteria createCriteria(Class persistentClass)

Tạo một cá thể Tiêu chí mới, cho lớp thực thể đã cho hoặc lớp cha của một lớp thực thể.

6

Criteria createCriteria(String entityName)

Tạo một phiên bản Tiêu chí mới, cho tên thực thể đã cho.

7

Serializable getIdentifier(Object object)

Trả lại giá trị định danh của thực thể nhất định được liên kết với phiên này.

số 8

Query createFilter(Object collection, String queryString)

Tạo một phiên bản mới của Truy vấn cho chuỗi bộ lọc và bộ sưu tập đã cho.

9

Query createQuery(String queryString)

Tạo một phiên bản mới của Truy vấn cho chuỗi truy vấn HQL đã cho.

10

SQLQuery createSQLQuery(String queryString)

Tạo một phiên bản SQLQuery mới cho chuỗi truy vấn SQL đã cho.

11

void delete(Object object)

Xóa một phiên bản liên tục khỏi kho dữ liệu.

12

void delete(String entityName, Object object)

Xóa một phiên bản liên tục khỏi kho dữ liệu.

13

Session get(String entityName, Serializable id)

Trả về phiên bản liên tục của thực thể đã đặt tên với số nhận dạng đã cho hoặc null nếu không có phiên bản liên tục như vậy.

14

SessionFactory getSessionFactory()

Nhận nhà máy phiên đã tạo phiên này.

15

void refresh(Object object)

Đọc lại trạng thái của phiên bản đã cho từ cơ sở dữ liệu bên dưới.

16

Transaction getTransaction()

Lấy phiên bản Giao dịch được liên kết với phiên này.

17

boolean isConnected()

Kiểm tra xem phiên hiện có được kết nối không.

18

boolean isDirty()

Phiên này có bất kỳ thay đổi nào phải được đồng bộ hóa với cơ sở dữ liệu không?

19

boolean isOpen()

Kiểm tra xem phiên có còn mở không.

20

Serializable save(Object object)

Duy trì phiên bản tạm thời đã cho, trước tiên chỉ định một số nhận dạng đã tạo.

21

void saveOrUpdate(Object object)

Lưu (Đối tượng) hoặc cập nhật (Đối tượng) đối tượng đã cho.

22

void update(Object object)

Cập nhật cá thể liên tục với số nhận dạng của cá thể tách rời đã cho.

23

void update(String entityName, Object object)

Cập nhật cá thể liên tục với số nhận dạng của cá thể tách rời đã cho.

Toàn bộ khái niệm của Hibernate là lấy các giá trị từ các thuộc tính lớp Java và duy trì chúng trong một bảng cơ sở dữ liệu. Tài liệu ánh xạ giúp Hibernate xác định cách kéo các giá trị từ các lớp và ánh xạ chúng với bảng và các trường liên quan.

Các lớp Java mà các đối tượng hoặc thể hiện sẽ được lưu trữ trong các bảng cơ sở dữ liệu được gọi là các lớp liên tục trong Hibernate. Hibernate hoạt động tốt nhất nếu các lớp này tuân theo một số quy tắc đơn giản, còn được gọi làPlain Old Java Object (POJO) mô hình lập trình.

Có các quy tắc chính sau đây của các lớp liên tục, tuy nhiên, không có quy tắc nào trong số này là yêu cầu khó -

  • Tất cả các lớp Java sẽ tồn tại đều cần một hàm tạo mặc định.

  • Tất cả các lớp phải chứa một ID để cho phép dễ dàng xác định các đối tượng của bạn trong Hibernate và cơ sở dữ liệu. Thuộc tính này ánh xạ tới cột khóa chính của bảng cơ sở dữ liệu.

  • Tất cả các thuộc tính sẽ tồn tại phải được khai báo là riêng tư và có getXXXsetXXX các phương thức được định nghĩa theo kiểu JavaBean.

  • Một tính năng trung tâm của Hibernate, proxy, phụ thuộc vào lớp liên tục không phải là lớp cuối cùng hoặc việc triển khai một giao diện khai báo tất cả các phương thức công khai.

  • Tất cả các lớp không mở rộng hoặc triển khai một số lớp và giao diện chuyên biệt theo yêu cầu của khung EJB.

Tên POJO được sử dụng để nhấn mạnh rằng một đối tượng nhất định là một đối tượng Java thông thường, không phải là một đối tượng đặc biệt và đặc biệt không phải là Enterprise JavaBean.

Ví dụ POJO đơn giản

Dựa trên một số quy tắc được đề cập ở trên, chúng ta có thể định nghĩa một lớp POJO như sau:

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;
   }
}

Một ánh xạ đối tượng / quan hệ thường được định nghĩa trong một tài liệu XML. Tệp ánh xạ này hướng dẫn Hibernate - làm thế nào để ánh xạ lớp hoặc các lớp đã xác định với các bảng cơ sở dữ liệu?

Mặc dù nhiều người dùng Hibernate chọn viết XML bằng tay, nhưng có một số công cụ để tạo tài liệu ánh xạ. Bao gồm cácXDoclet, MiddlegenAndroMDA cho người dùng Hibernate nâng cao.

Chúng ta hãy xem xét lớp POJO đã được xác định trước đó của chúng ta mà các đối tượng sẽ tồn tại trong bảng được định nghĩa trong phần tiếp theo.

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;
   }
}

Sẽ có một bảng tương ứng với mỗi đối tượng mà bạn sẵn sàng cung cấp tính bền bỉ. Hãy xem xét các đối tượng trên cần được lưu trữ và truy xuất vào bảng RDBMS 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,
   PRIMARY KEY (id)
);

Dựa trên hai thực thể trên, chúng ta có thể xác định tệp ánh xạ sau, tệp này hướng dẫn Hibernate cách ánh xạ lớp hoặc các lớp đã xác định vào bảng cơ sở dữ liệu.

<?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>

Bạn nên lưu tài liệu ánh xạ trong một tệp có định dạng <classname> .hbm.xml. Chúng tôi đã lưu tài liệu ánh xạ của mình trong tệp Employee.hbm.xml.

Hãy để chúng tôi hiểu một chút chi tiết về các phần tử ánh xạ được sử dụng trong tệp ánh xạ -

  • Tài liệu ánh xạ là một tài liệu XML có <hibernate-mapping> là phần tử gốc, chứa tất cả <class> các yếu tố.

  • Các <class>các phần tử được sử dụng để xác định các ánh xạ cụ thể từ một lớp Java đến các bảng cơ sở dữ liệu. Tên lớp Java được chỉ định bằng cách sử dụngname thuộc tính của phần tử lớp và cơ sở dữ liệu table tên được chỉ định bằng cách sử dụng thuộc tính bảng.

  • Các <meta> phần tử là phần tử tùy chọn và có thể được sử dụng để tạo mô tả lớp.

  • Các <id>phần tử ánh xạ thuộc tính ID duy nhất trong lớp với khóa chính của bảng cơ sở dữ liệu. Cácname thuộc tính của phần tử id đề cập đến thuộc tính trong lớp và columnthuộc tính tham chiếu đến cột trong bảng cơ sở dữ liệu. Cáctype thuộc tính giữ kiểu ánh xạ ngủ đông, kiểu ánh xạ này sẽ chuyển đổi từ kiểu dữ liệu Java sang SQL.

  • Các <generator>phần tử bên trong phần tử id được sử dụng để tự động tạo các giá trị khóa chính. Cácclass thuộc tính của phần tử trình tạo được đặt thành native để cho ngủ đông nhặt một trong hai identity, sequence, hoặc là hilo thuật toán tạo khóa chính tùy thuộc vào khả năng của cơ sở dữ liệu bên dưới.

  • Các <property>phần tử được sử dụng để ánh xạ một thuộc tính lớp Java vào một cột trong bảng cơ sở dữ liệu. Cácname thuộc tính của phần tử đề cập đến thuộc tính trong lớp và columnthuộc tính tham chiếu đến cột trong bảng cơ sở dữ liệu. Cáctype thuộc tính giữ kiểu ánh xạ ngủ đông, kiểu ánh xạ này sẽ chuyển đổi từ kiểu dữ liệu Java sang SQL.

Có sẵn các thuộc tính và phần tử khác, sẽ được sử dụng trong tài liệu ánh xạ và tôi sẽ cố gắng đề cập nhiều nhất có thể trong khi thảo luận về các chủ đề liên quan đến Hibernate khác.

Khi bạn chuẩn bị một tài liệu ánh xạ Hibernate, bạn thấy rằng bạn ánh xạ các kiểu dữ liệu Java thành các kiểu dữ liệu RDBMS. Cáctypesđược khai báo và sử dụng trong các tệp ánh xạ không phải là kiểu dữ liệu Java; chúng cũng không phải là kiểu cơ sở dữ liệu SQL. Những loại này được gọi làHibernate mapping types, có thể dịch từ kiểu dữ liệu Java sang SQL và ngược lại.

Chương này liệt kê tất cả các kiểu ánh xạ cơ bản, ngày và giờ, đối tượng lớn và nhiều kiểu ánh xạ nội sẵn khác.

Các loại nguyên thủy

Loại ánh xạ Kiểu Java Loại SQL ANSI
số nguyên int hoặc java.lang.Integer INTEGER
Dài long hoặc java.lang.Long BIGINT
ngắn short hoặc java.lang.Short SMALLINT
Phao nổi float hoặc java.lang.Float PHAO NỔI
gấp đôi double hoặc java.lang.Double GẤP ĐÔI
big_decimal java.math.BigDecimal SỐ
tính cách java.lang.String CHAR (1)
chuỗi java.lang.String VARCHAR
byte byte hoặc java.lang.Byte TINYINT
boolean boolean hoặc java.lang.Boolean BIT
có không boolean hoặc java.lang.Boolean CHAR (1) ('Y' hoặc 'N')
đúng sai boolean hoặc java.lang.Boolean CHAR (1) ('T' hoặc 'F')

Loại ngày và giờ

Loại ánh xạ Kiểu Java Loại SQL ANSI
ngày java.util.Date hoặc java.sql.Date NGÀY
thời gian java.util.Date hoặc java.sql.Time THỜI GIAN
dấu thời gian java.util.Date hoặc java.sql.Timestamp TIMESTAMP
lịch java.util.Calendar TIMESTAMP
lịch_ngày java.util.Calendar NGÀY

Loại đối tượng nhị phân và lớn

Loại ánh xạ Kiểu Java Loại SQL ANSI
nhị phân byte [] VARBINARY (hoặc BLOB)
bản văn java.lang.String CLOB
có thể nối tiếp bất kỳ lớp Java nào triển khai java.io.Serializable VARBINARY (hoặc BLOB)
làm tắc nghẽn java.sql.Clob CLOB
bãi java.sql.Blob BÃI

Các loại liên quan đến JDK

Loại ánh xạ Kiểu Java Loại SQL ANSI
lớp học java.lang.Class VARCHAR
ngôn ngữ java.util.Locale VARCHAR
Múi giờ java.util.TimeZone VARCHAR
tiền tệ java.util.Currency VARCHAR

Bây giờ chúng ta hãy lấy một ví dụ để hiểu cách chúng ta có thể sử dụng Hibernate để cung cấp tính bền bỉ của Java trong một ứng dụng độc lập. Chúng ta sẽ đi qua các bước khác nhau liên quan đến việc tạo một Ứng dụng Java bằng công nghệ Hibernate.

Tạo lớp học POJO

Bước đầu tiên trong việc tạo một ứng dụng là xây dựng lớp hoặc các lớp Java POJO, tùy thuộc vào ứng dụng sẽ được duy trì trong cơ sở dữ liệu. Hãy để chúng tôi xem xét của chúng tôiEmployee lớp học với getXXXsetXXX các phương thức để biến nó thành lớp tuân thủ JavaBeans.

POJO (Plain Old Java Object) là một đối tượng Java không mở rộng hoặc triển khai một số lớp và giao diện chuyên biệt theo yêu cầu của khuôn khổ EJB. Tất cả các đối tượng Java bình thường là POJO.

Khi bạn thiết kế một lớp để được duy trì bởi Hibernate, điều quan trọng là phải cung cấp mã tuân thủ JavaBeans cũng như một thuộc tính, sẽ hoạt động như chỉ mục như id trong lớp Nhân viên.

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 cơ sở dữ liệu

Bước thứ hai là tạo các bảng trong cơ sở dữ liệu của bạn. Sẽ có một bảng tương ứng với mỗi đối tượng, bạn sẵn sàng cung cấp sự kiên trì. Hãy xem xét các đối tượng trên cần được lưu trữ và truy xuất vào bảng RDBMS 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,
   PRIMARY KEY (id)
);

Tạo tệp cấu hình ánh xạ

Bước này là tạo một tệp ánh xạ hướng dẫn Hibernate cách ánh xạ lớp hoặc các lớp đã xác định với các bảng cơ sở dữ liệu.

<?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>

Bạn nên lưu tài liệu ánh xạ trong một tệp có định dạng <classname> .hbm.xml. Chúng tôi đã lưu tài liệu ánh xạ của mình trong tệp Employee.hbm.xml. Hãy cho chúng tôi xem chi tiết nhỏ về tài liệu lập bản đồ -

  • Tài liệu ánh xạ là tài liệu XML có <hibernate-mapping> làm phần tử gốc chứa tất cả các phần tử <class>.

  • Các <class>các phần tử được sử dụng để xác định các ánh xạ cụ thể từ một lớp Java đến các bảng cơ sở dữ liệu. Tên lớp Java được chỉ định bằng cách sử dụngname thuộc tính của phần tử lớp và tên bảng cơ sở dữ liệu được chỉ định bằng cách sử dụng table thuộc tính.

  • Các <meta> phần tử là phần tử tùy chọn và có thể được sử dụng để tạo mô tả lớp.

  • Các <id>phần tử ánh xạ thuộc tính ID duy nhất trong lớp với khóa chính của bảng cơ sở dữ liệu. Cácname thuộc tính của phần tử id đề cập đến thuộc tính trong lớp và columnthuộc tính tham chiếu đến cột trong bảng cơ sở dữ liệu. Cáctype thuộc tính giữ kiểu ánh xạ ngủ đông, kiểu ánh xạ này sẽ chuyển đổi từ kiểu dữ liệu Java sang SQL.

  • Các <generator>phần tử bên trong phần tử id được sử dụng để tự động tạo các giá trị khóa chính. Cácclass thuộc tính của phần tử trình tạo được đặt thành native để cho ngủ đông nhặt một trong hai identity, sequence hoặc là hilo thuật toán tạo khóa chính tùy thuộc vào khả năng của cơ sở dữ liệu bên dưới.

  • Các <property>phần tử được sử dụng để ánh xạ một thuộc tính lớp Java vào một cột trong bảng cơ sở dữ liệu. Cácname thuộc tính của phần tử đề cập đến thuộc tính trong lớp và columnthuộc tính tham chiếu đến cột trong bảng cơ sở dữ liệu. Cáctype thuộc tính giữ kiểu ánh xạ ngủ đông, kiểu ánh xạ này sẽ chuyển đổi từ kiểu dữ liệu Java sang SQL.

Có sẵn các thuộc tính và phần tử khác, sẽ được sử dụng trong tài liệu ánh xạ và tôi sẽ cố gắng đề cập nhiều nhất có thể trong khi thảo luận về các chủ đề liên quan đến Hibernate khác.

Tạo lớp ứng dụng

Cuối cùng, chúng ta sẽ tạo lớp ứng dụng của mình với phương thức main () để chạy ứng dụng. Chúng tôi sẽ sử dụng ứng dụng này để lưu một số hồ sơ của Nhân viên và sau đó chúng tôi sẽ áp dụng các hoạt động CRUD trên các hồ sơ đó.

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

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 few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 10000);

      /* List down all the employees */
      ME.listEmployees();

      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);

      /* List down new list of the employees */
      ME.listEmployees();
   }
   
   /* 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 */
   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()); 
         }
         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(); 
      }
   }
}

Biên dịch và Thực hiện

Dưới đây là các bước để biên dịch và chạy ứng dụng được đề cập ở trên. Đảm bảo rằng bạn đã đặt PATH và CLASSPATH thích hợp trước khi tiếp tục biên dịch và thực thi.

  • Tạo tệp cấu hình hibernate.cfg.xml như được giải thích trong chương cấu hình.

  • Tạo tệp ánh xạ Employee.hbm.xml như hình trên.

  • Tạo tệp nguồn Employee.java như hình trên và biên dịch nó.

  • Tạo tệp nguồn ManageEaffee.java như được hiển thị ở trên và biên dịch nó.

  • Thực thi lệnh nhị phân ManageEaffee để chạy chương trình.

Bạn sẽ nhận được kết quả sau và các bản ghi sẽ được tạo trong bảng NHÂN VIÊN.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Zara  Last Name: Ali  Salary: 1000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
First Name: Zara  Last Name: Ali  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000

Nếu bạn kiểm tra bảng EMPLOYEE của mình, bảng sẽ có các bản ghi sau:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara       | Ali       |   5000 |
| 31 | John       | Paul      |  10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec

mysql>

Cho đến nay, chúng ta đã thấy ánh xạ O / R rất cơ bản sử dụng hibernate, nhưng có ba chủ đề lập bản đồ quan trọng nhất mà chúng ta phải tìm hiểu chi tiết.

Đây là -

  • Lập bản đồ các bộ sưu tập,
  • Ánh xạ các liên kết giữa các lớp thực thể và
  • Ánh xạ thành phần.

Ánh xạ bộ sưu tập

Nếu một thực thể hoặc lớp có tập hợp các giá trị cho một biến cụ thể, thì chúng ta có thể ánh xạ các giá trị đó bằng cách sử dụng bất kỳ giao diện tập hợp nào có sẵn trong java. Hibernate có thể tồn tại các trường hợp củajava.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List, và bất kỳ array của các thực thể hoặc giá trị liên tục.

Sr.No. Loại bộ sưu tập & Mô tả ánh xạ
1 java.util.Set

Điều này được ánh xạ với một phần tử <set> và được khởi tạo bằng java.util.HashSet

2 java.util.SortedSet

Điều này được ánh xạ với một phần tử <set> và được khởi tạo bằng java.util.TreeSet. Cácsort thuộc tính có thể được đặt thành bộ so sánh hoặc thứ tự tự nhiên.

3 java.util.List

Điều này được ánh xạ với một phần tử <list> và được khởi tạo bằng java.util.ArrayList

4 java.util.Collection

Điều này được ánh xạ với một phần tử <bag> hoặc <ibag> và được khởi tạo bằng java.util.ArrayList

5 java.util.Map

Điều này được ánh xạ với một phần tử <map> và được khởi tạo bằng java.util.HashMap

6 java.util.SortedMap

Điều này được ánh xạ với một phần tử <map> và được khởi tạo bằng java.util.TreeMap. Cácsort thuộc tính có thể được đặt thành bộ so sánh hoặc thứ tự tự nhiên.

Mảng được hỗ trợ bởi Hibernate với <primitive-array> cho các kiểu giá trị nguyên thủy Java và <array> cho mọi thứ khác. Tuy nhiên, chúng hiếm khi được sử dụng, vì vậy tôi sẽ không thảo luận về chúng trong hướng dẫn này.

Nếu bạn muốn ánh xạ giao diện bộ sưu tập do người dùng xác định, giao diện này không được Hibernate hỗ trợ trực tiếp, bạn cần nói với Hibernate về ngữ nghĩa của bộ sưu tập tùy chỉnh của bạn, điều này không dễ dàng và không được khuyến khích sử dụng.

Ánh xạ liên kết

Ánh xạ liên kết giữa các lớp thực thể và mối quan hệ giữa các bảng là linh hồn của ORM. Sau đây là bốn cách thể hiện mối quan hệ cơ bản giữa các đối tượng. Một ánh xạ liên kết có thể là một chiều cũng như hai chiều.

Sr.No. Loại ánh xạ & Mô tả
1 Nhiều-một

Lập bản đồ mối quan hệ nhiều-một bằng Hibernate

2 Một-một

Lập bản đồ mối quan hệ 1-1 bằng Hibernate

3 Một-nhiều

Lập bản đồ mối quan hệ một-nhiều bằng Hibernate

4 Nhiều nhiều

Lập bản đồ mối quan hệ nhiều-nhiều bằng Hibernate

Ánh xạ thành phần

Rất có thể một lớp Thực thể có thể có một tham chiếu đến một lớp khác như một biến thành viên. Nếu lớp được giới thiệu không có vòng đời riêng của nó và hoàn toàn phụ thuộc vào vòng đời của lớp thực thể sở hữu, thì lớp được tham chiếu do đó được gọi làComponent class.

Ánh xạ Bộ sưu tập các thành phần cũng có thể thực hiện theo cách tương tự giống như ánh xạ các Bộ sưu tập thông thường với sự khác biệt nhỏ về cấu hình. Chúng ta sẽ xem chi tiết hai ánh xạ này với các ví dụ.

Sr.No. Loại ánh xạ & Mô tả
1 Ánh xạ thành phần

Ánh xạ cho một lớp có tham chiếu đến một lớp khác như một biến thành viên.

Cho đến nay, bạn đã thấy cách Hibernate sử dụng tệp ánh xạ XML để chuyển đổi dữ liệu từ POJO sang các bảng cơ sở dữ liệu và ngược lại. Chú thích ngủ đông là cách mới nhất để xác định ánh xạ mà không cần sử dụng tệp XML. Bạn có thể sử dụng chú thích bổ sung hoặc thay thế cho siêu dữ liệu ánh xạ XML.

Hibernate Annotations là cách mạnh mẽ để cung cấp siêu dữ liệu cho ánh xạ đối tượng và bảng quan hệ. Tất cả siêu dữ liệu được gộp thành tệp java POJO cùng với mã, điều này giúp người dùng hiểu cấu trúc bảng và POJO đồng thời trong quá trình phát triển.

Nếu bạn định làm cho ứng dụng của mình có thể di động tới các ứng dụng ORM tuân thủ EJB 3 khác, bạn phải sử dụng chú thích để đại diện cho thông tin ánh xạ, nhưng nếu bạn muốn linh hoạt hơn, thì bạn nên sử dụng ánh xạ dựa trên XML.

Thiết lập môi trường cho chú thích ngủ đông

Trước hết, bạn phải đảm bảo rằng bạn đang sử dụng JDK 5.0, nếu không, bạn cần nâng cấp JDK của mình lên JDK 5.0 để tận dụng hỗ trợ gốc cho các chú thích.

Thứ hai, bạn sẽ cần cài đặt gói phân phối chú thích Hibernate 3.x, có sẵn từ sourceforge: ( Tải xuống Hibernate Annotation ) và sao chéphibernate-annotations.jar, lib/hibernate-comons-annotations.jarlib/ejb3-persistence.jar từ bản phân phối Chú thích ngủ đông đến CLASSPATH của bạn.

Ví dụ về lớp được chú thích

Như tôi đã đề cập ở trên trong khi làm việc với Hibernate Annotation, tất cả siêu dữ liệu được gộp chung vào tệp POJO java cùng với mã, điều này giúp người dùng hiểu cấu trúc bảng và POJO đồng thời trong quá trình phát triển.

Hãy xem xét chúng ta sẽ sử dụng bảng EMPLOYEE sau đây để lưu trữ các đối tượng của chúng ta -

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)
);

Sau đây là ánh xạ của lớp Nhân viên với các chú thích để ánh xạ các đối tượng với bảng EMPLOYEE được xác định -

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
   @Id @GeneratedValue
   @Column(name = "id")
   private int id;

   @Column(name = "first_name")
   private String firstName;

   @Column(name = "last_name")
   private String lastName;

   @Column(name = "salary")
   private int salary;  

   public Employee() {}
   
   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;
   }
}

Hibernate phát hiện rằng chú thích @Id nằm trên một trường và giả định rằng nó sẽ truy cập trực tiếp vào các thuộc tính của một đối tượng thông qua các trường trong thời gian chạy. Nếu bạn đặt chú thích @Id trên phương thức getId (), bạn sẽ cho phép truy cập vào các thuộc tính thông qua các phương thức getter và setter theo mặc định. Do đó, tất cả các chú thích khác cũng được đặt trên các trường hoặc phương thức getter, theo chiến lược đã chọn.

Phần sau sẽ giải thích các chú thích được sử dụng trong lớp trên.

Chú thích @Entity

Các chú thích tiêu chuẩn EJB 3 được chứa trong javax.persistence, vì vậy chúng tôi nhập gói này như bước đầu tiên. Thứ hai, chúng tôi sử dụng@Entity chú thích cho lớp Employee, đánh dấu lớp này là một bean thực thể, vì vậy nó phải có một phương thức khởi tạo không đối số có thể nhìn thấy với phạm vi ít nhất được bảo vệ.

@Table Annotation

Chú thích @Table cho phép bạn chỉ định các chi tiết của bảng sẽ được sử dụng để duy trì thực thể trong cơ sở dữ liệu.

Chú thích @Table cung cấp bốn thuộc tính, cho phép bạn ghi đè tên của bảng, danh mục và lược đồ của nó, đồng thời thực thi các ràng buộc duy nhất trên các cột trong bảng. Hiện tại, chúng tôi chỉ sử dụng tên bảng, là NHÂN VIÊN.

Chú thích @Id và @GeneratedValue

Mỗi hạt thực thể sẽ có một khóa chính, mà bạn chú thích trên lớp có @Idchú thích. Khóa chính có thể là một trường đơn lẻ hoặc kết hợp nhiều trường tùy thuộc vào cấu trúc bảng của bạn.

Theo mặc định, chú thích @Id sẽ tự động xác định chiến lược tạo khóa chính thích hợp nhất sẽ được sử dụng nhưng bạn có thể ghi đè điều này bằng cách áp dụng @GeneratedValue chú thích, có hai tham số strategygeneratormà tôi sẽ không thảo luận ở đây, vì vậy chúng ta hãy chỉ sử dụng chiến lược tạo khóa mặc định. Cho phép Hibernate xác định loại trình tạo sẽ sử dụng giúp mã của bạn có thể di động giữa các cơ sở dữ liệu khác nhau.

Chú thích @Column

Chú thích @Column được sử dụng để chỉ định chi tiết của cột mà một trường hoặc thuộc tính sẽ được ánh xạ tới. Bạn có thể sử dụng chú thích cột với các thuộc tính được sử dụng phổ biến nhất sau đây:

  • name thuộc tính cho phép tên của cột được chỉ định rõ ràng.

  • length thuộc tính cho phép kích thước của cột được sử dụng để ánh xạ một giá trị đặc biệt cho một giá trị Chuỗi.

  • nullable thuộc tính cho phép cột được đánh dấu là KHÔNG ĐẦY ĐỦ khi lược đồ được tạo.

  • unique thuộc tính cho phép cột được đánh dấu là chỉ chứa các giá trị duy nhất.

Tạo lớp ứng dụng

Cuối cùng, chúng ta sẽ tạo lớp ứng dụng của mình với phương thức main () để chạy ứng dụng. Chúng tôi sẽ sử dụng ứng dụng này để lưu một số hồ sơ của Nhân viên và sau đó chúng tôi sẽ áp dụng các hoạt động CRUD trên các hồ sơ đó.

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      
      try {
         factory = new AnnotationConfiguration().
                   configure().
                   //addPackage("com.xyz") //add package if used.
                   addAnnotatedClass(Employee.class).
                   buildSessionFactory();
      } catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }
      
      ManageEmployee ME = new ManageEmployee();

      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 10000);

      /* List down all the employees */
      ME.listEmployees();

      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);

      /* List down new list of the employees */
      ME.listEmployees();
   }
   
   /* 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();
         employee.setFirstName(fname);
         employee.setLastName(lname);
         employee.setSalary(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 */
   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()); 
         }
         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(); 
      }
   }
}

Cấu hình cơ sở dữ liệu

Bây giờ hãy để chúng tôi tạo hibernate.cfg.xml tập tin cấu hình để xác định các tham số liên quan đến cơ sở dữ liệu.

<?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>

      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         cohondob
      </property>

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

Biên dịch và Thực hiện

Dưới đây là các bước để biên dịch và chạy ứng dụng được đề cập ở trên. Đảm bảo rằng bạn đã đặt PATH và CLASSPATH thích hợp trước khi tiếp tục biên dịch và thực thi.

  • Xóa tệp ánh xạ Employee.hbm.xml khỏi đường dẫn.

  • Tạo tệp nguồn Employee.java như hình trên và biên dịch nó.

  • Tạo tệp nguồn ManageEaffee.java như được hiển thị ở trên và biên dịch nó.

  • Thực thi lệnh nhị phân ManageEaffee để chạy chương trình.

Bạn sẽ nhận được kết quả sau và các bản ghi sẽ được tạo trong bảng EMPLOYEE.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Zara  Last Name: Ali  Salary: 1000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
First Name: Zara  Last Name: Ali  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000

Nếu bạn kiểm tra bảng EMPLOYEE của mình, bảng sẽ có các bản ghi sau:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara       | Ali       |   5000 |
| 31 | John       | Paul      |  10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec

mysql>

Ngôn ngữ truy vấn Hibernate (HQL) là một ngôn ngữ truy vấn hướng đối tượng, tương tự như SQL, nhưng thay vì hoạt động trên bảng và cột, HQL hoạt động với các đối tượng liên tục và thuộc tính của chúng. Các truy vấn HQL được Hibernate dịch thành các truy vấn SQL thông thường, từ đó thực hiện hành động trên cơ sở dữ liệu.

Mặc dù bạn có thể sử dụng câu lệnh SQL trực tiếp với Hibernate bằng Native SQL, nhưng tôi khuyên bạn nên sử dụng HQL bất cứ khi nào có thể để tránh những phức tạp về tính di động của cơ sở dữ liệu và để tận dụng các chiến lược tạo SQL và bộ nhớ đệm của Hibernate.

Các từ khóa như SELECT, FROM và WHERE, v.v., không phân biệt chữ hoa chữ thường, nhưng các thuộc tính như tên bảng và cột thì phân biệt chữ hoa chữ thường trong HQL.

Mệnh đề FROM

Bạn sẽ sử dụng FROMnếu bạn muốn tải một đối tượng liên tục hoàn chỉnh vào bộ nhớ. Sau đây là cú pháp đơn giản của việc sử dụng mệnh đề FROM:

String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();

Nếu bạn cần đủ điều kiện cho một tên lớp trong HQL, chỉ cần chỉ định gói và tên lớp như sau:

String hql = "FROM com.hibernatebook.criteria.Employee";
Query query = session.createQuery(hql);
List results = query.list();

Mệnh đề AS

Các ASmệnh đề có thể được sử dụng để gán bí danh cho các lớp trong truy vấn HQL của bạn, đặc biệt khi bạn có các truy vấn dài. Ví dụ, ví dụ đơn giản trước đây của chúng tôi sẽ như sau:

String hql = "FROM Employee AS E";
Query query = session.createQuery(hql);
List results = query.list();

Các AS từ khóa là tùy chọn và bạn cũng có thể chỉ định bí danh ngay sau tên lớp, như sau:

String hql = "FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

Mệnh đề SELECT

Các SELECTmệnh đề cung cấp nhiều quyền kiểm soát hơn đối với tập kết quả sau đó mệnh đề from. Nếu bạn muốn lấy một vài thuộc tính của các đối tượng thay vì đối tượng hoàn chỉnh, hãy sử dụng mệnh đề SELECT. Sau đây là cú pháp đơn giản của việc sử dụng mệnh đề SELECT để chỉ lấy trường first_name của đối tượng Employee:

String hql = "SELECT E.firstName FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

Điều đáng chú ý ở đây là Employee.firstName là một thuộc tính của đối tượng Employee chứ không phải là một trường của bảng EMPLOYEE.

Mệnh đề WHERE

Nếu bạn muốn thu hẹp các đối tượng cụ thể được trả về từ bộ nhớ, bạn sử dụng mệnh đề WHERE. Sau đây là cú pháp đơn giản của việc sử dụng mệnh đề WHERE:

String hql = "FROM Employee E WHERE E.id = 10";
Query query = session.createQuery(hql);
List results = query.list();

ĐẶT HÀNG THEO Mệnh đề

Để sắp xếp kết quả truy vấn HQL của bạn, bạn sẽ cần sử dụng ORDER BYmệnh đề. Bạn có thể sắp xếp các kết quả theo bất kỳ thuộc tính nào trên các đối tượng trong tập hợp kết quả tăng dần (ASC) hoặc giảm dần (DESC). Sau đây là cú pháp đơn giản của việc sử dụng mệnh đề ORDER BY:

String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";
Query query = session.createQuery(hql);
List results = query.list();

Nếu bạn muốn sắp xếp theo nhiều thuộc tính, bạn chỉ cần thêm các thuộc tính bổ sung vào cuối mệnh đề theo thứ tự, được phân tách bằng dấu phẩy như sau:

String hql = "FROM Employee E WHERE E.id > 10 " +
             "ORDER BY E.firstName DESC, E.salary DESC ";
Query query = session.createQuery(hql);
List results = query.list();

Mệnh đề GROUP BY

Mệnh đề này cho phép Hibernate lấy thông tin từ cơ sở dữ liệu và nhóm nó dựa trên giá trị của một thuộc tính và thông thường, sử dụng kết quả để bao gồm một giá trị tổng hợp. Sau đây là cú pháp đơn giản của việc sử dụng mệnh đề GROUP BY:

String hql = "SELECT SUM(E.salary), E.firtName FROM Employee E " +
             "GROUP BY E.firstName";
Query query = session.createQuery(hql);
List results = query.list();

Sử dụng các tham số được đặt tên

Hibernate hỗ trợ các tham số được đặt tên trong các truy vấn HQL của nó. Điều này làm cho việc viết các truy vấn HQL chấp nhận đầu vào từ người dùng dễ dàng và bạn không phải phòng thủ trước các cuộc tấn công SQL injection. Sau đây là cú pháp đơn giản của việc sử dụng các tham số được đặt tên:

String hql = "FROM Employee E WHERE E.id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id",10);
List results = query.list();

Điều khoản CẬP NHẬT

Cập nhật hàng loạt là mới đối với HQL với Hibernate 3 và công việc xóa trong Hibernate 3 khác với những gì chúng đã làm trong Hibernate 2. Giao diện Truy vấn hiện chứa một phương thức gọi là executeUpdate () để thực hiện các câu lệnh HQL UPDATE hoặc DELETE.

Các UPDATEmệnh đề có thể được sử dụng để cập nhật một hoặc nhiều thuộc tính của một hoặc nhiều đối tượng. Sau đây là cú pháp đơn giản của việc sử dụng mệnh đề UPDATE:

String hql = "UPDATE Employee set salary = :salary "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("salary", 1000);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

Mệnh đề DELETE

Các DELETEmệnh đề có thể được sử dụng để xóa một hoặc nhiều đối tượng. Sau đây là cú pháp đơn giản của việc sử dụng mệnh đề DELETE:

String hql = "DELETE FROM Employee "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

Mệnh đề INSERT

HQL hỗ trợ INSERT INTOmệnh đề chỉ nơi các bản ghi có thể được chèn từ đối tượng này sang đối tượng khác. Sau đây là cú pháp đơn giản của việc sử dụng mệnh đề INSERT INTO:

String hql = "INSERT INTO Employee(firstName, lastName, salary)"  + 
             "SELECT firstName, lastName, salary FROM old_employee";
Query query = session.createQuery(hql);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

Phương pháp tổng hợp

HQL hỗ trợ một loạt các phương thức tổng hợp, tương tự như SQL. Chúng hoạt động theo cùng một cách trong HQL như trong SQL và sau đây là danh sách các hàm có sẵn:

Sr.No. Chức năng & Mô tả
1

avg(property name)

Giá trị trung bình của một tài sản

2

count(property name or *)

Số lần thuộc tính xuất hiện trong kết quả

3

max(property name)

Giá trị lớn nhất của các giá trị thuộc tính

4

min(property name)

Giá trị tối thiểu của các giá trị thuộc tính

5

sum(property name)

Tổng các giá trị thuộc tính

Các distincttừ khóa chỉ đếm các giá trị duy nhất trong tập hợp hàng. Truy vấn sau sẽ chỉ trả về số lượng duy nhất -

String hql = "SELECT count(distinct E.firstName) FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

Phân trang bằng cách sử dụng Truy vấn

Có hai phương pháp của giao diện Truy vấn để phân trang.

Sr.No. Phương pháp & Mô tả
1

Query setFirstResult(int startPosition)

Phương thức này nhận một số nguyên đại diện cho hàng đầu tiên trong tập kết quả của bạn, bắt đầu bằng hàng 0.

2

Query setMaxResults(int maxResult)

Phương thức này yêu cầu Hibernate truy xuất một số cố định maxResults của các đối tượng.

Sử dụng hai phương pháp trên cùng nhau, chúng ta có thể tạo một thành phần phân trang trong ứng dụng web hoặc Swing của chúng ta. Sau đây là ví dụ mà bạn có thể mở rộng để tìm nạp 10 hàng cùng một lúc -

String hql = "FROM Employee";
Query query = session.createQuery(hql);
query.setFirstResult(1);
query.setMaxResults(10);
List results = query.list();

Hibernate cung cấp các cách thay thế để thao tác các đối tượng và lần lượt dữ liệu có sẵn trong các bảng RDBMS. Một trong những phương pháp là API tiêu chí, cho phép bạn tạo lập trình đối tượng truy vấn tiêu chí, nơi bạn có thể áp dụng các quy tắc lọc và điều kiện logic.

Ngủ đông Session giao diện cung cấp createCriteria() , có thể được sử dụng để tạo Criteria đối tượng trả về các thể hiện của lớp đối tượng kiên trì khi ứng dụng của bạn thực hiện truy vấn tiêu chí.

Sau đây là ví dụ đơn giản nhất về truy vấn tiêu chí là một, sẽ chỉ trả về mọi đối tượng tương ứng với lớp Employee.

Criteria cr = session.createCriteria(Employee.class);
List results = cr.list();

Hạn chế với Tiêu chí

Bạn có thể dùng add() phương pháp có sẵn cho Criteriađối tượng để thêm hạn chế cho truy vấn tiêu chí. Sau đây là ví dụ để thêm hạn chế trả lại hồ sơ với mức lương bằng 2000 -

Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq("salary", 2000));
List results = cr.list();

Sau đây là một số ví dụ khác bao gồm các tình huống khác nhau và có thể được sử dụng theo yêu cầu -

Criteria cr = session.createCriteria(Employee.class);

// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));

// To get records having salary less than 2000
cr.add(Restrictions.lt("salary", 2000));

// To get records having fistName starting with zara
cr.add(Restrictions.like("firstName", "zara%"));

// Case sensitive form of the above restriction.
cr.add(Restrictions.ilike("firstName", "zara%"));

// To get records having salary in between 1000 and 2000
cr.add(Restrictions.between("salary", 1000, 2000));

// To check if the given property is null
cr.add(Restrictions.isNull("salary"));

// To check if the given property is not null
cr.add(Restrictions.isNotNull("salary"));

// To check if the given property is empty
cr.add(Restrictions.isEmpty("salary"));

// To check if the given property is not empty
cr.add(Restrictions.isNotEmpty("salary"));

Bạn có thể tạo điều kiện VÀ hoặc HOẶC bằng cách sử dụng các hạn chế của LogicalExpression như sau:

Criteria cr = session.createCriteria(Employee.class);

Criterion salary = Restrictions.gt("salary", 2000);
Criterion name = Restrictions.ilike("firstNname","zara%");

// To get records matching with OR conditions
LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp );

// To get records matching with AND conditions
LogicalExpression andExp = Restrictions.and(salary, name);
cr.add( andExp );

List results = cr.list();

Mặc dù tất cả các điều kiện trên có thể được sử dụng trực tiếp với HQL như đã giải thích trong hướng dẫn trước.

Phân trang bằng cách sử dụng tiêu chí

Có hai phương pháp của giao diện Tiêu chí để phân trang.

Sr.No. Phương pháp & Mô tả
1

public Criteria setFirstResult(int firstResult)

Phương thức này nhận một số nguyên đại diện cho hàng đầu tiên trong tập kết quả của bạn, bắt đầu bằng hàng 0.

2

public Criteria setMaxResults(int maxResults)

Phương thức này yêu cầu Hibernate truy xuất một số cố định maxResults của các đối tượng.

Sử dụng hai phương pháp trên cùng nhau, chúng ta có thể tạo một thành phần phân trang trong ứng dụng web hoặc Swing của chúng ta. Sau đây là ví dụ mà bạn có thể mở rộng để tìm nạp 10 hàng cùng một lúc -

Criteria cr = session.createCriteria(Employee.class);
cr.setFirstResult(1);
cr.setMaxResults(10);
List results = cr.list();

Sắp xếp kết quả

API tiêu chí cung cấp org.hibernate.criterion.Orderlớp để sắp xếp tập hợp kết quả của bạn theo thứ tự tăng dần hoặc giảm dần, theo một trong các thuộc tính của đối tượng của bạn. Ví dụ này minh họa cách bạn sẽ sử dụng lớp Order để sắp xếp tập hợp kết quả -

Criteria cr = session.createCriteria(Employee.class);

// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));

// To sort records in descening order
cr.addOrder(Order.desc("salary"));

// To sort records in ascending order
cr.addOrder(Order.asc("salary"));

List results = cr.list();

Dự báo & Tổng hợp

API tiêu chí cung cấp org.hibernate.criterion.Projections, có thể được sử dụng để lấy giá trị trung bình, tối đa hoặc tối thiểu của các thuộc tính. Lớp Dự báo tương tự như lớp Restrictions, ở chỗ nó cung cấp một số phương thức gốc tĩnh để lấyProjection các trường hợp.

Sau đây là một số ví dụ về các tình huống khác nhau và có thể được sử dụng theo yêu cầu -

Criteria cr = session.createCriteria(Employee.class);

// To get total row count.
cr.setProjection(Projections.rowCount());

// To get average of a property.
cr.setProjection(Projections.avg("salary"));

// To get distinct count of a property.
cr.setProjection(Projections.countDistinct("firstName"));

// To get maximum of a property.
cr.setProjection(Projections.max("salary"));

// To get minimum of a property.
cr.setProjection(Projections.min("salary"));

// To get sum of a property.
cr.setProjection(Projections.sum("salary"));

Ví dụ về truy vấn tiêu chí

Hãy xem xét lớp POJO sau:

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;
   }
}

Chúng ta hãy tạo bảng EMPLOYEE sau để lưu trữ các đối tượng Nhân viên -

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)
);

Sau đây sẽ là tệp ánh xạ.

<?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>

Cuối cùng, chúng tôi sẽ tạo lớp ứng dụng của mình với phương thức main () để chạy ứng dụng mà chúng tôi sẽ sử dụng Criteria truy vấn -

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Projections;
import org.hibernate.cfg.Configuration;

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 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 all the employees */
      ME.listEmployees();

      /* Print Total employee's count */
      ME.countEmployee();

      /* Print Total salary */
      ME.totalSalary();
   }
   
   /* 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 having salary more than 2000 */
   public void listEmployees( ) {
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Criteria cr = session.createCriteria(Employee.class);
         // Add restriction.
         cr.add(Restrictions.gt("salary", 2000));
         List employees = cr.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(); 
      }
   }
   
   /* Method to print total number of records */
   public void countEmployee(){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Criteria cr = session.createCriteria(Employee.class);

         // To get total row count.
         cr.setProjection(Projections.rowCount());
         List rowCount = cr.list();

         System.out.println("Total Coint: " + rowCount.get(0) );
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
  
   /* Method to print sum of salaries */
   public void totalSalary(){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Criteria cr = session.createCriteria(Employee.class);

         // To get total salary.
         cr.setProjection(Projections.sum("salary"));
         List totalSalary = cr.list();

         System.out.println("Total Salary: " + totalSalary.get(0) );
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
}

Biên dịch và Thực hiện

Dưới đây là các bước để biên dịch và chạy ứng dụng được đề cập ở trên. Đảm bảo rằng bạn đã đặt PATH và CLASSPATH thích hợp trước khi tiếp tục biên dịch và thực thi.

  • Tạo tệp cấu hình hibernate.cfg.xml như được giải thích trong chương cấu hình.

  • Tạo tệp ánh xạ Employee.hbm.xml như hình trên.

  • Tạo tệp nguồn Employee.java như hình trên và biên dịch nó.

  • Tạo tệp nguồn ManageEaffee.java như được hiển thị ở trên và biên dịch nó.

  • Thực thi lệnh nhị phân ManageEaffee để chạy chương trình.

Bạn sẽ nhận được kết quả sau và các bản ghi sẽ được tạo trong bảng NHÂN VIÊN.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 5000
First Name: Mohd  Last Name: Yasee  Salary: 3000
Total Coint: 4
Total Salary: 15000

Nếu bạn kiểm tra bảng EMPLOYEE của mình, bảng sẽ có các bản ghi sau:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 14 | Zara       | Ali       |   2000 |
| 15 | Daisy      | Das       |   5000 |
| 16 | John       | Paul      |   5000 |
| 17 | Mohd       | Yasee     |   3000 |
+----+------------+-----------+--------+
4 rows in set (0.00 sec)
mysql>

Bạn có thể sử dụng SQL gốc để diễn đạt 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 dành riêng cho cơ sở dữ liệu như gợi ý truy vấn hoặc từ khóa CONNECT trong Oracle. Hibernate 3.x cho phép bạn chỉ định SQL viết tay, bao gồm các thủ tục được lưu trữ, cho tất cả các hoạt động tạo, cập nhật, xóa và tải.

Ứng dụng của bạn sẽ tạo một truy vấn SQL gốc từ phiên với createSQLQuery() trên giao diện Session -

public SQLQuery createSQLQuery(String sqlString) throws HibernateException

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

Truy vấn vô hướng

Truy vấn SQL cơ bản nhất là lấy danh sách các đại lượng 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();

Truy vấn thực thể

Các truy vấn trên đều nhằm trả về các giá trị vô hướng, về cơ bản trả về các giá trị "thô" từ tập kết quả. Sau đây là cú pháp để lấy toàn bộ các đối tượng thực thể từ một truy vấn sql gốc 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 SQL được đặt tên

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

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ề SQL gốc

Hãy xem xét lớp POJO sau:

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;
   }
}

Chúng ta hãy tạo bảng EMPLOYEE sau để lưu trữ các đối tượng Nhân viên -

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)
);

Sau đây sẽ là tệp ánh xạ -

<?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>

Cuối cùng, chúng tôi sẽ tạo lớp ứng dụng của mình với phương thức main () để chạy ứng dụng mà chúng tôi sẽ sử dụng Native SQL truy vấn -

import java.util.*; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.SQLQuery;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.cfg.Configuration;

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 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(); 
      }
   }
}

Biên dịch và Thực hiện

Dưới đây là các bước để biên dịch và chạy ứng dụng được đề cập ở trên. Đảm bảo rằng bạn đã đặt PATH và CLASSPATH thích hợp trước khi tiếp tục biên dịch và thực thi.

  • Tạo tệp cấu hình hibernate.cfg.xml như được giải thích trong chương cấu hình.

  • Tạo tệp ánh xạ Employee.hbm.xml như hình trên.

  • Tạo tệp nguồn Employee.java như hình trên và biên dịch nó.

  • Tạo tệp nguồn ManageEaffee.java như được hiển thị ở trên và biên dịch nó.

  • Thực thi lệnh nhị phân ManageEaffee để chạy chương trình.

Bạn sẽ nhận được kết quả sau và các bản ghi sẽ được tạo trong bảng NHÂN VIÊN.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

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

Nếu bạn kiểm tra bảng EMPLOYEE của mình, bảng sẽ có các bản ghi sau:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 26 | Zara       | Ali       |   2000 |
| 27 | Daisy      | Das       |   5000 |
| 28 | John       | Paul      |   5000 |
| 29 | Mohd       | Yasee     |   3000 |
+----+------------+-----------+--------+
4 rows in set (0.00 sec)
mysql>

Bộ nhớ đệm là một cơ chế để nâng cao hiệu suất của hệ thống. Nó là một bộ nhớ đệm nằm giữa ứng dụng và cơ sở dữ liệu. Bộ nhớ đệm lưu trữ các mục dữ liệu được sử dụng gần đây để giảm số lần truy cập cơ sở dữ liệu càng nhiều càng tốt.

Bộ nhớ đệm cũng quan trọng đối với Hibernate. Nó sử dụng lược đồ bộ nhớ đệm đa cấp như được giải thích bên dưới:

Bộ nhớ đệm cấp một

Bộ đệm cấp đầu tiên là bộ đệm Phiên và là bộ đệm bắt buộc mà qua đó tất cả các yêu cầu phải vượt qua. Đối tượng Session giữ một đối tượng dưới quyền riêng của nó trước khi đưa nó vào cơ sở dữ liệu.

Nếu bạn phát hành nhiều bản cập nhật cho một đối tượng, Hibernate cố gắng trì hoãn việc cập nhật càng lâu càng tốt để giảm số lượng các câu lệnh SQL cập nhật được phát hành. Nếu bạn đóng phiên, tất cả các đối tượng đang được lưu trong bộ nhớ cache sẽ bị mất và vẫn tồn tại hoặc được cập nhật trong cơ sở dữ liệu.

Bộ nhớ đệm cấp hai

Bộ đệm cấp hai là bộ đệm tùy chọn và bộ đệm cấp một sẽ luôn được hỏi ý kiến ​​trước khi thực hiện bất kỳ nỗ lực nào để định vị một đối tượng trong bộ đệm cấp hai. Bộ nhớ cache cấp thứ hai có thể được định cấu hình trên cơ sở mỗi lớp và mỗi tập hợp và chịu trách nhiệm chính cho việc lưu trữ các đối tượng trong các phiên.

Bất kỳ bộ đệm nào của bên thứ ba đều có thể được sử dụng với Hibernate. Anorg.hibernate.cache.CacheProvider được cung cấp, giao diện này phải được triển khai để cung cấp cho Hibernate xử lý việc triển khai bộ đệm.

Bộ nhớ đệm cấp truy vấn

Hibernate cũng triển khai một bộ đệm cho các tập kết quả truy vấn tích hợp chặt chẽ với bộ đệm cấp hai.

Đây là một tính năng tùy chọn và yêu cầu hai vùng bộ nhớ cache vật lý bổ sung để lưu giữ các kết quả truy vấn đã lưu trong bộ nhớ cache và dấu thời gian khi bảng được cập nhật lần cuối. Điều này chỉ hữu ích cho các truy vấn được chạy thường xuyên với các tham số giống nhau.

Bộ nhớ đệm cấp độ thứ hai

Hibernate sử dụng bộ nhớ cache cấp một theo mặc định và bạn không phải làm gì để sử dụng bộ nhớ cache cấp một. Hãy đi thẳng đến bộ nhớ cache cấp hai tùy chọn. Không phải tất cả các lớp đều được hưởng lợi từ bộ nhớ đệm, vì vậy điều quan trọng là có thể tắt bộ đệm cấp hai.

Bộ đệm ẩn cấp hai Hibernate được thiết lập theo hai bước. Đầu tiên, bạn phải quyết định sử dụng chiến lược đồng thời nào. Sau đó, bạn định cấu hình các thuộc tính hết hạn bộ nhớ cache và bộ nhớ cache vật lý bằng cách sử dụng nhà cung cấp bộ nhớ cache.

Các chiến lược đồng thời

Chiến lược đồng thời là một trung gian, chịu trách nhiệm lưu trữ các mục dữ liệu trong bộ đệm và truy xuất chúng từ bộ đệm. Nếu bạn định kích hoạt bộ nhớ cache cấp hai, bạn sẽ phải quyết định, đối với mỗi lớp và tập hợp liên tục, chiến lược đồng thời bộ nhớ cache nào sẽ sử dụng.

  • Transactional - Sử dụng chiến lược này cho dữ liệu hầu như chỉ đọc, nơi điều quan trọng là ngăn chặn dữ liệu cũ trong các giao dịch đồng thời, trong trường hợp hiếm hoi là cập nhật.

  • Read-write - Một lần nữa sử dụng chiến lược này cho dữ liệu hầu như chỉ đọc, nơi điều quan trọng là phải ngăn chặn dữ liệu cũ trong các giao dịch đồng thời, trong trường hợp hiếm hoi là cập nhật.

  • Nonstrict-read-write- Chiến lược này không đảm bảo tính nhất quán giữa bộ đệm và cơ sở dữ liệu. Sử dụng chiến lược này nếu dữ liệu hầu như không bao giờ thay đổi và khả năng nhỏ là dữ liệu cũ không đáng lo ngại.

  • Read-only- Một chiến lược đồng thời phù hợp với dữ liệu, không bao giờ thay đổi. Chỉ sử dụng nó cho dữ liệu tham khảo.

Nếu chúng tôi định sử dụng bộ nhớ đệm cấp hai cho Employee lớp, hãy để chúng tôi thêm phần tử ánh xạ cần thiết để yêu cầu Hibernate lưu vào bộ nhớ cache các cá thể của Nhân viên bằng cách sử dụng chiến lược đọc-ghi.

<?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>
      
      <cache usage = "read-write"/>
      
      <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>

Thuộc tính use = "read-write" yêu cầu Hibernate sử dụng chiến lược đồng thời đọc-ghi cho bộ đệm được xác định.

Nhà cung cấp bộ nhớ đệm

Bước tiếp theo của bạn sau khi xem xét các chiến lược đồng thời, bạn sẽ sử dụng các lớp ứng viên bộ đệm của mình để chọn nhà cung cấp bộ đệm. Hibernate buộc bạn phải chọn một nhà cung cấp bộ nhớ đệm duy nhất cho toàn bộ ứng dụng.

Sr.No. Tên & Mô tả bộ nhớ đệm
1

EHCache

Nó có thể cache trong bộ nhớ hoặc trên đĩa và bộ nhớ đệm theo cụm và nó hỗ trợ bộ nhớ đệm kết quả truy vấn Hibernate tùy chọn.

2

OSCache

Hỗ trợ bộ nhớ đệm vào bộ nhớ và đĩa trong một JVM với bộ chính sách hết hạn phong phú và hỗ trợ bộ nhớ cache truy vấn.

3

warmCache

Bộ nhớ cache cụm dựa trên JGroups. Nó sử dụng tính năng vô hiệu hóa theo cụm, nhưng không hỗ trợ bộ đệm ẩn truy vấn Hibernate.

4

JBoss Cache

Bộ đệm phân cụm được sao chép hoàn toàn theo giao dịch cũng dựa trên thư viện đa hướng JGroups. Nó hỗ trợ sao chép hoặc vô hiệu hóa, giao tiếp đồng bộ hoặc không đồng bộ, và khóa lạc quan và bi quan. Bộ đệm ẩn truy vấn Hibernate được hỗ trợ.

Mọi nhà cung cấp bộ nhớ đệm không tương thích với mọi chiến lược đồng thời. Ma trận tương thích sau đây sẽ giúp bạn chọn một sự kết hợp thích hợp.

Chiến lược / Nhà cung cấp Chỉ đọc Không hạn chế đọc-ghi Đọc viết Giao dịch
EHCache X X X  
OSCache X X X  
SwarmCache X X    
JBoss Cache X     X

Bạn sẽ chỉ định một nhà cung cấp bộ nhớ cache trong tệp cấu hình hibernate.cfg.xml. Chúng tôi chọn EHCache làm nhà cung cấp bộ nhớ đệm cấp hai của mình -

<?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>
   
      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         root123
      </property>
   
      <property name = "hibernate.cache.provider_class">
         org.hibernate.cache.EhCacheProvider
      </property>
   
      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>
   
   </session-factory>
</hibernate-configuration>

Bây giờ, bạn cần xác định các thuộc tính của các vùng bộ nhớ cache. EHCache có tệp cấu hình riêng,ehcache.xml, phải nằm trong CLASSPATH của ứng dụng. Cấu hình bộ đệm ẩn trong ehcache.xml cho lớp Nhân viên có thể trông như thế này -

<diskStore path="java.io.tmpdir"/>

<defaultCache
maxElementsInMemory = "1000"
eternal = "false"
timeToIdleSeconds = "120"
timeToLiveSeconds = "120"
overflowToDisk = "true"
/>

<cache name = "Employee"
maxElementsInMemory = "500"
eternal = "true"
timeToIdleSeconds = "0"
timeToLiveSeconds = "0"
overflowToDisk = "false"
/>

Vậy là xong, bây giờ chúng ta đã bật bộ nhớ đệm cấp hai cho lớp Nhân viên và Ngủ đông, bây giờ sẽ truy cập bộ nhớ đệm cấp hai bất cứ khi nào bạn điều hướng đến Nhân viên hoặc khi bạn tải Nhân viên theo mã định danh.

Bạn nên phân tích tất cả các lớp của mình và chọn chiến lược bộ nhớ đệm thích hợp cho từng lớp. Đôi khi, bộ nhớ đệm cấp thứ hai có thể hạ cấp hiệu suất của ứng dụng. Vì vậy, bạn nên đánh giá ứng dụng của mình trước tiên, không bật bộ nhớ đệm và sau đó bật bộ nhớ đệm phù hợp của bạn và kiểm tra hiệu suất. Nếu bộ nhớ đệm không cải thiện hiệu suất hệ thống, thì không có ích gì khi bật bất kỳ loại bộ nhớ đệm nào.

Bộ nhớ cache cấp truy vấn

Để sử dụng bộ đệm truy vấn, trước tiên bạn phải kích hoạt nó bằng cách sử dụng hibernate.cache.use_query_cache="true"thuộc tính trong tệp cấu hình. Bằng cách đặt thuộc tính này thành true, bạn thực hiện Hibernate tạo các bộ đệm cần thiết trong bộ nhớ để giữ các bộ truy vấn và định danh.

Tiếp theo, để sử dụng bộ đệm truy vấn, bạn sử dụng phương thức setCacheable (Boolean) của lớp Query. Ví dụ -

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

Hibernate cũng hỗ trợ hỗ trợ bộ nhớ cache chi tiết rất tốt thông qua khái niệm vùng bộ nhớ cache. Vùng bộ nhớ cache là một phần của bộ nhớ cache được đặt tên.

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

Mã này sử dụng phương pháp để yêu cầu Hibernate lưu trữ và tìm kiếm truy vấn trong vùng nhân viên của bộ đệm.

Hãy xem xét một tình huống khi bạn cần tải lên một số lượng lớn các bản ghi vào cơ sở dữ liệu của mình bằng Hibernate. Sau đây là đoạn mã để đạt được điều này bằng Hibernate -

Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
   Employee employee = new Employee(.....);
   session.save(employee);
}
tx.commit();
session.close();

Theo mặc định, Hibernate sẽ lưu vào bộ nhớ cache tất cả các đối tượng vẫn tồn tại trong bộ nhớ cache cấp phiên và cuối cùng ứng dụng của bạn sẽ rơi vào OutOfMemoryExceptionở đâu đó xung quanh hàng thứ 50.000. Bạn có thể giải quyết vấn đề này, nếu bạn đang sử dụngbatch processing với Hibernate.

Để sử dụng tính năng xử lý hàng loạt, trước tiên hãy đặt hibernate.jdbc.batch_sizedưới dạng kích thước lô thành một số ở 20 hoặc 50 tùy thuộc vào kích thước đối tượng. Điều này sẽ cho vùng chứa ngủ đông biết rằng mọi hàng X sẽ được chèn dưới dạng hàng loạt. Để triển khai điều này trong mã của bạn, chúng tôi sẽ cần thực hiện một số sửa đổi nhỏ như sau:

Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
   Employee employee = new Employee(.....);
   session.save(employee);
   if( i % 50 == 0 ) { // Same as the JDBC batch size
      //flush a batch of inserts and release memory:
      session.flush();
      session.clear();
   }
}
tx.commit();
session.close();

Mã trên sẽ hoạt động tốt đối với hoạt động INSERT, nhưng nếu bạn sẵn sàng thực hiện thao tác CẬP NHẬT, thì bạn có thể đạt được bằng cách sử dụng mã sau:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

ScrollableResults employeeCursor = session.createQuery("FROM EMPLOYEE").scroll();
int count = 0;

while ( employeeCursor.next() ) {
   Employee employee = (Employee) employeeCursor.get(0);
   employee.updateEmployee();
   seession.update(employee); 
   if ( ++count % 50 == 0 ) {
      session.flush();
      session.clear();
   }
}
tx.commit();
session.close();

Ví dụ về xử lý hàng loạt

Hãy để chúng tôi sửa đổi tệp cấu hình để thêm hibernate.jdbc.batch_size tài sản -

<?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>

      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         root123
      </property>
   
      <property name = "hibernate.jdbc.batch_size">
         50
      </property>

      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>

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

Hãy xem xét lớp Nhân viên POJO sau:

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;
   }
}

Hãy để chúng tôi tạo bảng NHÂN VIÊN sau để lưu trữ các đối tượng Nhân viên -

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)
);

Sau đây sẽ là tệp ánh xạ để ánh xạ các đối tượng Nhân viên với bảng EMPLOYEE -

<?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>

Cuối cùng, chúng tôi sẽ tạo lớp ứng dụng của mình với phương thức main () để chạy ứng dụng mà chúng tôi sẽ sử dụng flush()clear() các phương thức có sẵn với đối tượng Session để Hibernate tiếp tục ghi các bản ghi này vào cơ sở dữ liệu thay vì lưu trữ chúng trong bộ nhớ.

import java.util.*; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

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 employee records in batches */
      ME.addEmployees( );
   }
   
   /* Method to create employee records in batches */
   public void addEmployees( ){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer employeeID = null;
      
      try {
         tx = session.beginTransaction();
         for ( int i=0; i<100000; i++ ) {
            String fname = "First Name " + i;
            String lname = "Last Name " + i;
            Integer salary = i;
            Employee employee = new Employee(fname, lname, salary);
            session.save(employee);
         	if( i % 50 == 0 ) {
               session.flush();
               session.clear();
            }
         }
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
      return ;
   }
}

Biên dịch và Thực hiện

Dưới đây là các bước để biên dịch và chạy ứng dụng được đề cập ở trên. Đảm bảo rằng bạn đã đặt PATH và CLASSPATH thích hợp trước khi tiếp tục biên dịch và thực thi.

  • Tạo tệp cấu hình hibernate.cfg.xml như đã giải thích ở trên.

  • Tạo tệp ánh xạ Employee.hbm.xml như hình trên.

  • Tạo tệp nguồn Employee.java như hình trên và biên dịch nó.

  • Tạo tệp nguồn ManageEaffee.java như được hiển thị ở trên và biên dịch nó.

  • Thực thi lệnh nhị phân ManageE Jobee để chạy chương trình, chương trình này sẽ tạo 100000 bản ghi trong bảng EMPLOYEE.

Như bạn đã biết rằng trong Hibernate, một đối tượng sẽ được tạo và tồn tại. Khi đối tượng đã được thay đổi, nó phải được lưu trở lại cơ sở dữ liệu. Quá trình này tiếp tục cho đến lần tiếp theo đối tượng là cần thiết và nó sẽ được tải từ kho lưu trữ liên tục.

Do đó, một đối tượng trải qua các giai đoạn khác nhau trong vòng đời của nó và Interceptor Interfacecung cấp các phương thức, có thể được gọi ở các giai đoạn khác nhau để thực hiện một số tác vụ được yêu cầu. Các phương thức này là các lệnh gọi lại từ phiên đến ứng dụng, cho phép ứng dụng kiểm tra và / hoặc thao tác các thuộc tính của một đối tượng liên tục trước khi nó được lưu, cập nhật, xóa hoặc tải. Sau đây là danh sách tất cả các phương thức có sẵn trong giao diện Interceptor:

Sr.No. Phương pháp & Mô tả
1

findDirty()

Phương thức này được gọi khi flush() phương thức được gọi trên một đối tượng Session.

2

instantiate()

Phương thức này được gọi khi một lớp kiên trì được khởi tạo.

3

isUnsaved()

Phương thức này được gọi khi một đối tượng được chuyển đến saveOrUpdate() phương pháp/

4

onDelete()

Phương thức này được gọi trước khi một đối tượng bị xóa.

5

onFlushDirty()

Phương thức này được gọi khi Hibernate phát hiện một đối tượng bị bẩn (tức là đã được thay đổi) trong quá trình xả tức là cập nhật.

6

onLoad()

Phương thức này được gọi trước khi một đối tượng được khởi tạo.

7

onSave()

Phương thức này được gọi trước khi một đối tượng được lưu.

số 8

postFlush()

Phương thức này được gọi sau khi một lần xả đã xảy ra và một đối tượng đã được cập nhật trong bộ nhớ.

9

preFlush()

Phương thức này được gọi trước một lần xả.

Hibernate Interceptor cho chúng ta toàn quyền kiểm soát cách một đối tượng sẽ trông như thế nào đối với cả ứng dụng và cơ sở dữ liệu.

Làm thế nào để sử dụng Interceptors?

Để xây dựng một thiết bị đánh chặn, bạn có thể triển khai Interceptor lớp học trực tiếp hoặc mở rộng EmptyInterceptorlớp học. Sau đây sẽ là các bước đơn giản để sử dụng chức năng Hibernate Interceptor.

Tạo thiết bị đánh chặn

Chúng tôi sẽ mở rộng EmptyInterceptor trong ví dụ của chúng tôi, nơi phương thức của Interceptor sẽ được gọi tự động khi Employeeđối tượng được tạo và cập nhật. Bạn có thể triển khai nhiều phương pháp hơn theo yêu cầu của bạn.

import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;

public class MyInterceptor extends EmptyInterceptor {
   private int updates;
   private int creates;
   private int loads;

   public void onDelete(Object entity, Serializable id,
      Object[] state, String[] propertyNames, Type[] types) {
       // do nothing
   }

   // This method is called when Employee object gets updated.
   public boolean onFlushDirty(Object entity, Serializable id,
      Object[] currentState, Object[] previousState, String[] propertyNames,
      Type[] types) {
         if ( entity instanceof Employee ) {
            System.out.println("Update Operation");
            return true; 
         }
         return false;
   }
	
   public boolean onLoad(Object entity, Serializable id,
      Object[] state, String[] propertyNames, Type[] types) {
         // do nothing
         return true;
   }
   
   // This method is called when Employee object gets created.
   public boolean onSave(Object entity, Serializable id,
      Object[] state, String[] propertyNames, Type[] types) {
         if ( entity instanceof Employee ) {
            System.out.println("Create Operation");
            return true; 
         }
         return false;
   }
   
   //called before commit into database
   public void preFlush(Iterator iterator) {
      System.out.println("preFlush");
   }
   
   //called after committed into database
   public void postFlush(Iterator iterator) {
      System.out.println("postFlush");
   }
}

Tạo lớp học POJO

Bây giờ, chúng ta hãy sửa đổi một chút ví dụ đầu tiên của chúng ta trong đó chúng ta sử dụng bảng EMPLOYEE và lớp Nhân viên để chơi với -

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 cơ sở dữ liệu

Bước thứ hai là tạo các bảng trong cơ sở dữ liệu của bạn. Sẽ có một bảng tương ứng với mỗi đối tượng, bạn sẵn sàng cung cấp sự kiên trì. Hãy xem xét các đối tượng được giải thích ở trên, cần được lưu trữ và truy xuất vào bảng RDBMS 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,
   PRIMARY KEY (id)
);

Tạo tệp cấu hình ánh xạ

Bước này là tạo một tệp ánh xạ hướng dẫn Hibernate - cách ánh xạ lớp hoặc các lớp đã xác định vào bảng cơ sở dữ liệu.

<?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

Cuối cùng, chúng ta sẽ tạo lớp ứng dụng của mình với phương thức main () để chạy ứng dụng. Ở đây, cần lưu ý rằng trong khi tạo đối tượng phiên, chúng tôi đã sử dụng lớp Interceptor của mình làm đối số.

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

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 few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 10000);

      /* List down all the employees */
      ME.listEmployees();

      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);

      /* List down new list of the employees */
      ME.listEmployees();
   }
   
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession( new MyInterceptor() );
      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 */
   public void listEmployees( ){
      Session session = factory.openSession( new MyInterceptor() );
      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()); 
         }
         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( new MyInterceptor() );
      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( new MyInterceptor() );
      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(); 
      }
   }
}

Biên dịch và Thực hiện

Dưới đây là các bước để biên dịch và chạy ứng dụng được đề cập ở trên. Đảm bảo rằng bạn đã đặt PATH và CLASSPATH thích hợp trước khi tiếp tục biên dịch và thực thi.

  • Tạo tệp cấu hình hibernate.cfg.xml như được giải thích trong chương cấu hình.

  • Tạo tệp ánh xạ Employee.hbm.xml như hình trên.

  • Tạo tệp nguồn Employee.java như hình trên và biên dịch nó.

  • Tạo tệp nguồn MyInterceptor.java như được hiển thị ở trên và biên dịch nó.

  • Tạo tệp nguồn ManageEaffee.java như được hiển thị ở trên và biên dịch nó.

  • Thực thi lệnh nhị phân ManageEaffee để chạy chương trình.

Bạn sẽ nhận được kết quả sau và các bản ghi sẽ được tạo trong bảng NHÂN VIÊN.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

Create Operation
preFlush
postFlush
Create Operation
preFlush
postFlush
Create Operation
preFlush
postFlush
First Name: Zara  Last Name: Ali  Salary: 1000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
preFlush
postFlush
preFlush
Update Operation
postFlush
preFlush
postFlush
First Name: Zara  Last Name: Ali  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
preFlush
postFlush

Nếu bạn kiểm tra bảng EMPLOYEE của mình, bảng sẽ có các bản ghi sau:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara       | Ali       |   5000 |
| 31 | John       | Paul      |  10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec
mysql>