Thứ Sáu, 16 tháng 8, 2013

Với oracle, sử dụng hibernate generator hay trigger để tăng giá trị sequence ?



Bạn đều biết mỗi một table đều cần một trường đóng vai trò làm primary key. Giá trị của trường này luôn là duy nhất cho mỗi record. Trường này sẽ làm nhiệm vụ phân biệt mỗi record là duy nhất trong table, sẽ không thể có hai record mà có các giá trị hoàn toàn giống nhau được. Để thực hiện điều đó thì primary key thường là kiểu số và được database hỗ trợ tăng tự động. Khi thực hiện insert, bạn không cần nhập giá trị cho trường này. Database sẽ ngầm định thực hiện tăng giá trị số này lên, đảm bảo các record khác nhau sẽ có số khác nhau. Mỗi database lại có cách xử lý cột số này khác nhau. Oracle sẽ sử dụng một đối tượng sequence. Đối tượng này không có liên hệ gì đến table mà nó sẽ được sử dụng. Bạn chỉ biết đối tượng này thuộc schema nào mà thôi. Khi bạn cần tăng số tự động cho cột PK thì sử dụng câu SQL tương tự như sau:


INSERT INTO Orders_tab (Orderno, Custno)
VALUES (Order_seq.NEXTVAL, 1032);

Với Order_seq là một đối tượng sequence được tạo ra trước đó. Với ms sql hay mysql, khi khai báo table, bạn đã xác định rõ cột nào nhận giá trị tăng tự động rồi. Với ms sql, bạn khai báo cột đó là IDENTITY còn với mysql, bạn khai báo cột đó là AUTO_INCREMENT. Khác với oracle, bạn không cần khai báo những cột đã được xác định tăng giá trị tự động vào câu lệnh insert.

Xét riêng oracle, nếu bạn không muốn gọi nextval trong câu lệnh insert, bạn có thể dùng trigger để thực hiện tăng số tự động.

Khi làm việc với hibernate, một ORM rất phổ biến, để các thao tác thêm dữ liệu qua các mapping object thực hiện được mà không cần quan tâm đến số tăng tự động, bạn cần khai báo generator cho trường bạn chọn làm id của bảng. Generator sẽ xác định cơ chế tăng số tự động tương ứng với từng database. Hibernate sẽ thực hiện tăng số tự động giùm bạn như sau:

  • Bước 1: Hibernate sử dụng cơ chế generator để tạo giá trị mới. 
  • Bước 2: Hibernate gán giá trị mới vào trường chọn làm id của mapping object.
  • Bước 3: Hibernate chuyển hóa câu lệnh save thành insert với trường id nhận giá trị mới được sinh ở bước 1.
  • Bước 4: Nhờ có bước 1 và bước 2 mà bạn có thể lấy được giá trị id mới được tạo ra của object.

Trong trường hợp bạn sử dụng trigger để tăng giá trị cho cột số tự động (sử dụng database oracle), bạn không cần khai báo generator cho mapping object, bạn vẫn có thể thực hiện save object thành công. Nhưng hai cách làm đó khác gì nhau ?

  • Sử dụng trigger, câu lệnh insert của bạn sẽ không có giá trị cho cột số tự động, trigger sẽ làm việc đó. Bạn không thể lấy được ngay id vừa tạo ra qua object. Bạn cần thực hiện tiếp một query nữa để lấy ra id đó.
  • Sử dụng generator, hibernate đã lấy được giá trị mới cho id từ bước 1, nó sử dụng giá trị này cho câu lệnh insert luôn.  Bạn có thể lấy ngay id vừa tạo ra qua object. Không cần thêm bất cứ query nào cả.

So sánh thì thấy sử dụng generator rất hiệu quả. Nhưng nếu bạn lập trình sql script cho mục đích học hỏi thì dùng trigger là lựa chọn tốt.

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

Đăng nhận xét