Component không phải là một tham chiếu thực thể, nó giống như một đối tượng được chứa trong một đối tượng cha khác.. Như vậy chúng ta sẽ tạo mô hình object với 2 class tương ứng với 2 ta
Trang 1Báo cáo tìm hiểu đề tài – mã đề tài: SE04.
HIBERNATE – phần 1
I. Component mapping.
1. Component mapping là gi?
Component không phải là một tham chiếu thực thể, nó giống như một đối tượng được chứa trong một đối tượng cha khác Nó không có id và chỉ tồn tại khi thực thể cha tồn tại Component cho phép bạn nhóm một vài cột vào trong một đối tượng
Trang 2- home-phone
để tổ chức cơ sở dữ liệu tốt hơn, người ta sẽ tách các thuộc tính : StreetAddress, city, zipcode ra thành một đơn vị dữ liệu riêng, việc này giúp cơ sở dữ liệu của chúng ta tường minh hơn, rõ ràng hơn và việc truy xuất đơn giản hơn
Các thuộc tính sau khi được tách ra sẽ thuộc về 1 đơn vị dữ liệu có tên
là Address
Ta có nhận xét như sau:
Nói một cách khác, Address chính là một component
2. Using Component - sử dụng component
Việc ánh xạ từ bảng dữ liệu cho component là hết sức đơn giản để dễ hiểu hơn, ta xét việc ánh xạ từ bảng AccountOwner cho component address như sau:
Trang 3Cú pháp của một component như sau:
Bên trong thẻ component là thẻ parent khai báo tên của Cha
Tiếp theo là các thẻ property khai báo các thuộc tính bên trong của component
3. Nested Components - Component lồng nhau:
Là hiện tượng bên trong component cho có chứa các component con bên trong
Xét ví dụ sau:
Trang 4Thuộc tính zipcode được chia làm hai phần: Zip và plus4 Ví du: 1234.
12222-Như vậy để thuận tiện, người ta đưa zipcode vào một component như hình sau:
Ta thấy được rằng bên trong bảng AccountOwner có component Address và bên trong Address có component Zipcode Đây là một ví dụ điển hình cho việc thể hiện Nested component
Ta biểu diễn file mapping như sau:
4. Mapping a component – Tham chiếu trong component
Trang 5Một component có thể có tham chiếu tới đối tượng <parent>.
5. Collection of component
6. Component as Entity ID
II. Collection Mapping
1. Mapping collection of value
Tập hợp các giá trị: là danh sách lưu trữ các giá trị, các kiểu tham trị(String, integer,double…) nhưng không phải là đối tượng cố định
Trang 6Mapping collection of value là sự tập hợp của các giá trị.
Để định nghĩa tập hợp, ta sử dụng thẻ <bag>, 1 thẻ tập hợp đơn giản trong hibernat
Thẻ <bag> là đối tượng không theo thứ tự, mỗi cái có thể chứa các phần tử lặp lại
Ví dụ về thẻ <bag>:
2. Collection types in hibernate
Ngoài thẻ <bag> , còn có nhiều tập hợp khác trong hibernate, mỗi loại có những ưu điểm và đặc điểm riêng
Thẻ <Set> có thể tùy chọn sắp xếp : unsort hoặc natural
Thẻ <Set> được sử dụng trong quan hệ one-many hoặc many-one
Ví dụ về khai báo thẻ <Set>:
2.3. Association as <List>
Trang 7Thẻ <List> là tập hợp chỉ mục được kết nối, chúng ta có thể giữ lại thứ tự của list khi nó kết nối lại, do đó nó cần phải có một chỉ mục của cột mà nó tham chiếu tới trong bảng cơ sở dữ liệu.
<List>khác <Bag> là <List> có kết nối chỉ mục phần tử
Thẻ <List> được sử dụng trong quan hệ one-many hoặc many-one
Ví dụ về khai báo thẻ <List> :
2.4. Association as <Array>
Thẻ <Array> tương đối giống thẻ <List>, có một điểm khác biệt đó
là thẻ <Array> tương ứng với kiểu mảng trong java, còn thẻ <List
>tương ứng với kiểu List
Do đó, khi mảng không thể tự động tăng giảm được kích thước, người ta thường sử dụng thẻ<List>
Thẻ <Array> được sử dụng trong quan hệ one-many hoặc many-one
Ví dụ về khai báo thẻ <Array>:
2.5. Association as Map
Thẻ <map> gần giống như thẻ <List> nhưng thẻ <map> sử dụng khóa có kiểu bất kỳ để làm chỉ mục chứ không sử dụng kiểu int như thẻ <List>
Thẻ <map> có thể có thứ tự hoặc không có thứ tự nhưng đòi hỏi phải có khóa và giá trị cột
Thẻ <map> được sử dụng trong quan hệ one-many hoặc many-one
Ví dụ về khai báo thẻ <map>:
Trang 8hệ(many-Thẻ <idbag> được sử dụng trong quan hệ many-many.
Ví dụ về khai báo thẻ <idbag>:
3. Sorting the collection.
Để sắp tăng ta khai báo từ khóa sort với ba giá trị là natural,
unsort, hoặc my.custom.mycomparator.
III. Inheritance Mapping.(Tính kế thừa trong Hibernate)
Đặc tính của Kế thừa (Inheritance)
Java: sử dụng từ khóa “extend” hay “implement”
Trang 9Các bảng không thể “extend” từ các bảng khác được.
Vấn đề “Impedence missmatch”
Để hiểu rõ vấn đề Impedence missmatch ta xem ví dụ sau :
Ta có một mô hình dữ liệu có 2 table: Customers và Accounts
Như vậy chúng ta sẽ tạo mô hình object với 2 class tương ứng với 2 table này:
Nhưng mô hình object trên thiếu tính linh động và khả năng mở rộng, do đó chúng ta nên thiết kế lại để thêm inheritance và abstraction, làm mô hình gần hơn với thực tế:
Chúng ta có thể thấy rõ ràng sự không đối xứng (mismatch) giữa mô hình
dữ liệu và mô hình object trong trường hợp này Trong database, hoàn toàn chấp nhận được khi chứa toàn bộ thông tin của Person và PersonName trong một table Customers Nhưng để tăng tốc độ thực thi, việc bảo trì và sự linh hoạt; một object lớn nên được chia thành nhiều object nhỏ
Vậy phải giải quyết các vấn đề này như thế nào?
Trong Hibernate ta có 4 cách giải quyết :
1. Table per class hierachy
2. Table per subclass
3. Table per concrete class
4. Đa hình tiềm ẩn
Xét ví dụ sau đây:
Trang 10Ta có 3 lớp : Person, Teacher và Student Trong đó Person là lớp cha và Teacher , Student kế thừa từ lớp cha này.
Sơ đồ lớp:
Table per class hierachy
Với phương pháp nà ta sẽ ánh xạ tất cả các lớp vào duy nhất 1 bảng tất cả các thuộc tính của các lớp sẽ hiển thị trong bảng như là một colum, trong đó sẽ có 1 cột chứa các tên lớp con mà ta gọi là “Discriminator” để phân biệt các lớp với nhau
Theo bảng Person trên ta thấy Discriminator lúc này là cột PERSON_TYPE chứa 2 trường dữ liệu là Sutent và Teacher Đây là tên của hai lớp con kế thừa từ lớp cha Person
Bảng PERSON chứa tất cả các thuộc tính (attributes ) cùa các lớp Person, Teacher
và Student như là các colunms của nó
Mapping cho Table class hierachy:
Person.hbm.xml
<hibernate-mapping>
<class name=”Person” table=”PERSON”>
<id name=”id” column=”ID”>
<generator class=”increment”/>
</id>
<discriminator column=”PERSON_TYPE” type=”string”/>
<property name= “name” column=”NAME”/>
</class>
</hibernate-mapping>
Trang 11Bảng Person có chứa column PERSON_TYPE Column này được maped (ánh xạ) bằng cách sử dụng thẻ XML <discriminator>
Discriminator không phải là thuộc tính của bất kỳ java class nào, nó chỉ là một cột được dùng chung giữa databse và Hibernate
Mapping file cho hai lớp Student và Teacher
Student.hbm.xml
===============
<hibernate-mapping>
<subclass name=”Student” extends=Person” discriminator-value=”Student”>
<property name= “branch” column=”BRANCH”/>
<subclass name=”Teacher” extends=Person” discriminator-value=”Teacher”>
<property name= “department” column=”DEPARTMENT”/>
không thể khai báo cho các subclass ràng buộc NOT NULL
Table per concrete class
Một lớp con là một bảng riêng biệt
Trang 12Bây giờ ta mapping bằng <union-subclass>
<union-subclass> được sử dụng cho mỗi subclass trong mapping file
<class name="Person">
<id name="id" type="long" column="ID">
<generator class="sequence"/>
</id>
<property name="name" column="NAME"/>
<union-subclass name="Student" table="STUDENT">
<property name="branch" column="BRANCH"/>
</union-subclass>
<union-subclass name="Teacher" table="TEACHER ">
<property name="branch" column="BRANCH"/>
</union-subclass>
</class>
Table per subclass:
Ta tạo ra ba bảng riêng biệt cho 3 lớp
Trang 13<joined-subclass> được sử dụng cho mỗi subclass torng mapping file.
<class name="Person" table="PERSON">
<id name="id” column="ID">
<generator class="native"/>
</id>
<property name="name" column="NAME"/>
<joined-subclass name="Teacher" table="TEACHER">
IV. Working With Object
1. vòng đời của một object trong Hibernate
Các objects mà Hibernate quản lý phải luôn luôn ở một trong bốn trạng thái(STATE) sau đây:
1. Transient
2. Persisten
Trang 143. Removed.
Các Objects muốn chuyển từ trạng thái này sang trạng thái khác sẽ được thực hiện thông qua các phương thức khác nhau
Transient State_ Trạng thái tạm thời
Tất cả các đối tượng khi mới khởi tạo đều ở trạng thái Transient
Đối tượng account vừa được ta khởi tạo cho nên account bây giờ đang ở trạng thái tạm thời mà thôi
Đặc điểm của các đối tượng khi đang ở trạng thái Transient State:
Các đối tượng này không hề có bất kỳ liên quan đến các dữ liệu
có trong database
tượng nào khác thì nó sẽ được hủy bởi cơ chế thu gom rác(garbage collected)
PERSISTENT STATE_Trạng thái ổn định
Với các đối tượng ở trạng thái này thì nó có các đặc điểm sau:
• là một đối tượng được tồn tại bằng việc lấy lên từ database
• Hay là một đối tượng đang ở trạng thái tạm thời (Transient State) nhưng đã được lưu
• Đây là trạng thái duy nhất mà các objecs được lưu vào database Nói cách khác khi một object muốn được lưu vào databse điều đầu tiên là nó phải đang ở trạng thái Persisent
• Việc chỉnh sửa, cập nhật trên một đối tượng đang ở trang thái khác trạng thái này sẽ KHÔNG được lưu lại vào database
• Trong khi đó khi ta làm việc với một đối tượng đang ở trạng thái Persistent thì việc thay đổi của đối tượng này sẽ được tự động cập nhật xuống databse mà không càn gọi bất kỳ phương thức Session Persistent nào
Trang 15 các đối tượng được tạo ra ổn định , lâu bền thông qua các Hibernate session:
Ta xem ví dụ sau đây:
Đầu tiên ta thấy khi mới khởi tạo đối tượng account thông qua phương thức new Account() thì accoount lúc này đang ở trạng thái tạm thời mà
thôi(Transient state) Hibernate không làm việc trên account đơn giản vì nó không hiểu account là gì
Vậy để Hibernate hiểu và làm việc trên account ta phải chuyển nó về trạng thái Persistent thông qua session Lúc này việc cập nhật, thay đổi ta làm trên account sẽ được Hibernate tự động lưu xuống databse
REMOVE STATE.
Xét đối tượng đang ở trạng thái Persistent
Trang 16Remove state là trạng thái mà mà đối tượng này đã bị delete ra khỏi database.
• session.delete(account);
Lúc này mọi thay đổi trên đối tượng này sẽ không còn được lưu xuống
database nữa Cơ chế thu gom rác của Hibernate sẽ dọn dẹp đối tượng này bởi vì Hibernate không cho phép tồn tại một đối tượng rỗng.(Đối tượng không lưu trử bất kỳ thông tin gì.)
Xét ví dụ sau đây:
Đẩu tiên khởi tạo một phiên làm việc cho Hibernate(session)
Sau đó ta lấy lên một account với id = 1 Lúc này account được trả ra trong trạng thái Persistent
Tiếp đó ta tiến hành delete account đi
Lúc này mọi chỉnh sửa trên account sẽ bị Hibernate lờ đi vì account hiện tại đang ở trạng thái Remove
Chú ý rằng trong Java thì đối tượng account lúc này sẽ vẫn còn alive, tức
là ta có thể gán giá trị cho nó, làm việc với nó như một đối tượng bình thường dù
đã bị delete ra khỏi databse và đối tượng này sẽ alive cho đến khi nào lập trình viên set nó null hoặc hủy nó đi
DETACHED STATE
Trang 17Một đối tượng persistent sẽ vẫn còn được tham chiếu sau khi session của nó
Nhưng không thuộc sự quản lý của Hibernate nữa
Lúc này mọi sự thay đổi trên detached object sẽ không còn được lưu xuống database
Có thể redetached ( kết nối lại) để trả về trạng thái Persistent cho đối tượng và gây ra hiện tượng là lưu lại trạng thái của chính nó xuống database
update();
merge();
lock(); // ta retach() nhưng sẽ không lưu trạng thái
Xét ví dụ sau :
Trang 18Đầu tiên khởi tạo session1.
Tạo đối tượng account thông qua session1
Sau đó đóng session1 lại
Lúc này account đang ở trạng thái Detached State
Bây giờ ta muốn trả lại trạng thái Persistent cho nó thì ta re-attach lại thông qua việc mở ra một phiên làm việc mới tức là tạo ra session2
2. Các mối quan hệ thông dụng
2.1. Quan hệ một chiều (unidirectional association):
nhất trong các mối quan hệ
Mỗi một căn nhà (có địa chỉ) thuộc về một cá nhân, mỗi cá nhân
có thể có nhiều căn nhà Mối quan hệ hướng từ căn nhà ( có địa chỉ ) đến cá nhân là mối quan hệ Nhiều – Một
Trang 19Nhiều – Nhiều nhưng có them thuộc tính Unique = true
Trang 20<one-to-one name="person" constrained="true"/>
không thông dụng và ít được giới thiệu
Trang 21Bạn nên thay thế dùng một bảng tham gia trong trường hợp này.
2.2. Quan hệ một chiều có dùng bảng tham gia :
tiên lựa chọn Chỉ rõ unique = true đã chuyển từ quan hệ Nhiều – Nhiều sang quan hệ Một - Nhiều
Trang 22<generator class="native"/>
</id>
mối quan hệ phổ biến khi mối quan hệ là tuỳ chọn
hệ có thể sử dụng nhưng chi trong các trường hợp cực kỳ đặc biệt
<class name="Person">
Trang 23<id name="id" column="personId">
điển hình trong các mối quan hệ
Trang 242.3. Quan hệ hai chiều (bidirectional association) :
Trang 25<one-to-many class="Person"/>
</set>
Nếu bạn sử dụng một danh sách, hoặc lập chỉ mục thì thiết lập các cột quan trọng với khoá ngoại không phải null Hibernate sẽ quản lý các liên kết từ các phía để duy trì chỉ số của mỗi phần tử với thiết lập update = false và insert = false
Trang 27<generator class="foreign">
<param name="property">person</param> </generator>
Trang 30VI. Batch processing
Batch process là quá trình thực thi cùng một lúc một loạt các chương trình.Trong suốt quá trình thực thi Batch process ta cần thêm xóa sửa một lượng lơn
dữ liệu, điều này có thể làm tràn bộ nhớ tạm của Hibernate (Outofmemmory)
Để giải quyết vấn đề này, ta sử dụng phương thức flush() và clear() để xóa bộ
nhớ tạm sau mỗi 100 đến 200 dòng dữ liệu
Hai phương thức này giải phóng bộ nhớ tạm ở mức 1
Ngược lại, nếu bộ nhớ tạm ở mức hai được sử dụng ( Mức Entity), ta phải tắt chức năng này bằng câu lệnh :
Trang 31Để thêm 100000 dòng dữ liệu ta làm các việc như sau :
Tiến hành insert dữ liệu
Kiểm tra và dung hai phương thức flush() và Cleart() để xóa bộ nhớ tạm ở mức một
2. Batch Update –batch Delete
Hiệu chỉnh CacheMode.IGNORE để Hibernate không tương tác với
bộ nhớ tạm mức hai trong một session riêng
2.2. Sử dụng câu truy vấn
Cú pháp :
Trang 32 Mệnh đề FROM và WHERE được tùy chọn.
Trang 33Đặc tính của Kế thừa (Inheritance)
Java: sử dụng từ khóa “extend” hay “implement”
Các bảng không thể “extend” từ các bảng khác được
Vấn đề “Impedence missmatch”
Để hiểu rõ vấn đề Impedence missmatch ta xem ví dụ sau :
Ta có một mô hình dữ liệu có 2 table: Customers và Accounts
Như vậy chúng ta sẽ tạo mô hình object với 2 class tương ứng với 2 table này:
Nhưng mô hình object trên thiếu tính linh động và khả năng mở rộng, do đó chúng ta nên thiết kế lại để thêm inheritance và abstraction, làm mô hình gần hơn với thực tế:
Trang 34Chúng ta có thể thấy rõ ràng sự không đối xứng (mismatch) giữa mô hình dữ liệu
và mô hình object trong trường hợp này Trong database, hoàn toàn chấp nhận được khi chứa toàn bộ thông tin của Person và PersonName trong một table Customers Nhưng để tăng tốc độ thực thi, việc bảo trì và sự linh hoạt; một object lớn nên được chia thành nhiều object nhỏ
Vậy phải giải quyết các vấn đề này như thế nào?
Trong Hibernate ta có 4 cách giải quyết :
5. Table per class hierachy
6. Table per subclass
7. Table per concrete class
8. Đa hình tiềm ẩn
Xét ví dụ sau đây:
Ta có 3 lớp : Person, Teacher và Student Trong đó Person là lớp cha và
Teacher , Student kế thừa từ lớp cha này
Sơ đồ lớp: