Thứ Hai, 29 tháng 7, 2013

How to use in-memory database h2 with hibernate

H2 là một database engine rất hữu ích khi bạn phát triển sản phẩm vì tính nhanh gọn trong cài đặt và triển khai của nó. Nhưng nó không phải là một cơ sở dữ liệu thích hợp trong môi trường production. Lợi ích đáng giá của H2 là chế độ in-memory database. Điều này có nghĩa là bạn tạo một cơ sở dữ liệu nằm gọn trên memory RAM của bạn. Trong trường hợp này, cơ sở dữ liệu về cấu trúc cũng như nội dung sẽ không được persistent.


Mặc định, in-memory database h2 sẽ tự động close khi last connection đến database được release. Khi database close thì cấu trúc và nội dung của nó sẽ bị xóa khỏi bộ nhớ. Trong bài viết này mình sẽ hướng dẫn bạn phương hướng (không chi tiết) về cách hình thành data source trong IDE sử dụng in-memory database (private) và in-memory database (named). Cuối cùng sẽ là cách sử dụng hai  kiểu database này với hibernate.



Phân biệt: in-memory database (private) và in-memory database (named)



in-memory database (private): Bạn sẽ khai báo một db URL lược bỏ phần tên db đi. Loại db này chỉ chấp nhận một connection duy nhất. H2 sẽ tạo một database mới cho connection thứ hai hướng đến db URL này. URL của loại db này trông như sau:  jdbc:h2:mem: Vì db nằm trong memory nên sẽ không có username, password.



in-memory database (named): Khác với loại db trên, loại db này có xác định một tên cụ thể cho db. Loại db này chấp nhận nhiều connection. Hai connection cùng hướng đến URL của loại db này sẽ cùng được kết nối đến cùng một database trong điều kiện cùng virtual machine. URL của loại db này trông như sau: jdbc:h2:mem:<databaseName>



Khi nào thì dùng named db khi nào dùng private db ?



Tùy yêu cầu application của bạn. Ví dụ bạn tạo một Java application. Bạn chạy application đấy trong JRE. Nếu application cần nhiều connection cùng lúc đến in-memory h2 database thì bạn sẽ cần loại named db.



Để tạo datas source trong IDE đến named in-memory h2 db, bạn cần:


  • h2-1.3.173.jar
  • driver class: org.h2.Driver
  • url: jdbc:h2:mem:sample_db # sample_db là tên của db
  • username: không cần, để rỗng
  • password: không cần, để rỗng

Sau khi thiết lập data source, bạn chạy script để thiết lập cấu trúc cho db. Thế là xong.


Để làm việc named h2 db với hibernate, bạn cần nhiều hơn thế.



H2 db luôn tự động close db khi last connection release. Để giữ db luôn open phục vụ các connection tiếp theo, bạn cần gài thêm tham số DB_CLOSE_DELAY=-1 sau db URL. 



H2 còn tự động close db khi JVM exit. Điều này có nghĩa là sau mỗi lần chạy ứng dụng xong, db của bạn sẽ bị xóa sạch. Để giữ cho db của bạn open cho lần chạy ứng dụng tiếp theo, bạn cần gài tiếp thêm tham số DB_CLOSE_ON_EXIT=FALSE sau db URL



Còn một tham số nữa dùng để tăng độ tin cậy khi thiết lập kết nối đến db là IFEXISTS. Tham số này sẽ kiểm tra xem liệu db khai báo theo URL có tồn tại hay không. Mặc định khi application thực hiện DriverManager.getConnection(url, ...), nếu db chưa tồn tại, h2 sẽ tạo một empty db cho application. Nếu bạn không muốn h2 tự động làm điều này thì bạn chỉ cần gài tham số IFEXISTS=TRUE sau URL. Một cố gắng kết nối đến db chưa tồn tại sẽ khiến cho exception được ném ra.



Khi chạy hibernate application, hibernate framework sẽ chỉ đơn giản load *.hbm.xml và map với entity class. Nó giả định là bạn có db rồi, cấu trúc db đã có rồi. Nhưng chạy db in-memory, db này sẽ hình thành trong khu vực memory mà được cấp cho application của bạn khi chạy. Bạn không thể tạo ra nó từ trước, bạn chỉ có thể tạo ra nó khi chạy application của bạn. Làm thế nào đây:


  • Cần gán IFEXISTS=FALSE để h2 tạo một empty db cho bạn
  • Sử dụng tính năng execute SQL on connection, bạn gán thêm đoạn này để load và run script trước khi sử dụng: INIT=RUNSCRIPT FROM '~/create.sql'



Tóm lại, để sử dụng h2 với hibernate, bạn cần điều chỉnh đoạn URL như sau:

jdbc.url=jdbc:h2:mem:sample_db;INIT=RUNSCRIPT FROM '<đường dẫn tuyệt đối đến script file của bạn trên file system>';DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;IFEXISTS=FALSE;


Script file của bạn chỉ cần chứa các lệnh SQL để tạo tables để hình thành cấu trúc cho db. Vả lại bạn tìm trong h2 cũng không thấy lệnh SQL tạo db đâu.

Không có nhận xét nào:

Đăng nhận xét