Đề tài Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web

1. Tổng quan.1

1.1. Tổng quan vềMDA .1

1.1.1. Khái niệm MDA.1

1.1.2. Sơlược các thành phần cơbản trong MDA .2

1.1.2.1. PIM (Platform Independent Model) .2

1.1.2.2. PSM (Platform Specified Model).3

1.1.2.3. Code .3

1.1.2.4. Các bước chuyển đổi tự động .3

1.1.3. Các lợi ích từMDA .4

1.1.3.1. Tính khảchuyển đổi (Portability) .4

1.1.3.2. Hiệu suất (Productivity).5

1.1.3.3. Tính cộng tác với các hệthống khác (Interoperability).7

1.1.3.4. Bảo trì và lập tài liệu (Maintenance and Documentation) .8

1.1.4. Sơlược vềsựchuyển đổi mô hình .8

1.1.4.1. Các mô hình đánh dấu.9

1.1.5. Tóm tắt các thành phần chính của MDA Framework .11

1.1.6. Ví dụvềáp dụng MDA framework .14

1.1.6.1. Các thuộc tính Public và Private.14

1.1.6.2. Sựliên kết (Association) giữa các lớp .16

1.1.7. Các công cụhỗtrợMDA .18

1.1.7.1. openMDX .18

1.1.7.2. Giới thiệu vềRational XDE.21

1.2. Các frameworks sửdụng cho ứng dụng web.22

1.2.1. Struts.22

1.2.1.1. MVC Design Pattern (Model-View-Controller Design Pattern) .23

1.2.1.2. Struts : Một sựhiện thực của MVC pattern.24

1.2.1.3. Các tầng của MVC áp dụng trong Struts .24

1.2.2. JavaServer Faces .30

1.2.2.1. Các ưu điểm của công nghệJavaServer Faces .31

1.2.2.2. Ứng dụng JavaServer Faces.32

1.2.2.3. User Interface Component Model.32

1.2.2.4. Quản lý Backing Bean .33

1.2.3. So sánh giữa JavaServer Faces (JSF) vàStruts.33

1.2.3.1. Độtrưởng thành .34

1.2.3.2. Tính linh động của Controller/ Xửlý các sựkiện .34

1.2.3.3. Định hướng .36

1.2.3.4. Phát triển trang .39

1.2.3.5. Tích hợp .39

1.2.3.6. Khảnăng mởrộng.40

1.2.4. Hibernate .40

1.2.4.1. ORM .41

1.2.4.2. Kiến trúc Hibernate.41

1.2.4.3. Truy vấn trong Hibernate - HQL (Hibernate Query Language).45

2. Áp dụng MDA vào quá trình phát triển ứng dụng Web .53

2.1. Các hướng tiếp cận hỗtrợcho MDA.53

2.1.1. Pattern.53

2.1.2. Code template (code mẫu).53

2.1.3. UML Profile – cơchếmởrộng UML .53

2.1.4. Plugin.54

2.1.4.1. Cấu trúc bên trong một plugin .55

2.1.4.2. The Plug-in Development Environment (PDE).55

2.2. Lập mô hình ứng dụng web với UX .56

2.2.1. Các artifact của UX .57

2.2.1.1. Screen.57

2.2.1.2. Quản lý Content .58

2.2.1.3. Các đường định hướng.59

2.2.2. Lập mô hình UX với UML.59

2.2.2.1. Screen Flow .65

2.2.2.2. User Input.66

2.2.2.3. Sựhiện thực storyboard .70

2.2.2.4. Screen Compartment.72

2.2.3. Ánh xạtừmô hình UX sang JSF.74

2.2.4. Tổng kết.75

2.3. Giới thiệu vềMDA Toolkit .75

2.3.1. Transformation Development Wizard.75

2.3.1.1. MDA Transformation .76

2.3.1.2. Wizard.76

2.3.2. MDA API .76

2.3.3. MDA Profile Tool .77

2.4. Quy trình phát triển MDA với Rational XDE và MDA Toolkit .78

2.4.1. Các vấn đềnảy sinh và các kết luận.78

2.4.2. Các mặt chính của MDA Toolkit .79

2.4.3. Vai trò của các profile UML .80

2.4.4. Đóng gói và chuyển giao các chuyển đổi MDA Toolkit .80

2.4.5. Các bài học trong việc thiết kếvà ứng dụng các giải pháp MDA .81

