post-image

Tại sao nên dùng Hibernate thay vì JDBC

JDBC & Hibernate

Object Mapping

Với JDBC ta phải map các trường trong bảng với các thuộc tính của Java object một cách “thủ công”. Với Hibernate sẽ hỗ trợ ta map một cách “tự động” thông qua các file cấu hình map XML hay sử dụng các anotation.

JDBC sẽ map Java object với table như sau:

//rs là ResultSet trả về từ câu query get dữ liệu bảng user.
List<User> users = new ArrayList<>();
while(rs.next()) {
     User user = new User();
     user.setId(rs.getInt("id"));
     user.setUsername(rs.getString("username"));
     user.setPassword(rs.getString("password"));
     user.setCreatedDate(rs.getDate("createdDate"));
     users.add(user);
 }Code language: PHP (php)

Cũng với table user đó sử dụng các anotaion để Hibernate có thể map một cách “tự động” như sau.

@Entity
@Table(name = "user")
@Data
public class UserModel {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
 
    @NotEmpty
    @Column(name = "username")
    private String username;
 
    @NotEmpty
    @Column(name = "password")
    private String password;
 
    @NotEmpty
    @Column(name = "createdDate")
    private Date createdDate;
}Code language: CSS (css)

HQL

Hibernate cung cấp các câu lệnh truy vấn tương tự SQL, HQL của Hibernate hỗ trợ đầy đủ các truy vấn đa hình như, HQL “hiểu” các khái niệm như kế thừa (inheritance), đa hình (polymorphysm), và liên kết (association)

Database Independent

Code sử dụng Hibernate là độc lập với hệ quản trị cơ sở dữ liệu, nghĩa là ta không cần thay đổi câu lệnh HQL khi ta chuyển từ hệ quản trị CSDL MySQL sang Oracle, hay các hệ quản trị CSDL khác… Do đó rất dễ để ta thay đổi CSDL quan hệ, đơn giản bằng cách thay đổi thông tin cấu hình hệ quản trị CSDL trong file cấu hình.

//used MySQL
com.mysql.jdbc.Driver
 
// used Oracle
oracle.jdbc.driver.OracleDriverCode language: JavaScript (javascript)

Ví dụ khi ta muốn lấy 10 bản ghi dữ liệu của một table từ 2 CSDL khác nhau.

Với JDBC ta có câu truy vấn như sau.

# MySQL
SELECT column_name FROM table_name ORDER BY column_name ASC LIMIT 10; 
 
# SQL Server
SELECT TOP 10 column_name FROM table_name ORDER BY column_name ASC;Code language: PHP (php)

Với Hibernate câu truy vấn không thay đổi với cả 2 CSDL.

Session.CreateQuery("SELECT E.id FROM Employee E ORDER BY E.id ASC").SetMaxResults(10).List();Code language: CSS (css)

Minimize Code Changes

Khi ta thay đổi (thêm) cột vào bảng, với JDBC ta phải thay đổi những gì:

  • Thêm thuộc tính vào POJO class.
  • Thay đổi method chứa câu truy vấn “select”, “insert”, “update” để bổ sung cột mới.
  • Có thể có rất nhiều method, nhiều class chứa các câu truy vấn như trên.

Với Hibernate ta chỉ cần:

  • Thêm thuộc tính vào Entity class.
  • Cập nhật Hibernate Annotation để map column – property..

Lazy Loading

Với những ứng dụng Java làm việc với cơ sở dữ liệu lớn hàng trăm triệu bản ghi, việc có sử dụng Lazy loading trong truy xuất dữ liệu từ database mang lại lợi ích rất lớn.

Ví dụ những file tài liệu do người dùng upload được lưu ở bảng document. Bảng user có quan hệ một-nhiều với bảng document. Trong trường hợp này class User là class cha, class Document là class con. Bảng document nhanh chóng đầy lên theo thời gian. Mỗi khi ta lấy thông tin user và document tương ứng từ database giả sử dữ liệu document là rất lớn, để ứng dụng không bị chậm vì phải mất nhiều bộ nhớ để chứa toàn bộ document của toàn bộ user, ta áp dụng Lazy loading cho từng user như sau.