2.4.5.1. Vềvấn đềcác kết nối mô hình ngữnghĩa.81

2.4.5.2. Vềvấn đềxác định các chuyển đổi cần thiết .83

2.4.5.3. Vềvấn đềlập tài liệu các yêu cầu chuyển đổi .83

2.4.5.4. Vềvấn đềtạo UML Profile.93

2.4.5.5. Vềvấn đềphát triển chuyển đổi .94

2.4.5.6. Vềvấn đềtriển khai chuyển đổi .98

3. Hiện thực .99

3.1. Pattern và Code Template.99

3.1.1. DateHelperLib .99

3.1.2. FileHelperLib .99

3.2. Plugin .99

3.2.1. Plugin UserManagement .99

3.2.1.1. Chức năng .99

3.2.1.2. Hiện thực:.100

3.2.1.3. Hướng dẫn sửdụng plugin: .102

3.2.2. Plugin Search.105

3.2.2.1. Chức năng .105

3.2.2.2. Hiện thực.106

3.2.2.3. Hướng dẫn sửdụng.107

3.3. Ứng dụng web: WebLog .109

pdf115 trang | Chia sẻ: netpro | Lượt xem: 2215 | Lượt tải: 4download
Bạn đang xem trước 20 trang tài liệu Đề tài Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
thực thể Session từ một SessionFactory. SessionFactory không có tính lighweight. Nó được dùng chung cho nhiều thread ứng dụng. Điển hình là có một SessionFactory cho toàn ứng dụng, được tạo trong phần khởi tạo ứng dụng. Tuy nhiên, nếu ứng dụng cần truy xuất nhiều database bằng cách sử dụng Hibernater thì cần một SessionFactory cho mỗi database. SessionFactory lưu lại các câu lệnh SQL đã tạo và các siêu dữ liệu (metadata) ánh xạ khác mà Hibernate sử dụng ở thời điểm chạy. Nó cũng lưu các dữ liệu đã từng được đọc (được cache lại) trong một đơn vị công việc và có thể được sử dụng trong một đơn vị công việc trong tương lai (chỉ nếu các ánh xạ class và collection xác định rằng cache cấp hai này là cần thiết). Configuration interface Đối tượng Configuration được sử dụng để định cấu hình và boostrap Hibernate. Ứng dụng sử dụng một thực thể Configuration để xác định vị trí của các tài liệu ánh xạ (mapping document) và các thuộc tính xác định Hibernate và sau đó tạo ra SessionFactory. Transaction interface Interface Transaction là một API tùy chọn. Nghĩa là các ứng dụng Hibernate có thể không sử dụng interface này, thay vào đó nó sẽ quản lý các transaction bằng code cơ sở của riêng nó. Một Transaction interface tách biệt (trừu tượng hóa) code ứng dụng khỏi sự hiện thực transaction bên dưới (có thể là transaction JDBC, UserTransaction JTA hoặc transaction CORBA) cho phép ứng dụng điều khiển các biên transaction (transaction Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 44 boundary – cho phép xác định khi nào một transaction bắt đầu và kết thúc) thông qua một API nhất quán. Điều này giúp cho các ứng dụng Hibernate có tính khả chuyển trên các môi trường thực thi và các container khác nhau. Query và Criteria interface Interface Query cho phép thực hiện các truy vấn đến các cơ sở dữ liệu và điều khiển việc các truy vấn này được thực thi như thế nào. Các truy vấn được viết bằng HQL (Hibernate Query Language) hoặc bằng ngôn ngữ SQL nguyên thuỷ. Một thực thể Query được dùng để bind các thông số truy vấn, giới hạn của số kết quả trả về bởi truy vấn và nhiệm vụ cuối cùng là thực thi truy vấn. Interface Criteria cũng tương tự như vậy, nó cho phép tạo và thực thi các truy vấn chuẩn hướng đối tượng. Một thực thể Query có tính lightweight và không thể sử dụng ngoài Session đã tạo ra nó. 1.2.4.2.1.2. Các interface callback Interface Callback cho phép các ứng dụng nhận một thông báo khi có một sự kiện xảy ra đối với một đối tượng – ví dụ như khi đối tượng được nạp vào, được lưu hoặc bị xoá. Các ứng dụng Hibernate không cần hiện thực những callback này nhưng chúng sẽ có ích cho việc hiện thực các loại chức năng tổng quát, như là tạo ra các bản ghi kiểm toán (audit record). Gồm các interface như: • Lifecycle và Validatable: cho phép một đối tượng persistent phản hồi các sự kiện liên quan đến vòng đời (lifecycle) persistent của riêng nó. • Interceptor cho phép ứng dụng xử lý các callback mà không buộc các class persistent hiện thực các API đặc trưng của Hibernate (Hibernate-specific API). Các hiện thực interface Interceptor được truyền đến các thực thể persistent như các thông số. 1.2.4.2.1.3. Type Một thành phần cơ bản và rất mạnh của kiến trúc này định nghĩa của Hibernate về Type. Một đối tượng Type của Hibernate ánh xạ một kiểu của Java đến một kiểu cột của cơ sở dữ liệu (database column type). Kiểu này có thể kéo dài qua nhiều cột. Tất cả các thuộc tính persistent của class persistent, bao gồm các quan hệ (association), có môt kiểu Hibernate tương ứng. Điều này làm cho Hibernate trở nên đặc biệt linh hoạt và dễ mở rộng. Có rất nhiều kiểu Hibernate đã được xây dựng sẵn, bao gồm tất cả các kiểu gốc của Java (Java primitive) và nhiều class JDK, bao gồm các kiểu cho java.util.Currency, Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 45 java.util.Calendar, byte[] và java.io.Serializable. Hơn thế nữa, Hibernate còn hỗ trợ cho kiểu tuỳ chỉnh do người dùng tự định nghĩa (user-defined custom type). Các interface UserType và CompositeType cho phép thêm vào kiểu riêng của người sử dụng. Đặc tính này giúp điều khiển các class ứng dụng được sử dụng rộng rãi như là Address, Name, MonetaryAmount một cách thuận tiện.Các kiểu tuỳ chỉnh được xem như là một đặc tính chính của Hibernate và được khuyến khích dùng. 1.2.4.2.1.4. Các interface mở rộng Nhiều chức năng mà Hibernate cung cấp có khả năng định cấu hình. Điều này cho phép ta chọn giữa nhiều chiến lược được xây dựng sẵn. Khi các chiến lược này không đủ hiệu quả, Hibernate cho phép thêm vào các hiện thực của riêng người dùng bằng cách hiện thực một interface. Các điểm mở rộng gồm có: • Tạo khoá chính: interface IdentifierGenerator. • Hỗ trợ hình thái ngôn ngữ SQL: class trừu tượng Dialect. • Các chiến lược lưu trữ đệm – cache: interface Cache và CacheProvider. • Quản lý kết nối JDBC: interface ConnectionProvider. • Quản lý transaction: interface TransactionFactory, Transaction và TransactionManagerLookup. • Các chiến lược ORM: phân cấp interface ClassPersister. • Các chiến lược truy cập thuộc tính: interface PropertyAccessor. • Tạo proxy: interface ProxyFactor. 1.2.4.3. Truy vấn trong Hibernate - HQL (Hibernate Query Language) Truy vấn là phần thú vị nhất trong việc viết code truy xuất dữ liệu. Một câu truy vấn phức tạp có thể tốn nhiều thời gian để đạt được kết quả và ảnh hưởng của nó lên hiệu suất của ứng dụng là rất lớn. 1.2.4.3.1. Định nghĩa Hibernate cũng có một ngôn ngữ truy vấn cho riêng nó, tên là Hibernate Query Language, gọi tắt là HQL. Về mặt cấu trúc HQL cũng tương tự như SQL với các mệnh đề SELECT, FROM và WHERE. HQL cũng hỗ trợ subselect nếu cơ sở dữ liệu bên dưới cũng hỗ trợ. Nhưng thật sự HQL là ngôn ngữ truy vấn hướng đối tượng với các khái niệm về thừa kế (inheritence), tính đa hình (polymorphism) và quan hệ (association). 1.2.4.3.2. Các cách thực hiện việc truy vấn trong Hibernate Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 46 Thực ra trong Hibernate ta có thể dùng đến 3 cách để biểu diễn câu truy vấn. • Cách thứ nhất là sử dụng HQL: Ví dụ: session. createQuery(“from Category c where c.name like ‘Laptop%’”); • Cách thứ hai là sử dụng hàm API Criteria cho truy vấn, gồm truy vấn theo chuẩn (query by criteria, QBC) và truy vấn theo ví dụ (query by example, QBE). Ví dụ: session. createCriteria((Category.class).add(Expression.like("name", "Laptop%") ); • Cách thứ ba là sử dụng câu SQL trực tiếp với sự ánh xạ tự động tập kết quả thành các đối tượng Ví dụ: session.createSQLQuery("select {c.*} from CATEGORY {c} where NAME like 'Laptop%'","c",Category.class); Trong tài liệu này chúng ta chỉ đề cập đến cách truy vấn đầu tiên. Cần tham khảo thêm về hai cách còn lại có thể tham khảo thêm tài liệu Hibernate in Action, chương 7 “Retrieving objects efficiently”. Đầu tiên là cách các câu truy vấn được thực thi (ta chưa quan tâm đến các câu truy vấn, phần này sẽ được trình bày ngay sau đó). 1.2.4.3.2.1. Cách thực thi câu truy vấn • Interface cho việc truy vấn (query interface) Để tạo một thực thể Query mới ta có thể gọi hàm createQuery(). Ví dụ: Query hqlQuery = session.createQuery("from User"); • Phân trang kết quả Phân trang là một kỹ thuật thường được sử dụng. Người sử dụng có thể nhìn thấy kết quả tìm kiếm (ví dụ, tìm các Nhânviên trong một công ty) trong một trang. Trang này chỉ hiển thị giới hạn một tập con của kết quả (ví dụ, 10 nhân viên) vào một thời điểm, và người sử dụng có thể chuyển sang trang kết quả kế tiếp hoặc quay lại trang kết quả trước đó. Interface Query hỗ trợ việc phân trang của kết quả truy vấn: Query query = session. createQuery(“from User u order by u.name asc”); query.setFirstResult(0); query.setMaxResult(10); Hàm setMaxResult(10) giới hạn tập kết quả truy vấn đến 10 đối tượng đầu tiên được chọn ra (select) trong cơ sở dữ liệu. Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 47 Bây giờ với một số nền tảng về cách thực thi câu truy vấn, ta có thể tập trung khám phá ngôn ngữ truy vấn HQL. 1.2.4.3.2.2. Các thành phần trong câu truy vấn • Mệnh đề FROM Mệnh đề FROM cho phép xác định các đối tượng sẽ được truy vấn. Nó cũng cho phép tạo ra các bí danh cho tên đối tượng. Giả sử ta muốn truy vấn tất cả các thực thể Event có tên là “Festival”, câu truy vấn sẽ như sau: from Event e where e.name = “Festival” Câu truy vấn này có một cái tên bí danh cho thực thể Event là e. Tên bí danh này có thể được sử dụng giống như trong câu truy vấn SQL ngoại trừ việc ở đây ta sử dụng nó để định danh các đối tượng thay vì định danh các bảng như trong SQL. Một điểm cần lưu ý trong câu truy vấn HQL trên là nó đang truy vấn trên một thuộc tính của đối tượng Event: thuộc tính name. Như vậy là khi truy vấn ta không dùng tên cột trong bảng mà dùng tên thuộc tính. Do HQL sử dụng theo các khái niệm hướng đối tượng, vì vậy không thể viết tắt e.name thành name được. Tên thuộc tính phải luôn được đi kèm với tên đối tượng. Rõ ràng là khi sử dụng HQL, ta không quan tâm đến table và column dữ liệu quan hệ bên dưới mà tập trung vào các thuộc tính của các đối tượng. Khi truy vấn chỉ liên quan đến một đối tượng, thì chỉ cần một đối tượng List chứa các thực thể của đối tượng truy vấn. Nếu cần truy vấn nhiều đối tượng có liên quan đến nhau (các đối tượng có quan hệ với nhau), mệnh đề FROM sẽ chứa nhiều đối tượng: Ví dụ: from Event e, Attendee a where … Và danh sách kết quả sẽ chứa một phép tích Cartesian các đối tượng được truy vấn (phép tích Cartesian là kết quả của việc kết hợp mỗi dòng của môt bảng với mỗi dòng của một bảng khác) mà rất có thể nó không phải là sản phẩm ta mong muốn. Để truy vấn trên nhiều đối tượng có liên quan đến nhau, ta cần kết hợp (join) chúng trong mệnh đề FROM. • Kết hợp (Join) Trong SQL cũng có phép JOIN trả về dữ liệu từ nhiều bảng với một câu truy vấn duy nhất. Tuy nhiên phép JOIN trong HQL chỉ kết hợp các thuộc tính của đối tượng và các quan hệ, trong khi phép JOIN trong SQL kết hợp các bảng. Nếu cần truy vấn các thực thể của đối tượng Event mà một người tham dự (Attendee) xác định sắp tham gia, ta phải kết hợp thuộc tính attendee với đối tượng Event trong câu truy vấn: from Event e join e.attendee a where a.id = 321 Trong HQL, ta có thể kết hợp tất cả các quan hệ (nhiều-một và một-một), cũng như các tập hợp với đối tượng cơ sở của truy vấn. Đối tượng cơ sở trong một truy vấn là đối tượng hiện diện trong mệnh đề FROM. Trong ví dụ trên, đối tượng cơ sở là Event. Trong ví dụ trên, ta có thể đặt một bí danh cho quan hệ được kết hợp và truy vấn trên các thuộc Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 48 tính trong đối tượng được kết hợp. Quy tắc đặt tên cho bí danh của HQL là sử dụng chữ viết thường. o Các loại kết hợp HQL có nhiều kiểu kết hợp khác nhau, các kiểu kết hợp này đều có trong SQL, chỉ có một kiểu kết hợp là ngoại lệ.Bảng sau tóm tắt các kiểu kết hợp Loại kết hợp Luật inner join Các đối tượng không phù hợp với nhau ở một trong hai đầu kết hợp sẽ bị loại bỏ. left [outer] join Trả về tất cả đối tượng ở đầu trái của kết hợp. Nếu đối tượng ở đầu trái của kết hợp không có đối tượng nào trùng khớp (match) ở đầu phải của kết hợp thì nó vẫn được trả về. right [outer] join Trả về tất cả đối tượng ở đầu phải của kết hợp. Nếu đối tượng ở đầu phải của kết hợp không có đối tượng nào trùng khớp (match) ở đầu trái của kết hợp thì nó vẫn được trả về. full join Trả về tất cả đối tượng ở cả hai đầu kết hợp, bất kể có hay không đối tượng trùng khớp ở đầu đối diện của kết hợp. Inner join fetch Được sử dụng để truy xuất một đối tượng kết hợp hoặc một tập hợp các đối tượng bất kể có hay không outer-join hoặc lazy property trên quan hệ. Loại kết hợp này không có trong SQL. Loại kết hợp mặc định được sử dụng là inner join. Muốn sử dụng loại khác ta phải xác định chính xác loại kết hợp trong mệnh đề kết hợp (left, right, full). Tất cả các loại kết hợp đều có loại tương ứng trong SQL, ngoại trừ inner join fetch. Kết hợp một lazy collection với inner join fetch sẽ làm cho collection này được trả về khi populated. Ví dụ: from Event e inner join fetch e.speakers Câu truy vấn này sẽ trả về tất cả các thực thể Event với các tập hợp của Speakers (nghĩa là một thực thể Event sẽ có một tập các Speaker tương ứng với Event đó). Xét sự kết hợp một đối tượng có quan hệ một-nhiều với một đối tượng cơ sở: from Event e join e.location l where l.name = :name Kết hợp thực thể Location với đối tượng Event cho phép truy vấn trên các thuộc tính của Location, và đạt được kết quả truy vấn hiệu quả hơn. Giải thích: Nếu không dùng phép kết hợp join này ta có thể có câu truy vấn sau: from Event e where e.location.name = :name and e.location.address.state = :state Vì ta phải duyệt qua các đối tượng hai lần, một lần cho tên của Location và một lần cho trạng thái (state) của Location, do đó trình biên dịch truy vấn sẽ kết hợp thực thể Location với Event hai lần. Kết hợp Location với Event trong mệnh đề FROM sẽ chỉ phải thực hiện phép kết một lần và truy vấn cũng thực hiện hiệu quả hơn. Các đối tượng trong phép kết cũng có thể được trả về trong mệnh đề SELECT của câu lệnh HQL. • Mệnh đề SELECT Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 49 Mệnh đề SELECT cho phép xác định một danh sách các giá trị trả về từ câu truy vấn. Giá trị trả về có thể là toàn bộ đối tượng, các thuộc tính xác định của đối tượng và giá trị dẫn xuất từ một truy vấn. Giá trị dẫn xuất bao gồm kết quả từ các hàm chức năng, như là hàm min(), max() và hàm count(). Một đặc điểm của HQL là khả năng trả về các đối tượng mới từ các giá trị được chọn. o Phép chiếu Phép chiếu là việc chọn các cột xác định của dữ liệu trả về từ một truy vấn. Giả sử thay vì trả về toàn bộ đối tượng Event trong câu truy vấn, ta chỉ muốn lấy tên của Event. Việc truy xuất toàn bộ đối tượng chỉ để lấy thuộc tính tên thì rất không hiệu quả. Thay vào đó, câu truy vấn chỉ cần truy xuất đến dữ liệu mong muốn: select e.name from Event e Câu truy vấn này trả về một danh sách các thực thể kiểu chuỗi chứa các tên của Event. Nếu muốn truy xuất hai thuộc tính, ví dụ như ngày bắt đầu và tên của Event: select e.name, e.startDate from Event e Mỗi phần tử trong danh sách trả về là một array kiểu Object (Object[]) chứa các giá trị xác định. Chiều dài của array Object[] bằng với số cột được yêu cầu truy xuất. Sau đây là một ví dụ về cách thức truy vấn và xử lý truy vấn trên nhiều thuộc tính Ví dụ: Session session = factory.openSession(); String query = " select e.name, e.startDate from Event e "; Query query = session.createQuery("query"); List results = query.list(); for (Iterator I = results.iterator(); i.hasNext();) { Object[] row = (Object[]) i.next(); String name = (String) row[0]; Date startDate = (Date) row[1]; // … } Lưu ý rằng các giá trị trong array Object[] có thứ tự giống với thứ tự các thuộc tính trong câu truy vấn. Array chứa các thực thể thuộc kiểu Object, không có giá trị thuộc kiểu cơ bản (gồm các kiểu như int, long, boolean…) có thể được trả về từ một truy vấn dạng này. Giới hạn này cũng vẫn tồn tại khi truy vấn một giá trị đơn, bởi vì một List không thể chứa các giá trị kiểu cơ bản. Một cách thông dụng để xử lý vấn đề này là dùng các đối tượng giản lược (summary object) chứa một tập con dữ liệu của đối tượng. Trong trường hợp ví dụ trên, một đối tượng giản lược sẽ chứa thuộc tính name và startdate của Event. Khi duyệt trên danh sách kết quả, ta sẽ cần một danh sách cho các đối tượng giản lược. Có một cách tốt hơn để giải quyết vấn đề trên. o Trả về các đối tượng mới Mệnh đề SELECT có thể được sử dụng để tạo ra các đối tượng mới, giữ các giá trị trong câu truy vấn. Xét ví dụ sau: Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 50 select new EventSummary(e.name, e,startDate) from Event e Danh sách kết quả sẽ được trả về theo các thực thể của đối tượng EventSummary. Dĩ nhiên class EventSummary phải có một constructor tương ứng với constructor được sử dụng trong câu lệnh HQL: EventSummary(String, Date). Phần trước đã trình bày về những thành phần chính của câu truy vấn HQL. Phần sau sẽ trình bày về các hàm tập hợp (aggregate functions) có sẵn trong HQL và cách chúng được sử dụng trong mệnh đề SELECT và WHERE. • Sử dụng các hàm Các hàm là các lệnh đặc biệt, trả về một giá trị được tính toán. Trong SQL có hai kiểu hàm: hàm kết hợp và hàm vô hướng (scalar). Các hàm vô hướng thường xử lý trên một giá trị đơn và trả về một giá trị đơn. Cũng có các hàm vô hướng không cần đối số, như hàm now() hoặc CURRENT_TIMESTAMP, cả hai đều trả về thời gian của hệ thống (timestamp) . Các hàm tập hợp xử lý trên một tập các giá trị trả về giá trị tổng kết (summary value). Hibernate hỗ trợ năm hàm tập hợp trong SQL thông dụng nhất, gồm: count (đếm phần tử trong tập hợp thỏa ràng buộc), avg (tính trị trung bình), min (tính trị nhỏ nhất), max (tính trị lớn nhất) và sum (tính tổng các giá trị). Các hàm này có chức năng tương tự như các hàm tương ứng trong SQL. Xét ví dụ sau: select count(e) from Event e Ví dụ này trả về số đối tượng Event có trong cơ sở dữ liệu. Để đếm số đối tượng Event và không đếm trùng các đối tượng giống nhau, sử dụng từ khóa distinct: select count(distinct e) from Event e Tất cả các hàm tập hợp đều trả về một đối tượng Integer. Để truy xuất kết quả, cách đơn giản nhất là lấy giá trị đầu tiên trong danh sách kết quả: Integer count = (Integer) session. find (“select count(distinct e) from Event e”).get(0); Xét một ví dụ khác: lấy tập hợp những người tham gia (Attendee) cho một sự kiện cho trước. Hiện nay để lấy được thông tin này thì code sẽ như sau: String query = “from Event e inner join fetch e.attendees where e.name = :name”; Query q = session.createQuery(query); q.setParameter(“name”, ”Meeting”); Event event = (Event) q.list().get(0); Set attendees = event.getAttendees(); session.close(); Có một cách khác ngắn hơn nhiều để đạt được tập hợp con. Hibernate cung cấp hàm elements(…) để trả về các thành phần của một tập hợp: select elements(e.attendees) from Event e where e.name = :name Câu truy vấn trả về một đối tượng List chứa các thực thể Attendee ứng với sự kiện Event. Nếu sử dụng phép kết hợp trong mệnh để FROM, ta có thể sử dụng alias trong phép kết hợp làm đối số của hàm. Câu truy vấn sau cũng tương đương với câu trên: Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 51 select elements(a) from Event e join e.attendees a where e.name =: name Các hàm cũng có thể được sử dụng trong mệnh đề WHERE. • Các thuộc tính có sẵn của HQL (HQL property) Các thuộc tính có sẵn của HQL dành cho các đối tượng trong câu truy vấn. HQL hỗ trợ hai thuộc tính đối tượng: id và class. Thuộc tính id cho phép truy xuất đến giá trị khóa chính của một đối tượng trong cơ sở dữ liệu. Bất kể ta đặt tên cho thuộc tính id trong đối tượng và trong định nghĩa ánh xạ là gì thì sử dụng id trong câu truy vấn HQL vẫn sẽ trả về giá trị khóa chính. Ví dụ, nếu có một class với thuộc tính id được đặt tên là objectId, ta vẫn có thể sử dụng thuộc tính id trong câu truy vấn HQL: from MyObject m where m.id > 50 Ta vẫn có thể sử dụng thuộc tính objectId nếu muốn. Có thể xem thuộc tính Id của HQL như một cách viết gọn cho giá trị khóa chính. Thuộc tính class cung cấp chức năng tương tự. Thuộc tính class giúp truy xuất đến tên class Java của các đối tượng trong cơ sở dữ liệu. Điều này đặc biệt có ích khi ta ánh xạ một phân cấp class trong cơ sở dữ liệu và chỉ muốn trả về các class thuộc một kiểu xácđịnh. Xét ví dụ sau để thấy thuộc tính class được sử dụng như thế nào. Ví dụ class Attendee có quan hệ với class Payment. Class Payment xác định cách Attendee sẽ trả tiền cho các Event. Payment có hai class con (subclass): CreditCardPayment và CashPayment. Câu truy vấn sau sẽ truy xuất được tất cả Attendee trả bằng tiền mặt: from Attendee a join a.payment p where p.class = de.laliluna.CashPayment Cũng giống như thuộc tính id, ta cũng có thể trả về thuộc tính class trong lệnh SELECT select p.id, p.class from Payment p; Câu truy vấn trả về tất cả các id và class cho đối tượng Payment trong một đối tượng List gồm các phần tử là array Object[]. Tuy nhiên, thuộc tính class không được trả về như là một thực thể của java.lang.Class. Thay vào đó, thuộc tính class là môt thực thể java.lang.String, có giá trị là giá trị được xác định trong thuộc tính discriminor- value (tạm dịch là giá trị phân biệt) trong định nghĩa ánh xạ. Thuộc tính class chỉ có trong phân cấp đối tượng. Nói cách khác là thuộc tính class chỉ có trong các đối tượng được ánh xạ với một discriminator-value. Nếu truy xuất thuộc tính class của một đối tượng không có discriminator-value sẽ nhận ngoại lệ QueryException báo rằng bộ phân tích truy vấn (query parser) không thể phân tích được thuộc tính class này. Các thuộc tính id và class có thể được sử dụng trong mệnh đề SELECT và WHERE. • Sử dụng biểu thức (expression) Các biểu thức được sử dụng để truy vấn các đối tượng có thuộc tính thỏa mãn các Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 52 tiêu chuẩn xác định. Được sử dụng trong mệnh đề WHERE của truy vấn, các biểu thức hỗ trợ hầu hết các toán tử thông dụng trong SQL. Tóm lại: Hibernate là một công nghệ mới giải phóng cho người phát triển code khỏi cơ sở dữ liệu quan hệ thực sự bên dưới. Người phát triển chỉ cần biết các class ánh xạ từ cơ sở dữ liệu bên dưới mà không phải làm việc với các bảng (table). Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 53 2. Áp dụng MDA vào quá trình phát triển ứng dụng Web 2.1. Các hướng tiếp cận hỗ trợ cho MDA 2.1.1. Pattern Một pattern là một giải pháp có thể sử dụng lại nhiều lần. Trước khi tạo ra một pattern ta cần phải hiểu kỹ về cấu trúc và mục đích của pattern đó. Rational XDE cung cấp một môi trường rất uyển chuyển cho việc thiết kế, tạo, kiểm tra, lập tài liệu, tổ chức và đóng gói pattern. Ta có thể chọn làm việc đồng thời trên nhiều chức năng trong quy trình phát triển pattern hoặc có thể làm chúng trong các bước riêng biệt. Ta có thể tạo hoàn chỉnh một pattern thiết kế trong cửa sổ dành riêng cho việc thiết kế pattern là Pattern Explorer và Pattern Properties. Tuy nhiên, ta cũng có thể thêm các thành phần thiết kế có cấu trúc trong cửa sổ thiết kế mô hình Model Explorer hoặc cửa sổ diagram. Mỗi pattern là duy nhất, do đó quy trình tạo pattern sẽ khác nhau cho mỗi pattern. Các hướng dẫn cơ bản (chung nhất cho mọi pattern) được cung cấp ở trên cho phép ta tạo ra các thành phần thiết yếu nhất cho một cấu trúc pattern. Ta có thể xây dựng các thủ tục (các bước thực hiện) để tinh chế tốt hơn các thuộc tính và cấu trúc của pattern. 2.1.2. Code template (code mẫu) Code template là một trong những giải pháp phần mềm giải quyết một vấn đề thường diễn ra trong một ngữ cảnh và cũng hỗ trợ cho đặc tính của Pattern. Pattern cung cấp sự mở rộng từ mô hình đến mô hình trong khi code template cung cấp sự mở rộng từ mô hình sang code. Code template tăng cường khả năng của Rational XDE bằng cách cho phép người sử dụng tạo thêm nhiều code hơn từ các mô hình XDE. Code template làm việc cùng với bộ tạo code bằng cách cung cấp thông tin code tạo ra cho một thành phần mô hình XDE cụ thể nào, ví dụ cho phần thân method. Tập hợp các thành phần mà code template được bind đến (ràng buộc vào) phụ thuộc vào ngôn ngữ hiện thực việc tạo code đó. Code template có thể được viết trong một ngôn ngữ lập trình xác định hoặc trong một ngôn ngữ script. Trong Rational XDE, code template có thể được viết bằng các ngôn ngữ sau: Scripted Template, Java, .NET, COM, External JavaScript Code template có thể tham chiếu các thành phần của mô hình XDE. 2.1.3. UML Profile – cơ chế mở rộng UML Nghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web 54 Mở rộng ứng dụng Web (Web Application Extention) cho UML cho phép ta mô tả các trang Web và các thành phần có ý nghĩa về kiến trúc khác ở trong mô hình bên cạnh các class chuẩn trong mô hình. Chỉ có phương pháp này ta mới có thể thể hiện chính xác toàn bộ hệ thống qua mô hình và có thể duy trì khả năng theo vết (traceability) cũng như khả năng tích hợp (intergrity). Một sự mở rộng cho UML (tức tạo ra một UML profile) thực hiện dưới dạng các stereotype, các tagged value và các ràng buộc (constraint). Kết hợp lại, cơ chế này cho phép c

Các file đính kèm theo tài liệu này:

  • pdfNghiên cứu và áp dụng công nghệ MDA, các framework hỗ trợ ứng dụng Web.pdf