// Declaring fetch type for one to many association in your POJO
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private Set documents = new HashSet();
 
// To fetch user with document use initialize() method as follows
User user = (User)session.get(User.class, new Integer(100));
 
// This code will fetch all products for user 100 from database 'NOW'
documents = user.getDocuments();Code language: JavaScript (javascript)

Loại bỏ Try-Catch Blocks

Sử dụng JDBC nếu lỗi xảy khi tao tác với database thì sẽ có exception SQLexception ném ra. Bởi vậy ta phải sử dụng try-catch block để xử lý ngoại lệ.

Hibernate xử lý việc này giúp bạn bằng cách nó override toàn bộ JDBC exception thành Unchecked Exception và ta không cần viết try-catch trong code của mình nữa.

Quản lý commit/ rollback Transaction

Transaction là nhóm các hoạt động (với database) của một tác vụ. Nếu một hoạt động không thành công thì toàn bộ tác vụ không thành công.

Với JDBC lập trình viên phải chủ động thực hiện commit khi toàn bộ hoạt động của tác vụ thành công, hay phải rollback khi có một hoạt động không thành công để kết thúc tác vụ.

Với Hibernate thì ta không cần quan tâm đến commit hay rollback, Hibernate đã quản lý nó giúp ta rồi.

Hibernate Caching

Hibernate cung cấp một cơ chế bộ nhớ đệm, giúp giảm số lần truy cập vào database của ứng dụng càng nhiều càng tốt. Điều này sẽ có tác dụng tăng performance đáng kể cho ứng dụng của bạn.

Hibernate lưu trữ các đối tượng trong session khi transation được kích hoạt. Khi một query được thực hiện liên tục, giá trị được lưu trữ trong session được sử dụng lại. Khi một transaction mới bắt đầu, dữ liệu được lấy lại từ database và được lưu trữ session. Hibernate cung cấp hai cấp độ Cache: bộ nhớ cache cấp một (first level cache) và bộ nhớ cache cấp hai (second level cache).

Chúng ta sẽ tìm hiểu chi tiết hơn về Cache trong Hibernate ở các bài viết kế tiếp.

Associations

Thật dễ dàng để tạo một liên kết giữa các bảng bằng Hibernate như quan hệ một-một, một-nhiều, nhiều-một và nhiều-nhiều trong Hibernate bằng cách sử dụng các Annotation để ánh xạ đối tượng của bảng.

Chẳng hạn, chúng ta có bảng Person quan hệ 1-1 với bảng PersonDetail. Với JDBC, chúng ta phải viết SQL để thực hiện INNER JOIN giữa 2 bảng. Với Hibernate, chỉ đơn giản thêm Annotation @OneToOne như sau:

JPA Annotation Support

Hibernate implement đặc tả JPA, do đó chúng ta có thể sử dụng các Annotation của JPA như @Entity, @Table, @Column, … Nhờ đặc điểm này, chúng ta có thể dễ dàng chuyển đổi giữa các ORM Framework mà không cần phải sử đổi code.

Connection Pooling

Như chúng ta đã biết, Connection Pooling giúp tăng performance nhờ vào sử dụng lại các kết nối khi có yêu cầu thay vì việc tạo kết nối mới.

Một số Connection Pooling được hỗ trợ bởi Hibernate: C3p0, Apache DBCP.

Chúng ta có thể dễ dàng tích hợp với các thư viện Connection Pooling có sẵn chỉ với vài dòng cấu hình như sau:

<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
Code language: HTML, XML (xml)

Nguồn:

https://gpcoder.com/6300-gioi-thieu-ve-hibernate/#Tai_sao_nen_dung_Hibernate_thay_vi_JDBC

Tài liệu tham khảo:

Leave a Reply

Your email address will not be published. Required fields are marked *