text:
Trước khi bạn bắt đầu
Hướng dẫn này dành cho những người phát triển web muốn học cách sử dụng và kết hợp các dịch vụ web từ quan điểm của XML và xuất dữ liệu XML tới web. Điều đó có nghĩa là bạn đã biết về Java™, XML, SQL, việc phát triển web và các khái niệm cơ bản của các dịch vụ web. Sự hiểu biết về JDBC sẽ rất có ích. Nếu bạn cần nhớ lại các chủ đề đó thì hãy xem lại phần Các tài nguyên để có thêm thông tin.
Giới thiệu về loạt bài này
Bạn không thể thay đổi hoàn toàn trang web mà không nhảy vào một trang web mà ở đó cho phép bạn truy cập đến các dữ liệu của nó thông qua một API dựa trên các dịch vụ Web, hoặc sử dụng dữ liệu từ một trang khác thu được thông qua API dựa trên các dịch vụ web. Khi bạn xem xét ưu điểm của thông tin hiện có trong các ứng dụng của riêng bạn, điều đó không chắc là có sự ngạc nhiên lớn nào. Điều đó không chỉ là vấn đề thời gian trước khi ai đó bắt đầu kết hợp dữ liệu từ các hệ thống khác nhau để tạo ra vài thông tin trọn vẹn. Các ứng dụng này được gọi là các mashup. Các mashup là ứng dụng gần đây nhất trên web, từ các trang dựa trên cộng đồng tới các trang tìm kiếm chuyên biệt.
Hầu hết các Mashup đều rất hữu ích, chúng có điểm chung là được phát triển với tập các dịch vụ riêng biệt. Nếu một trong các dịch vụ thay đổi hoặc nếu sở thích của bạn với các loại dịch vụ thay đổi thì bạn sẽ có nhiều việc phải làm.
Mục đích của các bước hướng dẫn này là tạo nhanh một ứng dụng mashup để người dùng có thể thêm hoặc hủy các dịch vụ một cách tùy ý và hệ thống sẽ không biết được người dùng đã làm gì với chúng. Loạt bài tiến hành như sau:
Trong phần 1, Nicholas Chase đã giới thiệu các khái niệm của mashup, đã chỉ ra các mashup làm việc như thế nào và chỉ dẫn bạn quá trình xây dựng một phiên bản đơn giản như thế nào (xem Các tài nguyên). Bạn cũng đã nhận thấy các vấn đề về hiệu suất quan trọng khi thực hiện gọi hàng tá các trang web tiềm ẩn.
Trong phần 2, bạn giải quyết vài vấn đề đó bằng cách sử dụng khả năng pureXML™ mới của IBM® DB2® để xây dựng một nơi lưu trữ XML, nơi này lưu trữ các kết quả của các yêu cầu trước đó và cũng cho phép bạn lấy thông tin đặc trưng.
Cuối cùng, bạn sẽ cần sử dụng các bản thể luận (ontology) hoặc các từ vựng mà các khái niệm và mối quan hệ giữa chúng là xác định, do đó trong phần 3 bạn bắt đầu quá trình đó bằng việc tìm hiểu về RDF và RDFS, hai thành phần khóa của Web Ontology Language (OWL). Các vấn đề này ta sẽ thảo luận trong phần 4. Ở phần 5, chúng tôi đưa ra các bản thể luận mà bạn đã tạo ra ở phần 4 và sử dụng chúng để cho phép người dùng thay đổi các nguồn thông tin.
Trong phần 6, những điều thú vị sẽ tăng lên. Tại đó, bạn có một ứng dụng đang thực thi và khung làm việc (framework) trong đó, do vậy hệ thống có thể sử dụng tùy ý suy dẫn ngữ nghĩa để hiểu các dịch vụ. Trong phần này, bạn đưa ra kiểm soát người dùng, cho phép họ ánh xạ các dịch vụ mới vào bản thể luận và nhấc hoặc chọn dữ liệu được dùng với một mashup tùy ý.
Giới thiệu về bài viết này
Bài viết này là phần 2 trong một loạt bài gồm 6 bài viết về sử dụng và kết hợp các dịch vụ web như thế nào từ quan điểm của XML và xuất dữ liệu lên web. Trong phần 1, bạn đã học về việc lựa chọn XML từ các dịch vụ sử dụng REST, nhưng các khái niệm về các dịch vụ SOAP là tương tự (xem Các tài nguyên). Bạn sẽ tiếp tục loạt bài này với việc lưu trữ các dữ liệu XML đó vào một cơ sở dữ liệu, tạo ra một bộ đệm lưu trữ các kết quả truy vấn. Hơn nữa bạn sẽ lấy được các dữ liệu đã lưu trữ để sử dụng trong các ứng dụng Java của bạn.
Sau bài viết này, bạn sẽ học cách cài đặt một máy chủ cơ sở dữ liệu (database server) như thế nào và sửa đổi nó để nhận dữ liệu cũng như là viết các câu truy vấn như thế nào để gắn một dữ liệu XML vào một cột XML một cách rõ ràng.
Bạn sẽ học về:
- Cài đặt DB2 Enterprise Edition
- Tạo một cơ sở dữ liệu DB2 9 mới, cấu hình nó để gắn với XML
- Tạo một bảng cơ sở dữ liệu sử dụng kiểu cột XML
- Chọn thông tin đã lưu dưới dạng XML trong cơ sở dữ liệu quan hệ sử dụng XPath
- Viết các câu truy vấn XML XQuery
- Viết các câu truy vấn SQL và XQuery lai ghép
Hướng dẫn này sử dụng Java, nhưng các khái niệm là giống nhau với bất kì ngôn ngữ lập trình hoặc hệ điều hành nào.
Các điều kiện tiên quyết
Theo đoạn mã trong hướng dẫn này, bạn cần phải cài đặt và kiểm tra các phần mềm sau đây:
- IBM® DB2® 9 (thường được gọi là "Viper"): Cơ sở dữ liệu quan hệ này cũng chứa đựng những khả năng XML quan trọng, bạn sẽ cần chúng. Bạn có thể tải về một phiên bản dùng thử của DB2 9 hoặc DB2 Enterprise 9 hoặc DB2 Express-C 9 một phiên bản miễn phí của máy chủ dữ liệu DB2 Express 9.
- Apache Tomcat hoặc một máy servlet khác: Bạn sẽ xây dựng các ứng dụng web sử dụng các servlet, vì vậy bạn cần có một máy servlet chẳng hạn như Apache Tomcat. Nếu bạn chọn xây dựng ứng dụng trên một môi trường khác, hãy chắc chắn rằng bạn đã có nó trong tay. Tải về apache-tomcat-5.5.17.zip và cài đặt vào một thư mục với tên thư mục không chứa dấu cách.
- Java: Apache Tomcat 5.5 yêu cầu Java 1.5 hoặc cao hơn. Hãy tải về J2SE SDK.
- Hãy làm cho mọi việc dễ dàng hơn, bạn có thể sử dụng một IDE chẳng hạn như Eclipse hoặc IBM Rational Web Developer™. Bạn có thể tải về Eclipse ở địa chỉ Eclipse.org, tải về một bản dùng thử Rational Web Developer ở địa chỉ Rational Web Developer, hoặc bạn sử dụng một môi trường phát triển mà bạn thích. Tuy nhiên bạn sẽ không làm những gì quá sức với trình biên dịch và việc thực thi.
Đi một ngày đàng học một sàng khôn
Trước khi chúng ta bắt đầu việc tạo các nơi lưu trữ, hãy kiểm tra dữ liệu hiện có. Bạn nên hiểu về bối cảnh của XML và các cơ sở dữ liệu.
Truyền DB2 9 vào ứng dụng
Các dịch vụ web là tiện ích cho việc xem thông tin một cách nhanh chóng. Ngày nay, nhiều trang web cho người dùng truy cập trên giao diện hạn chế, đó là trình duyệt. Bây giờ họ có thể truy cập chúng thông qua các dịch vụ web. Các dịch vụ web được phổ biến và được sử dụng trong hầu hết các ứng dụng thứ cấp. Các ứng dụng này gọi là mashup. Và các ứng dụng này nổi lên ở bất cứ đâu thông tin có thể giúp giải quyết một vấn đề thích hợp.
Trong phần 1, bạn đã gặp mashup và đã bắt đầu lấy thông tin từ nhiều hơn một vị trí nào đó, sửa đổi tập các dữ liệu vào các ứng dụng tùy ý của bạn (xem Các tài nguyên). Bây giờ chúng ta muốn lưu tạm thời vào bộ đệm các tập dữ liệu để sử dụng chúng một cách hợp lý. Tại sao phải lưu dữ liệu vào bộ đệm? Một lí do quan trọng đó là các dịch vụ mà bạn kết nối có một lượng lớn các yêu cầu ở mọi thời điểm. Bạn lấy các dữ liệu này miễn phí nên để lịch sự thì bạn giảm số lượng yêu cầu mà bạn gửi đi trong suốt phiên làm việc của người dùng trên ứng dụng của bạn. Bởi vì các ứng dụng không yêu cầu dữ liệu thời gian thực, bạn có thể làm giảm tải băng thông một cách rõ ràng. Bạn cũng có thể lợi dụng kho dữ liệu cục bộ, làm giảm thời gian cho truy vấn thực hiện (và trong hầu hết trường hợp là nhiều truy vấn).
Để đạt được các mục tiêu đó, bạn sẽ tận dụng máy chủ DB2 và các đặc tính mới của XML mà IBM đã giới thiệu trong phiên bản 9 cũng như vài mẹo Java để quản lý việc lưu trữ tạm thời của bạn.
Dữ liệu quan hệ với dữ liệu XML
Một trong những lợi ích lớn nhất của việc sử dụng cơ sở dữ liệu quan hệ đó là tốc độ mà ở đó bạn có thể truy cập và thao tác dữ liệu. Các mô hình hệ thống quản lý cơ sở dữ liệu quan hệ RDBMS có thể phân tích lượng lớn dữ liệu trong các bảng qua vài cơ sở dữ liệu và trả về các truy vấn gần như ngay lập tức. Chẳng hạn bạn muốn biết "có bao nhiêu nắp cống đã được đặt ở Minneapolis MN bởi các nhà thầu khác nhau vào tháng chín trong vòng 5 năm?". Nếu bạn biết viết truy vấn và bạn có các cơ sở dữ liệu bạn có thể có câu trả lời trong nháy mắt. Một trở ngại đó là bạn cần bản thân dữ liệu và truy cập tới nó. Nhưng dữ liệu đã chờ sẵn trong cơ sở dữ liệu và bạn sẽ phải hiểu đưa nó tới nơi bạn cần như thế nào và hiểu nó theo cách của bạn như thế nào.
Lưu trữ dữ liệu dưới định dạng đọc được và có khả năng truyền từ nơi này đến nơi khác là một chức năng của XML. Khi dữ liệu được lưu trữ trong một cơ sở dữ liệu dưới dạng các bảng giống như bảng tính, nó thường được định dạng cho ứng dụng cụ thể. XML cho phép bạn lưu trữ dữ liệu ở phần mở rộng, con người có thể đọc được định dạng, điều đó chuẩn bị sẵn sàng cho sự trao đổi giữa các ứng dụng với con người. Bạn có thể sắp đặt tất cả các cách để phân chia dữ liệu và mang nó vào các ứng dụng. Ở đó bạn có thể bắt đầu thao tác lại dữ liệu. Đây chính là nền tảng để xây dựng khối mashup của bạn, khả năng tổ hợp dữ liệu từ hai ứng dụng rất khác nhau, cấu trúc lại nó và tạo các biến thể của riêng bạn.
Những thách thức mà bạn phải đối mặt là làm thế nào để kích hoạt tính năng XML để có thể xử lý một số các phân tích phức tạp hơn và làm thế nào để tận dụng lợi thế của máy chủ DB tốc độ cao?
Hầu hết các cơ sở dữ liệu quan hệ cố gắng xử lý dữ liệu XML từ đầu. Nhưng hầu hết các lần, các kỹ thuật của chúng có một chút hỗn độn, bao gồm việc lưu trữ dữ liệu văn bản hoặc phá vỡ nó vào nhiều bảng. Một phần của vấn đề liên quan đến dữ liệu XML khứ hồi (round tripping), hoặc lấy lại dữ liệu từ cơ sở dữ liệu theo cấu trúc giống với trước khi lưu trữ và phần khác liên quan đến việc bạn sử dụng các truy vấn quan hệ để truy cập dữ liệu đã được cấu trúc XML.
Mặt khác, các cơ sở dữ liệu XML nguyên gốc thường lưu trữ XML trong cấu trúc chính xác ở chỗ mà chúng nhận được. Các cơ sở dữ liệu XML cũng cung cấp truy cập đến dữ liệu sử dụng ngôn ngữ truy vấn được thiết kế đặc biệt cho XML như XPath, XQuery và XUpdate.
Vì bạn đang làm việc với dữ liệu XML như là một phần của ứng dụng, bạn thực sự cần có khả năng về cơ sở dữ liệu XML nguyên thủy. May thay, bạn có pureXML.
Dữ liệu XML lưu trữ trong DB2
pureXML là tên thuộc tính cho các bảng DB2. Các bảng này được thiết kế
để lưu các tài liệu XML được tổ chức tốt trong các cột, cùng với các
cột chứa dữ liệu quan hệ. Giống như các kiểu khác nhau của dữ liệu
quan hệ nhị phân, chẳng hạn như
LONG,
VARCHAR, hoặc
LOB,
được lưu trữ tách biệt với các nội dung khác của bảng, dữ liệu XML
được lưu trữ trong các cột của bảng có kiểu XML ở các đối tượng lưu
trữ XML mở rộng. Để sử dụng sức mạnh của các máy truy vấn của DB2 để
quản lý dữ liệu, bạn tách riêng XML với dữ liệu quan hệ mà bạn dùng để
chỉ số hóa nó. Một khi bạn lưu trữ XML và dữ liệu chỉ số quan hệ của
nó, bạn có thể truy cập nó qua một ngôn ngữ truy vấn đặc biệt.
XQuery là ngôn ngữ riêng của XML mà nó có thể truy cập dữ liệu XML sử dụng các biểu thức XPath thay vì SQL. Nó là thành quả của World Wide Web Consortium, bên cạnh XPath 2.0, trong những năm vừa rồi và đã đạt đến điểm mà các sản phẩm chủ đạo như DB2 bắt đầu hỗ trợ cho nó.
XQuery tổ hợp các thủ tục đơn giản (chẳng hạn như vòng lặp) với XPath một cách linh hoạt và mạnh mẽ cho việc lựa chọn và vận chuyển dữ liệu mà bạn không thể thực hiện được với chỉ XPath.
Bạn định hoàn thành cái gì
Trong phần 1, bạn đã tạo ra một ứng dụng gọi tới một số dịch vụ, thu nhận dữ liệu từ chúng như một luồng XML và chuyển đổi dữ liệu đó sang dạng HTML để hiển thị trên trình duyệt (xem Các tài nguyên). Bởi vì đó là một mashup nên bạn đang xử lý các dịch vụ. Thực tế, trong trường hợp các dịch vụ con, bạn phải thực hiện hàng tá hoặc hơn các truy vấn cho một trang. Nếu bạn chạy ví dụ ở phần 1, bạn có thể khó chịu vì độ dài của các truy vấn đó như thế nào.
Trong bài viết này, bạn sẽ tạo ra một hệ thống để lưu tạm thời các kết quả trả về từ các dịch vụ khác nhau mà bạn sử dụng. Dữ liệu sẽ chứa thông tin trên URL, thường là yêu cầu dữ liệu, ngày tháng, thời gian yêu cầu được thực hiện cũng như các dữ liệu thực tế trả ra cho yêu cầu.
Trong servlet, trước tiên bạn sẽ kiểm tra cơ sở dữ liệu này, và nếu dữ liệu không tồn tại bạn sẽ yêu cầu một bản sao mới nhất và lưu nó vào cơ sở dữ liệu trong lần tiếp theo.
Bằng cách làm này, bạn có khả năng chuyển một trang có thể chứa một tá hoặc hơn các yêu cầu web (và làm trong một phút hoặc thậm chí hơn) thành các kết quả nhanh chóng. Điều đó cũng dễ dàng hơn nhiều trên các dịch vụ tìm kiếm.
Cài đặt
Khi bạn thêm vào một máy chủ DB2 thành một hỗn hợp, bạn sẽ cài "deamon" trên một máy chủ thuận tiện nhất. Bạn nên có Tomcat và Apache được cài đặt sẵn, nhưng bạn cũng sẽ cần kết nối Tomcat với cơ sở dữ liệu sử dụng JDBC.
Cài đặt DB2
Tải về phiên bản dùng thử DB2 9 (xem Các điều kiện tiên quyết). Bạn có thể đăng nhập vào developerWorks và truy cập đến phiên bản beta DB2 mới nhất miễn phí với khả năng hỗ trợ pureXML để lưu trữ XML. Chúng ta sẽ sử dụng các đặc tính mới này để lưu trữ các đối tượng dữ liệu từ các truy vấn của ứng dụng.
Một khi bạn đã tải về phần mềm, hãy giải nén tệp ZIP và đặt tệp Setup.exe vào thư mục db2\ESE\image. Nhấn đúp chuột và bắt đầu quá trình cài đặt với thuật sỹ cài đặt (setup wizard). Cửa số đầu tiên là DB2 Setup Launchpad (xem Hình 1).
Hình 1. Setup Launchpad
Danh sách bên trái ghi vài lựa chọn, chọn Installation Prerequisites và Install a Product. Các lựa chọn còn lại chứa những chuyển đổi từ các sản phẩm khác sang và đưa ra các chú thích cho phiên bản DB2 này. Nếu đây là cài đặt mới, thì sự chuyển đổi không có tác dụng. Nhưng nếu muốn, bạn hãy tiếp tục và đọc các chú thích đưa ra để có các thông tin cơ bản về phiên bản DB2 này.
Bắt đầu với Installation Prerequisites, đó là các cài đặt quyết định thành công của DB2. Danh sách đó nằm ngoài phạm vi của bài viết này. Bạn hãy cài đặt các thủ tục cập nhật và vá hệ thống. Chúng tôi khuyên bạn theo dõi các liên kết đã cung cấp ở Setup Launchpad. Các liên kết sẽ chỉ dẫn cho bạn các thông tin trong phạm vi của yêu cầu. Các giới hạn thực hiện ở đây chính là việc chắc chắn rằng bạn cập nhật và hỗ trợ tối thiểu các yêu cầu phần cứng như không gian đĩa và RAM. Một khi bạn đã xác nhận rằng máy chủ của bạn đáp ứng được hãy nhấn chọn Install a Product và bắt đầu cài đặt
Hình 2. Cài đặt một Product
Khi bạn chọn Install a Product từ thực đơn bên trái, chương trình cài đặt đưa cho bạn lựa chọn để tạo một cài đặt mới của máy chủ (server) hoặc máy khách (client). Với các mục tiêu của bài viết này, bạn sẽ cài đặt cả hai, cho bạn chức năng máy chủ và có khả năng quản trị máy chủ của bạn sau khi nó được cài đặt. Bắt đầu với Enterprise Server. Khi cửa sổ cài đặt installation Wizard bắt đầu, bạn chỉ cần nhấn Next cho đến khi có hợp đồng đăng ký (license agreement). Nếu hợp đồng phù hợp với bạn hãy chấp nhận và nhấn Next lần nữa.
Tiếp theo bạn sẽ lựa chọn cài đặt đặc trưng (typical), rút gọn (compact) hoặc tùy ý (custom). Chọn cài đặt typical và nhấn Next để di chuyển đến cửa sổ tiếp theo.
Hộp thoại tiếp theo hỏi bạn nếu muốn cài đặt, hãy lưu lại các cài đặt phản hồi từ cửa sổ wizard vào một tệp để sử dụng sau. Việc này có lợi khi bạn cài đặt các server tương tự hoặc nếu bạn định sử dụng các đặc tính môi trường cơ sở dữ liệu phân hoạch của DB2. Ngay bây giờ, bạn chọn Install DB2 Enterprise Server Edition và nhấn Next.
Ở hộp thoại tiếp theo trong hình 3, hãy nhập vào đường dẫn nơi mà bạn muốn cài đặt server và nhấn Next, nếu bị nhắc bạn hãy chọn một tên cho việc cài đặt cơ sở dữ liệu. Trừ phi có lí do nào đó còn nếu không bạn có thể chấp nhận tên mặc định là DB2_01 và thực hiện cài đặt mặc định này trên máy tính.
Hình 3. Đặt hộp thoại thông tin người dùng
Nếu bạn đang dùng Windows™ XP hoặc NT, bước cài đặt tiếp theo yêu cầu tên miền (Domain) mà tài khoản người dùng của bạn sẽ là thành viên của tên miền đó. Nhưng bạn có thể sử dụng một người dùng hiện có. Cài đặt này sẽ tạo ra một người dùng phục vụ cho mục đích đó, tùy theo bất kỳ nhu cầu của bạn có nằm ngoài phạm vi của bài viết này. Trong bài viết này sử dụng các lựa chọn mặc định.
Chúng ta đang cài đặt các công cụ phát triển ứng dụng trên cùng một máy, nên hãy tiếp tục chọn None - user local user account cho Domain và hủy bỏ username mặc định. Nhập và xác nhận lại mật khẩu và chắc chắn rằng hộp kiểm ở cuối đã được kiểm tra. Nhấn Next.
Bạn sẽ được hỏi bạn muốn tạo ra máy chủ gì. Hãy sử dụng mặc định của DB2 và nhấn Next.
Bạn có thể bỏ qua hộp các công cụ Prepare the DB2 tools catalog bằng cách không chọn gì ở hộp thoại tiếp theo và nhấn Next.
Bạn không cần khai báo e-mail. Hãy xóa hộp kiểm Set up your DB2 server to send notifications và nhấn Next.
Để bảo mật dịch vụ DB2 hơn, bạn có thể kích hoạt người dùng và các nhóm quản trị như là những người nắm giữ hợp lệ duy nhất đối với dữ liệu DB2 đã lưu trữ và phục vụ. Điều đó là không cần thiết trong bài học này nhưng nó sẽ không làm tổn hại vì vậy hãy để nguyên và nhấn Next.
Cuối cùng bạn được xem hộp thoại với tất cả các lựa chọn bạn đã làm. Nhấn Finish để hoàn tất việc cài đặt.
Cài đặt JDBC
Để truy cập DB2 qua JDBC, bạn cần thực hiện một số phân lớp, bao gồm DB2 JDBC driver để hoạt động với Tomcat servlet. Bạn có thể thực hiện việc đó theo một số cách, bao gồm việc thêm vào nó một ứng dụng riêng của bạn. Cách khác là làm cho nó có thể dùng được với tất cả các ứng dụng chạy trên Tomcat. Để làm được điều đó hãy sao chép tệp <DB2_HOME>/sqllib/java/db2java.zip vào thư mục Tomcat's common/lib. Mặc dù đó là tệp zip chứ không phải tệp JAR, máy chủ sẽ tìm ra nó.
Lưu trữ XML
Bây giờ hãy xem cách DB2 lưu trữ thông tin XML trong cơ sở dữ liệu
Tạo cơ sở dữ liệu
Trước tiên bạn cần một cơ sở dữ liệu để lưu trữ các đối tượng XML đã trả về. Với các ưu điểm của thuộc tính XML trên DB2, bạn nên cân nhắc kỹ lưỡng để định hình một cơ sở dữ liệu mới. Vì vậy chúng ta sẽ thực hiện từng bước quá trình tạo cơ sở dữ liệu này
Trên thanh taskbar của Windows, trong khay hệ thống có một biểu tượng của máy chủ DB2 với tên là DB2.
Nhấn phải vào biểu tượng đó và chọn DB2 Control Center để mở DB2 Control Center. Ở bên phải, bạn sẽ thấy một nhánh thực đơn với hai lựa chọn là All Systems và All Databases. Nhấn phải chuột vào All Databases chọn Create Database>Standard. Việc này sẽ mở ra cửa sổ thuật sỹ tạo cơ sở dữ liệu được trình bày trong Hình 4.
Hình 4. Thuật sỹ (wizard) tạo cơ sở dữ liệu, bước 1
Tại đó, bạn được hỏi tên cơ sở dữ liệu là gì và bạn muốn lưu trữ nó ở đâu. Với bài viết này, bạn dùng mashup_1 cho tên và định danh của cơ sở dữ liệu. Bạn có thể thêm vào bất kỳ tên chú thích nào bạn muốn.
Tiếp theo hãy chọn nơi bạn sẽ lưu trữ các tệp cơ sở dữ liệu. Các cơ sở dữ liệu có thể chứa một lượng rất lớn dữ liệu. Hãy chọn nơi mà có thể quản lý được khối lượng dữ liệu đó của ứng dụng của bạn. Để phát triển ứng dụng này bạn chỉ lần khoảng 10-20MB bộ nhớ, nhưng cũng có thể tăng thêm ở một môi trường lớn. Bây giờ hãy chọn một nơi có không gian nhớ lớn hơn 10MB để có thể dùng được và tạo một thư mục ở đó. Gõ vào đường dẫn thư mục ở trường Default path. Bạn có thể nhấn vào Browse và chọn một thư mục theo cách đó.
Nhấn vào hộp kiểm Enable database for XML. Hộp này yêu cầu bạn cài đặt kiểu mã là UTF-8. Đó là khóa cho các yêu cầu của bạn.
Hãy giữ các cài đặt mặc định còn lại và nhấn Next (Xem Hình 5).
Hình 5. Thuật sỹ tạo cơ sở dữ liệu, bước 2
Trình cài đặt sẽ hỏi bạn nơi lưu trữ dữ liệu cho DB một lần nữa. Giữ nguyên hộp kiểm Use the database path as a storage path và nhấn Next (Xem Hình 6).
Hình 6. Thuật sỹ tạo cơ sở dữ liệu, bước 3
Bạn gặp một chọn lựa quan trọng cho cơ sở dữ liệu mới, đó là sự địa phương hóa (locale settings). Để các bản XML hoạt động, chúng yêu cầu bảng mã UTF-8. Bạn có thể chọn bất kỳ mã quốc gia nào nhưng bạn phải chọn UTF-8 ở danh sách đổ xuống Code set. Để nguyên mục Collating Sequence với các giá trị mặc định của nó và nhấn Next (Xem Hình 7).
Hình 7. Thuật sỹ tạo cơ sở dữ liệu, bước 4
Cuối cùng bạn sẽ hoàn tất được việc cài đặt với màn hình tổng hợp. Hãy nhấn nút Finish và đợi trong giây lát để hệ thống tạo ra các tệp khởi tạo và bắt đầu các tiến trình với cơ sở dữ liệu mới của bạn. Khi cơ sở dữ liệu được hoàn thành, bạn sẽ tìm thấy nó ở cây All Databases. Bạn có thể mở rộng mashup_1 và nhìn thấy các thành phần.
Bây giờ bạn đã có một nơi cho XML, bạn cần định dạng nó để chứa dữ liệu.
Tạo bảng
Ở phần 1, bạn đã kết nối với hai dịch vụ web Yahoo! News, Technorati và YouTube, để tập hợp dữ liệu XML và sửa đổi nó đưa vào cơ sở dữ liệu của bạn (xem Các tài nguyên). Hai dịch vụ này cung cấp các định dạng dữ liệu rất khác nhau nhưng bạn sẽ lưu tất cả chúng vào cùng bảng cơ sở dữ liệu. Chọn Tools>Command Editor trên ứng dụng Control Center. Theo thường lệ, cách nhanh nhất là sử dụng dòng lệnh và thực hiện các lệnh trên đó. Trong Command Editor, chèn đoạn mã trong Ví dụ 1 vào.
Ví dụ 1. Tạo bảng queryResults
connect to MASHUP_1; create table queryresults (id INT generated always as identity, requestdate TIMESTAMP, query XML)
Sau khi bạn nhập đoạn mã vào cửa sổ Command Editor, nhấn Execute và chờ thông báo "The SQL command completed successfully" thể hiện câu lệnh SQL đã hoàn thành.
Cột id là khóa chính và cột requestdate là cột quan hệ đặc thù biểu diễn ngày giờ của truy vấn gốc. Mặt khác, cột query là một giá trị XML. Cấu trúc của nó biến đổi dựa trên dữ liệu được trả về cho truy vấn. Ví dụ, bạn có thể có hai dòng cơ sở dữ liệu khác nhau như trong Ví dụ 2.
Ví dụ 2. Các dòng cơ sở dữ liệu mẫu
1, 2006-07-25-13.26.46, <?xml version="1.0" encoding="ISO-8859-1"?> <tv source-info-url="http://labs.zap2it.com/" source-info-name="TMS Data Direct Service" generator-info-name="XMLTV" generator-info-url="http://www.xmltv.org/"> <programme start="20060714043000 -0400" stop="20060714050000 -0400" channel="I21883.labs.zap2it.com"> <title lang="en">Flintstones</title> <sub-title lang="en">The Gravelberry Pie King</sub-title> <desc lang="en">Fred gets fired and enters the pie-baking business.</desc> <credits> <actor>Alan Reed</actor> <actor>Jean Vander Pyl</actor> <actor>Mel Blanc</actor> <actor>Gerry Johnson</actor> <actor>Don Messick</actor> </credits> <date>19651112</date> <category lang="en">Children</category> <category lang="en">Animated</category> <category lang="en">Series</category> <episode-num system="dd_progid">EP001648.0149</episode-num> <episode-num system="onscreen">65149</episode-num> <subtitles type="teletext" /> <rating system="VCHIP"> <value>TV-G</value> </rating> </programme> <programme start="20060714050000 -0400" stop="20060714053000 -0400" channel="I21883.labs.zap2it.com"> <title lang="en">Dastardly & Muttley</title> <sub-title lang="en">Muttley On the Bounty</sub-title> <category lang="en">Children</category> <category lang="en">Animated</category> <category lang="en">Series</category> <episode-num system="dd_progid">EP001168.0006</episode-num> <episode-num system="onscreen">6901</episode-num> <rating system="VCHIP"> <value>TV-G</value> </rating> </programme> </tv> 2, 2006-07-25-13.38.46, <tapi version="1.0"> <document> <result> <url>http://www.chaosmagnet.com</url> <inboundblogs></inboundblogs> <inboundlinks>25</inboundlinks> <rankingstart>0</rankingstart></result> <item> <weblog> <name>Gary Said... ( The blog of Gary LaPointe )</name> <url>http://garysaid.com</url> <rssurl>http://garysaid.com/index.rdf</rssurl> <atomurl></atomurl> <inboundblogs>60</inboundblogs> <inboundlinks>2161</inboundlinks> <rank></rank> <lastupdate>2006-07-24 20:26:25 GMT</lastupdate> </weblog> <nearestpermalink>http://garysaid.com</nearestpermalink> <excerpt>Doug Dave (goodness) Angela (fluid) Tonya Martha Racheline Heather (dooce) ZuDfunck Ryan (fait) Eleanor alisa Kristin Elizabeth Sherri Meg Jacqueline Melissa (geek) James (american) Nicholas Lorna Evie Rachael Kachina Jeff (geekable) Tim Samantha SarahB Melissa (stars) David Kates Christine (pink) Kristine Psychbloke KelliDiane Clancy Molly.com Ryan (rant) Todd Nikita</excerpt> <linkcreated>2006-07-14 19:59:03 GMT</linkcreated> <linkurl>http://www.chaosmagnet.com/blog/</linkurl> </item> </document> </tapi>
Cho dù các dòng đều có cấu trúc cơ sở dữ liệu như nhau, không có hạn chế nào áp đặt cho cấu trúc XML được chứa trong các cột truy vấn.
Nhưng đôi khi đó không phải là những gì bạn muốn.
Dữ liệu hợp lệ
Các chuyên gia cơ sở dữ liệu đôi khi lo lắng về chất lượng dữ liệu khi dùng XML vì tính tự nhiên linh hoạt của nó. Do chúng ta có thể lưu trữ bất kỳ tài liệu XML nào vào bất kỳ cột nào được xác định bởi một kiểu dữ liệu XML mới trong DB2, nên bạn có thể dễ dàng rơi vào hậu quả là các cấu trúc dữ liệu XML bị thay đổi hoặc mâu thuẫn với sự logic ứng dụng của bạn. Nhà cung cấp dữ liệu có thể thay đổi cấu trúc của XML đầu ra mà không hề thông báo cho bạn. Mashup của bạn dùng ba nguồn dữ liệu khác nhau với ba cấu trúc tệp khác nhau và ngay lập tức sự thay đổi thể hiện trên bản thân nó. Trong khi bạn đang cân nhắc tạo ra một kết quả trong một cột XML chứa các dữ liệu khác nhau, DB2 cho phép bạn có thể liên kết một lược đồ với một cột cơ sở dữ liệu và cho phép chèn hoặc cập nhật dữ liệu một cách hợp lệ trước khi thêm nó vào cơ sở dữ liệu.
Trước khi bạn có thể làm cho dữ liệu trong bảng XML thành hợp lệ, bạn cần định nghĩa một lược đồ XML mà chỉ ra các thành phần XML, thứ tự của chúng và kiểu dữ liệu, ... có thể chấp nhận được. Bạn có thể tạo một lược đồ XML theo nhiều cách, và các nhà cung cấp dữ liệu đôi khi sẽ cung cấp một liên kết tới một lược đồ XML trong tài liệu XML của họ. Các đặc tả của một lược đồ XML nằm ngoài phạm vi của bài viết này, vì vậy hãy chuyển đến bước tiếp theo và đăng kí lược đồ XML hợp lệ của bạn (Xem Ví dụ 3).
Ví dụ 3. Đăng kí một lược đồ XML
connect to another database; register xmlschema 'http://mysample.org' from 'C:/XMLFILES/bigxmlfile.XSD' as user1.mysample complete;
Trong Command Editor, kết nối đến cơ sở dữ liệu và đưa ra lệnh để đăng kí cho bigxmlfile.xsd như là một lược đồ với tên user1.mysample. Thao tác này được lưu lại kho bên trong của DB2 dưới lược đồ SQL có tên user1 và lược đồ XML có tên mysample. Mệnh đề complete cho biết DB2 hoàn thành việc đăng kí và thực hiện lược đồ với dữ liệu hợp lệ đã được chèn vào bảng user1.
Sự hợp lệ không tự động mà sẽ yêu cầu bạn
chỉ rõ cơ sở dữ liệu hợp lệ với các lược đồ của bạn khi bạn dùng câu
lệnh INSERT. Khi chèn tệp XML vào một trường XML bạn sẽ cần dùng hàm
XMLVALIDATE(). Hàm này chỉ ra lược đồ
đã đăng kí trước đó hợp lệ với cái gì. Nếu tệp không phù hợp với lược
đồ, cơ sở dữ liệu trả về một lỗi thay vì thêm một dòng vào cơ sở dữ
liệu.
Vì bạn có thể chọn một lược đồ ở thời điểm chèn, bạn có thể dùng hàm này để hợp lệ dữ liệu với mỗi dịch vụ khác. Nhưng chúng ta sẽ để nó như là một bài tập cho người đọc.
Chèn XML sử dụng SQL
Giờ bạn đã có cấu trúc mẫu cho dữ liệu của mình để tập trung vào nó. Bạn có thể thực hiện câu lệnh INSERT trước tiên để đặt dữ liệu vào. Bạn sẽ dùng SQL để chèn dữ liệu vào bảng, từ đó bạn sẽ không thực thi bất kì thao tác nào trên đó cho đến khi nó đã đúng vị trí. Để làm điều này bạn dùng lại Command Editor và gửi một truy vấn SQL tới máy chủ có chứa các tệp XML của mình và đặt nó vào bảng.
Ví dụ 4. Chèn câu trả lời Yahoo!
connect to MASHUP_1; connect to MASHUP_1; INSERT INTO queryResults (requestdate, query) VALUES(CURRENT TIMESTAMP,XMLPARSE(document cast('<queryData><queryType>REST</queryType> <queryUrl>http://api.search.yahoo.com/NewsSearchService/ V1/newsSearch?appid=mashupid&type=all&query=New+York </queryUrl> <result> <Title>Star Wars force falls for Hasbro</Title><Summary>Falling sales of lightsabers and other Star Wars merchandise has dented US toymaker Hasbro's revenues.</Summary><Url>http://news.bbc.co.uk/go/rss/- /1/hi/business/5212750.stm</Url><ClickUrl>http://news.bbc.co.uk /go/rss/ -/1/hi/business/5212750.stm</ClickUrl><NewsSource>BBC News</NewsSource><NewsSourceUrl>http://news.bbc.co.uk/ </NewsSourceUrl><Language>en</Language><PublishDate> 1153835696</PublishDate><ModificationDate>1153835698 </ModificationDate></result></queryData>' as clob) preserve whitespace))
Nhìn bề ngoài, đây là một truy vấn SQL chuẩn, chỉ rõ các cột và các giá trị. Giá trị thứ nhất, giá trị TIMESTAMP là ngày giờ hiện tại. Giá trị thứ hai, query, là một giá trị XML. Để chèn vào, bạn cần có một đối tượng XML, cái mà bạn nhận được khi gọi hàm XMLPARSE với tham số kiểu đối tượng (document) và đối tượng để phân tích. Để làm cho văn bản có giá trị, đoạn mã sử dụng nó như một CLOB hoặc đối tượng lớn kí tự.
Đây là một câu lệnh chèn (insert) chuẩn của SQL nếu bỏ qua phần chuyển đổi trên.
Sau khi nhập đoạn mã đó và cửa sổ Command Editor, nhấn Execute và chờ thông điệp "The SQL command completed successfully" nói rằng câu lệnh SQL đã được hoàn thành.
Hãy vào Control Center và mở Database. Mở rộng các bảng và cuốn qua các bảng mặc định. Khi bạn tìm thấy bảng queryResults hãy chọn nó. Ở phía dưới panel, chọn actions open để xem bảng hộp thoại Open table dialogue. Trước tiên, chọn dòng duy nhất mà bạn đã thêm SQL và nhấn Fetch XML. Bạn nhấn vào nút có nhãn ... để mở hộp thoại chứa lược đồ XML và cấu trúc nút mà bạn đã vừa mới thêm.
Chúc mừng! Bạn vừa mới cài đặt xong một máy chủ cơ sở dữ liệu, đã tạo ra một cơ sở dữ liệu và cuối cùng đưa dữ liệu XML vào cơ sở dữ liệu. Bây giờ hãy xem làm thế nào để đưa dữ liệu lại cho ứng dụng sử dụng.
Tạo các truy vấn
Bây giờ bạn đã có dữ liệu trong cơ sở dữ liệu, hãy xem lại chúng.
SQL hay XQuery?
Như chúng tôi đã đề cập trước đó, DB2 cung cấp công cụ hỗ trợ cho ngôn ngữ truy vấn của W3C được gọi là XQuery. Bạn có thể thực hiện các truy vấn phức tạp đối với dữ liệu XML đã lưu trữ, tận dụng sức mạnh của các biểu thức. Các biểu thức trong một XQuery được biểu diễn là các mệnh đề hoặc các mệnh đề lồng nhau. Mệnh đề đầu tiên trong số các mệnh đề đó là mệnh đề tương tự như kiểu câu lệnh SQL "SELECT FROM WHERE", được gọi là một biểu thức FLWOR. Một biểu thức XPath giống như một đường dẫn dữ liệu ở một tệp tin hệ thống, các bước qua các nút con của lược đồ XML cho đến khi một điểm dữ liệu được tìm thấy. Với một bộ làm mới trên XPath, xem phần 1 của loạt bài này (xem Các tài nguyên). Trong khi bạn vẫn có thể sử dụng SQL để truy cập vào dữ liệu XML trong DB2, XQuery cho các đặc trưng bổ sung riêng cho XML. Bạn có thể sử dụng các ưu điểm đó trong mashup của mình.
FLWOR
FLWOR là những chữ cái đầu giành riêng cho biểu thức trong ngôn ngữ XQuery:
FOR: Lặp qua một chuỗi đầu vào, liên kết một biến với lần lượt mỗi mục đầu vào
LET: Khai báo một biến và gán cho nó một giá trị, giá trị có thể là một danh sách các mục
WHERE: Xác định rõ phạm vi lọc các kết quả truy vấn
ORDER BY: Xác định rõ trật tự sắp xếp các kết quả
RETURN: Xác định kết quả được trả về
Xem Ví dụ 5 để thấy FLWOR
Ví dụ 5. Ví dụ truy vấn FLWOR
for $statement in document(https://www.sample.com/sample.xml)//post let $comment := $statement/comment where $statement/postedby = 'userBob' return <quoteBob>{$comment}</quoteBob>
Đoạn mã trong ví dụ 5 gán tất cả các phần tử post
trong một tài liệu XML được tìm thấy ở https://www.sample.com//post
vào một biến được gọi là
$statement sử dụng
câu lệnh
FOR. Câu lệnh
LET cho thêm một biến
$comment
lưu lần lượt mỗi thành phần <comment> của phần tử post, nhưng
chỉ trong điều kiện của
WHERE giá trị các
phần tử <postedby> là userBob. Sau đó chúng ta trả về thông tin
trên XML, lặp đi lặp lại qua các kết quả, và tạo nên đầu ra qua mệnh
đề
RETURN. Các kết quả giống như Ví dụ 6 sau đây.
Ví dụ 6. mẫu đầu ra từ một truy vấn FLWOR
<quoteBob<Man, this is insightful.</quoteBob< <quoteBob>Riveting. Absolutely riveting.</quoteBob< <quoteBob>My eyes! My eyes!!!</quoteBob<
Hãy tìm hiểu qua mỗi loại mệnh đề một cách kỹ lưỡng
FOR
Câu lệnh
FOR lặp qua mỗi nốt trong một chuỗi
đầu vào, gắn các nốt đó với một biến và sau đó chuyển đến bước tiếp
theo (xem Ví dụ 7).
Ví dụ 7. Ví dụ về câu lệnh
FOR
<results> { for $result in document("http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid =mashupid&type=all&query=star+wars")/ResultSet/Result return <articles> { <article> { $$result/Title }: {$result/Summary} </article> } </results>
Nếu bạn đã dùng câu lệnh giống như trong Ví dụ 7, bạn sẽ có đầu ra là một nốt <article> với mỗi Title và Summary được trả về bằng ResultSet/Result giống như trong Ví dụ 8.
Ví dụ 8. Đầu ra của câu lệnh
FOR
<results> <results> <article> 'Star Wars' sales cut Hasbro results': YESTERDAY Close $19.16 Change $1.66 52-WEEK High $22.10 Low $17.00 Hasbro Inc., the nation's second-largest toy maker, said yesterday that earnings and revenue declined in the second quarter, due in part to an anticipated drop in "Star Wars" product sales. </article> <article> 'Star Wars' toys hit Hasbro profit: Hasbro said quarterly profits fell 8% on lower sales of "Star Wars" toys. </article> </results>
Đây là một khác biệt với mệnh đề
LET trong
trường hợp quan trọng.
LET
LET kết nối một biến vào một chuỗi các nốt
và có thể kết nối nhiều hơn một biến từ nhiều hơn một đường dẫn. Hãy
xem Ví dụ 9.
Ví dụ 9. Ví dụ câu lệnh
LET
<results> { let $t := document("http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid =mashupid&type=all&query=star+wars")/ResultSet/Result/title $s := document("http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid =mashupid&type=all&query=star+wars")/ResultSet/Result/summary return <articles> { $t } { $s } </articles> </results>
Ví dụ này trả về một nốt <articles> với vài nốt con, đó là một
danh sách các tiêu đề và các bản tóm tắt.
LET trả về tất cả các kết quả và không có trùng lặp. Bạn
có thể nhận thấy đầu ra của câu lệnh này giống như trong Ví dụ 10.
Ví dụ 10. Đầu ra
<results> <articles> <title>Star Wars Sales Cut Hasbro results</title> <title> Star Wars force falls for Hasbro</title> <summary> Falling sales of lightsabers and other Star Wars merchandise has dented US toymaker Hasbro's revenues.</summary> <summary> YESTERDAY Close $19.16 Change $1.66 52-WEEK High $22.10 Low $17.00 Hasbro Inc., the nation's second-largest toy maker, said yesterday that earnings and revenue declined in the second quarter, due in part to an anticipated drop in "Star Wars" product sales.</summary> </articles> </results>
WHERE
Mệnh đề
WHERE đánh giá dữ liệu ở một nốt mỗi
lần câu lệnh cố gắng
RETURN (trả lại) thông
tin (Xem Ví dụ 11).
Ví dụ 11. Ví dụ truy vấn
WHERE
<results> { for $result in document("http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid =mashupid&type=all&query=star+wars")/ResultSet/Result where $result/newssource = "BBC News" return <article> { $$result/Title }: {$result/Summary} </article> </results>
Mỗi lần câu lệnh chuẩn bị trả thông tin về, đó là từng nốt /bib/book
trong tệp bib.xml, mệnh đề
WHERE kiểm tra
xem nốt book/year có lớn hơn 1992 không. Trong trường hợp này, bạn
giới hạn đầu ra từ tệp XML vào những sách ở các nốt thỏa mãn điều
kiện. Mệnh đề
WHERE của XQuery hoạt động
giống như mệnh đề
WHERE trong SQL. Hơn nữa,
vì bạn giới hạn các kết quả, nên các kết quả được trả về tương ứng kết
quả mỗi lần lặp, giống như mệnh đề
FOR.
RETURN
Mệnh đề
RETURN cho phép bạn định dạng đầu ra
XML khi cần thiết (Xem Ví dụ 12).
Ví dụ 12. Ví dụ về
RETURN
return <article> { $$result/Title }: {$result/Summary} </article>
Trong ví dụ này, các định dạng trả về các kết quả bên trong một nốt XML có tên <bookInfo> nhưng bạn có thể tạo bất kỳ định dạng đầu ra nào bạn muốn.
Sử dụng XQuery
Để sử dụng XQuery như là một ngôn ngữ truy vấn trực tiếp thay cho SQL,
bạn phải xác định ngay từ đầu với phát biểu
xquery (Xem Ví dụ 13).
Ví dụ 13. Một mẫu XQuery
connect to mashup_1; xquery db2-fn:xmlcolumn('QUERYRESULTS.QUERY')
Như thường lệ, trước tiên bạn phải kết nối với cơ sở dữ liệu DB khi
chúng ta đang dùng Command Editor. Bạn có thể sử dụng phương pháp khác
kết nối đến cơ sở dữ liệu, chẳng hạn như khi bạn truy cập JDBC trong
mã Java. Phần cốt yếu của ví dụ này là
Xquery. Trước tiên, bạn bắt đầu câu Xquery để chuẩn bị máy
chủ cho cái gì sẽ đến tiếp theo. Bạn đưa ra bối cảnh của cơ sở dữ liệu
và bạn đang trả lời cho loại dữ liệu gì, trong trường hợp này là một
XMLCOLLUMN. Tiếp theo bạn đưa ra đường dẫn đến cơ sở dữ liệu, đó là
trong bảng: QUERYRESULTS và cột:QUERY. Điều đó sẽ trả về ví dụ XML đã
lưu trữ trước đó của bạn. Trong trường hợp này hàm
db2-fn:xmlcolumn() giống như hàm
document() của XPath.
Kết hợp XML với SQL
Bạn có thể truy cập dữ liệu trong DB2 theo nhiều cách. Tùy theo mục đích của bạn mà bạn có thể dùng cách nào đó. Bạn có thể kết hợp các câu lệnh FLWOR với các SQL truyền thống cho phép bạn chọn các bản ghi dựa trên cả dữ liệu quan hệ và dữ liệu XML.
Trả về dữ liệu (bao gồm cả XML) dựa trên dữ liệu quan hệ
Trong ứng dụng của mình, bạn sử dụng dữ liệu quan hệ ở trong lược đồ của mình. Chúng cho phép bạn kiểm tra tính chất mới của một bản ghi bằng cách giữ một timestamp. Thay vì trả về tất cả dữ liệu XML trong bảng, bạn có thể lọc các thông tin được trả về dựa trên các cột resultDate của bảng queryResults như trong Ví dụ 14.
Ví dụ 14. Lọc các thông tin được trả về
select id, xmlserialize(query as clob) from QUERYRESULTS where requestDate > '2006-07-23-07.45.00'
Sử dụng hàm
xmlserialize() sau đó bạn có thể
phân tích cú pháp một đối tượng nếu cần thiết.
Bạn cũng có thể chỉ chọn một phần của dữ liệu XML đã yêu cầu sử dụng các lệnh XPath như trong Ví dụ 15.
Ví dụ 15. Một câu lệnh XPath
select requestdate, xmlquery('$q//queryUrl' passing query as "q") from queryresults where requestDate >'2006-07-23-07.45.00'
Hàm
xmlquery() cho biết cơ sở dữ liệu xử lý
một truy vấn XQuery. Trong trường hợp này là một biểu thức XPath đơn
giản.
Trả về dữ liệu (bao gồm cả XML) dựa trên dữ liệu XML
Bạn cũng có thể truy vấn dựa trên nội dung XML. Thí dụ, bạn có thể chọn tất cả các ngày và giờ bạn đã yêu cầu từ một kiểu truy vấn riêng, như trong Ví dụ 16.
Ví dụ 16. Chọn các ngày và giờ.
Select requestDate from QUERYRESULTS where xmlexists('$c/queryData[queryType="REST"]' passing queryresults.query as "c")
Bạn có thể sử dụng câu truy vấn này để chọn cả requestDate và cột queryUrl từ XML (xem Ví dụ 17).
Ví dụ 17. Chọn requestDate và queryUrl
select requestdate, xmlquery('$q/queryData/result' passing query as "q") from queryresults where requestDate > '2006-07-23-07.45.00' and xmlexists('$c/queryData[queryType="REST"]' passing queryresults.query as "c") and xmlexists('$c/queryData[queryUrl="http://api.search.yahoo.com/NewsSearchSer vice/V1/newsSearch?appid=mashupid&type=all&query=New+York"]' passing queryresults.query as "c")
Ở ví dụ 17 đoạn mã yêu cầu cột requestdate và
phần tử kết quả từ cột truy vấn với tất cả các bản
ghi thỏa mãn cả 3 thành phần của mệnh đề where: requestDate, nội dung
của phần tử
queryType và nội dung của
queryData.
(Chú ý rằng có thể tổ hợp các yêu cầu XML-quan hệ vào một câu lệnh XPath đơn nhưng nếu làm như vậy bạn phải tìm XML đã trả về trong một cấu trúc ngắn gọn).
Sử dụng XQuery trong câu lệnh SQL
Sử dụng XQuery trong một câu lệnh SQL là việc kết hợp nó vào câu lệnh
SELECT, như trong
Ví dụ
18.
Ví dụ 18. Sử dụng XQuery trong câu lệnh SQL
select XMLSERIALIZE(xmlquery('for $r in $c/queryData/result return $r ' passing queryresults.query as "c") AS CLOB) from queryresults where requestDate > '2006-07-23-07.45.00' and xmlexists ('$c/queryData[queryType="REST"]' passing queryresults.query as \"c\")
Trong ví dụ này, bạn sử dụng câu lệnh XQuery giống như khi bạn đã từng
dùng nó trước đó, nhưng bạn chứa nó trong hàm
xmlquery() để có thể sử dụng nó trong một lệnh SELECT
thông thường.
Xóa và cập nhật dữ liệu XML
Để xóa và cập nhật các bản ghi DB2 có chứa XML cũng giống như thực thi các thao tác đó đối với một bảng DB2 điển hình. Không may, bạn không thể chỉ biến đổi một phần của một cột XML. Thay vào đó, bạn phải cập nhật giá trị của cột XML với toàn bộ tài liệu cho dù chỉ một ít văn bản thay đổi.
Bạn sẽ không thực hiện bất kỳ phép xóa và cập nhật nào ở phiên bản này của mashup.
Tích hợp với mashup
Giờ bạn đã hiểu các truy vấn làm việc như thế nào, bạn có thể thêm chúng vào mashup servlet. Thực thi các truy vấn là việc thực hiện các truy vấn JDBC đơn giản nhưng với các truy vấn XML-quan hệ thay vì SQL truyền thống. Cũng như vậy, thay vì các giá trị đơn giản, ta lấy về một chuỗi XML đã cấp phát và sau đó bạn có thể đặt chúng vào một đối tượng của mô hình đối tượng tài liệu DOM (Document Object Model).
Dự án của bạn đặt ở đâu.
Bạn đang có một servlet. Nó lặp qua một nhóm các dịch vụ xác định trước, gọi dữ liệu ra từ URL của chúng và chuyển vào một trang web phù hợp. Trước khi thực hiện các thay đổi với cơ sở dữ liệu, xem đoạn mã trong ví dụ 19.
Ví dụ 19. Đoạn mã
import java.io.IOException; import import java.io.IOException; import java.io.StringReader; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; public class MashupClientServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { public MashupClientServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().print("<html>"); ... response.getWriter().print("</html>"); } public static Document getData (String query) { try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document; document = builder.parse(query); return document; } catch (Exception e) { System.out.println(e.getMessage()); return null; } } public static Node renderService(String query, Service svc, Document hostDoc){ Document document = getData(svc.baseURL+query); if (document != null){ try { Node serviceElement = hostDoc.createElement("span"); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); XPath xpath = XPathFactory.newInstance().newXPath(); String expression = svc.recordExp; NodeList recordNodes = (NodeList) xpath.evaluate( expression, document, XPathConstants.NODESET); Node toImport = null; for (int i=0; i < recordNodes.getLength(); i++) { Document templateDoc = builder.parse( new InputSource(new StringReader(svc.template))); ... } toImport = hostDoc.importNode( templateDoc.getDocumentElement(), true); serviceElement.appendChild(toImport); } return serviceElement; } catch (Exception e){ e.printStackTrace(); return null; } } else { System.out.println( "Get Data returned null. What do we do now?"); return null; } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String query = request.getParameter("query").toString(); try { DocumentBuilder builder = DocumentBuilderFactory .newInstance().newDocumentBuilder(); Service[] svcs = Service.getServices(); Document hostDoc = builder.parse( new InputSource(new StringReader("<results/>"))); Node hostRoot = hostDoc.getDocumentElement(); for (int k=0; k < svcs.length; k++){ Service svc = svcs[k]; Node renderedService = renderService(query, svc, hostDoc); if (renderedService != null){ Element nameElement = hostDoc.createElement("h1"); nameElement.appendChild( hostDoc.createTextNode(svc.name)); Node serviceElement = hostDoc.createElement("span"); serviceElement.appendChild(nameElement); serviceElement.appendChild(renderedService); hostRoot.appendChild(serviceElement); hostRoot.appendChild(hostDoc.createTextNode("\n")); } } DOMSource source = new DOMSource(hostDoc); StreamResult result = new StreamResult(response.getWriter()); TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer transformer = transFactory.newTransformer(); transformer.transform(source, result); } catch (Exception e){ e.printStackTrace(response.getWriter()); } } }
Bạn có thể xem toàn bộ ví dụ trong các tệp mã nguồn mà bạn tải về cho bài viết này, nhưng ví dụ 19 cho bạn ý tưởng chung nhất về việc bạn đang làm việc với cái gì. Bạn nên hiểu ít nhất một thay đổi từ đoạn mã khi nó đã đặt ở cuối phần 1 (xem Tài nguyên); Servlet có được dữ liệu thực tế bằng các phương pháp riêng của nó. Nếu bạn đang xây dựng sản phẩm thực sự, bạn có thể thực hiện các thay đổi để làm tăng độ bền vững của việc xử lý các trường hợp ngoại lai, v.v.. Cấu trúc này có hai ưu điểm. Thứ nhất, nó làm cho việc bẫy các lỗi dễ hơn khi tải các thông tin đầu vào (feed) (chẳng hạn một dịch vụ mà bị ngưng hoặc trả về XMl không hợp lệ). Thứ hai, nó làm cho việc thêm vào chức năng mới thuận tiện hơn.
Nhưng các tính năng mới đó là gì?
Các tính năng có hai dạng. Thứ nhất, servlet kiểm tra cơ sở dữ liệu với dữ liệu đã lưu trữ có tương ứng với truy vấn hiện tại hay không trước khi thừa nhận việc nó cần phải tải về bản sao mới. Nếu nó tìm ra dữ liệu đã lưu trữ, nó dùng dữ liệu đó thay vì thực hiện một yêu cầu mới. Việc này có thể tiết kiệm vài phút cho mỗi trang nếu trang đó có nhiều yêu cầu dịch vụ được kết nối bên trong.
Thứ hai, nó ghi dữ liệu vào cơ sở dữ liệu ở vị trí đầu tiên. Hãy bắt đầu với dạng thứ hai này.
Chuẩn bị ghi dữ liệu
Bước thứ nhất là ghi lại mỗi yêu cầu mới được tải về vào cơ sở dữ liệu. Xem ví dụ 20.
Ví dụ 20. Lưu dữ liệu vào cơ sở dữ liệu
... public static void saveData(String queryUrl, Document document){ try{ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document saveDocument = builder.parse( new InputSource(new StringReader("<queryData/>"))); Element typeElement = saveDocument.createElement("queryType"); typeElement.appendChild(saveDocument.createTextNode("REST")); Element queryUrlElement = saveDocument.createElement("queryUrl"); queryUrlElement.appendChild( saveDocument.createTextNode(queryUrl.replaceAll("&", "[[ampersand]]"))); Element rootElement = saveDocument.getDocumentElement(); rootElement.appendChild(typeElement); rootElement.appendChild(queryUrlElement); Element resultData = saveDocument.createElement("result"); Node dataToSave = saveDocument.importNode( document.getDocumentElement(), true); resultData.appendChild(dataToSave); saveDocument.getDocumentElement().appendChild(resultData); DOMSource domSource = new DOMSource(saveDocument); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.transform(domSource, result); String dataString = writer.toString(); } catch (Exception e){ e.printStackTrace(); } } public static Node renderService(String query, Service svc, Document hostDoc){ ...
Bạn có thể gói gọn tất cả các thao tác vào một phương thức
savedata(). Đối số của phương thức là URL truy vấn gốc và tài liệu được trả về bởi dịch vụ web. Để bắt đầu hãy tạo một tài liệu mới với một phần tử gốc
queryData và sau đó thêm
queryType và các phần tử
queryUrl. Chú ý rằng XML có sử dụng kí tự đặc biệt là kí tự & Bạn không thể sử dụng chúng ở truy vấn XPath. (Vì bạn sẽ không sử dụng dữ liệu gọi một cách trực tiếp bất kì dịch vụ nào) để viết nội dung của thành phần
queryUrl bạn thay kí tự
& bằng
[[ampersand]]. Miễn là bạn làm một việc tương tự khi tìm kiếm. Bạn sẽ tìm ra dữ liệu. Từ đó bạn tạo thành phần kết quả và nhập dữ liệu vào đối tượng Document mới để bạn có thể thêm nó vào thành phần mới.
Khi bạn đã thêm thành phần kết quả vào saveDocument thì bạn đã sẵn sàng cho việc chèn dữ liệu vào cơ sở dữ liệu. Để làm điều đó bạn cần một xâu biểu diễn của Document. Bạn có thể có nó bằng việc tạo ra một đối tượng StringWriter và sử dụng nó như là kết quả của phép biến đổi đồng nhất.
Giờ bạn có thể lưu nó vào cơ sở dữ liệu.
Lưu dữ liệu
Việc lưu dữ liệu vào cơ sở dữ liệu là liên quan đến truy vấn, cũng giống như bạn làm với bất kì thao tác JDBC nào. Trong trường hợp này, dễ nhất là sử dụng một PreparedQuery. Hãy xem ví dụ 21.
Ví dụ 21. Lưu dữ liệu vào cơ sở dữ liệu
import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.sql.PreparedStatement; import java.util.Properties; ... public class MashupClientServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { ... public static void saveData(String queryUrl, Document document){ try{ ... saveDocument.getDocumentElement().appendChild(resultData); DOMSource domSource = new DOMSource(saveDocument); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.transform(domSource, result); String dataString = writer.toString(); String alias = "mashup_1"; String userId = "myuserid"; String password = "mypassword"; Properties props = new Properties(); String url = "jdbc:db2:" + alias; Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance(); props.setProperty("user", userId); props.setProperty("password", password); props.setProperty("CONNECTNODE", "0"); Connection con = DriverManager.getConnection( url, props ); con.setAutoCommit(false); PreparedStatement stmt = con.prepareStatement( "INSERT INTO queryResults (requestdate, query) " + "VALUES(CURRENT TIMESTAMP,XMLPARSE(" + "document cast(? as clob) preserve whitespace))"); stmt.setString(1, dataString); stmt.execute(); stmt.close(); con.commit(); con.close(); } catch (Exception e){ e.printStackTrace(); } } public static Document getData (String query) { try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document; document = builder.parse(query); saveData(query, document); return document; } catch (Exception e) { System.out.println(e.getMessage()); return null; } } public static Node renderService(String query, Service svc, Document hostDoc){ ...
Như ở bất kỳ ứng dụng JDBC nào khác, bạn bắt đầu bằng việc định nghĩa các thuộc tính
của kết nối và thiết bị được sử dụng cho kết nối đó. (Lớp thiết bị đó là một phần
của tệp db2java.zip mà bạn đã thêm vào Tomcat.) Sau đó bạn có thể tạo một kết nối
thực tế và thiết lập trạng thái an toàn. (Bởi vì bạn không sử dụng các giao tác
(transactions) nên bạn có thể dễ dàng đặt
autoCommit là true.)
Từ đó bạn tạo một
PreparedStatement mà chứa một câu lệnh
SQL giống như ở ví dụ 4. Sự khác biệt ở đây đó là:
bạn có thể chứa một placeholder, như được chỉ ra bằng dấu hỏi chấm (?) vào trong
cái mà bạn có thể thiết lập dữ liệu sử dụng phương thức
setString().
Trong trường hợp này bạn chuyển hướng dữ liệu vào một CLOB (đối tượng lớn dữ liệu).
Sau đó sử dụng hàm
XMLPARSE() chuyển dữ liệu vào một Document.
Khi bạn đã tạo và định vị
PreparedStatement bạn có thể
thực hiện và đóng nó lại, sau đó xác nhận câu lệnh và ngắt kết nối.
Tất cả điều đó xảy ra khi bạn gọi hàm
saveData() ngay
lập tức sau khi lấy dữ liệu mới.
Kiểm tra bộ đệm dữ liệu
Khi bạn có dữ liệu trong cơ sở dữ liệu, bạn cần phải kiểm tra nó. Bạn thực hiện
điều đó với phương thức
checkCache(). Phương thức lấy
một truy vấn và tìm kiếm dữ liệu từ truy vấn đó trong cơ sở dữ liệu với các
khoảng thời gian riêng. Ví dụ, tìm kiếm dữ liệu từ truy vấn
http://www.technorati.com/tag=Java đã lưu trong giờ qua. Bạn có thể xem truy vấn
này làm việc như thế nào trong ví dụ 22.
Ví dụ 22. Kiểm tra nơi lưu trữ
... import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import java.util.Calendar; import java.text.SimpleDateFormat; public class MashupClientServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { public MashupClientServlet() { super(); } ... public static String checkCache(String query){ try{ String alias = "mashup_1"; String userId = "myusername"; String password = "mypassword"; Properties props = new Properties(); String url = "jdbc:db2:" + alias; Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance(); props.setProperty("user", userId); props.setProperty("password", password); props.setProperty("CONNECTNODE", "0"); Connection con = DriverManager.getConnection( url, props ); con.setAutoCommit(false); Statement stmt = con.createStatement(); Calendar oldestRequestTime = Calendar.getInstance(); oldestRequestTime.add(Calendar.MINUTE, -60); SimpleDateFormat sdf = (SimpleDateFormat)SimpleDateFormat.getDateTimeInstance(); sdf.setCalendar(oldestRequestTime); sdf.applyLocalizedPattern("yyyy-MM-dd-HH.mm.ss"); String sdfStr = sdf.format(oldestRequestTime.getTime()); Statement stmt = con.createStatement(); String sql = "select XMLSERIALIZE(xmlquery(" + "'for $r in $c/queryData/result return $r' "+ "passing queryresults.query as \"c\") AS CLOB) "+ "from queryresults where requestDate > '"+sdfStr+"' "+ "and xmlexists ('$c/queryData[queryType=\"REST\"]' "+ "passing queryresults.query as \"c\") and "+ "xmlexists ('$c/queryData[queryUrl=\""+ query.replaceAll("&", "[[ampersand]]")+ "\"]' passing queryresults.query as \"c\")"; "+ "order by queryresults.requestDate desc"; ResultSet result = stmt.executeQuery(sql); String returnStr = "-1"; if (result.next()){ //Using cached data! returnStr = result.getString(1); } con.commit(); con.close(); return returnStr; } catch (Exception e){ e.printStackTrace(); return "-1"; } } public static void saveData(String queryUrl, Document document){ try{ ...
Trước tiên, bạn kết nối với cơ sở dữ liệu. Sau đó, bạn xác định rõ thời điểm nào dữ
liệu quá cũ để dùng. Để làm được điều đó bạn bắt đầu với việc tạo một đối tượng
Calendar. Đối tượng này nắm giữ ngày giờ hiện tại,
cộng thêm -60 phút (hoặc 60 phút trước) và đưa nó vào một xâu. Mặt khác, bạn
sẽ tìm kiếm dữ liệu với một
queryData lớn hơn 60
phút trước thời điểm hiện tại.
Để thực hiện tìm kiếm đó, trước tiên bạn tạo một đối tượng
Statement.
Sau đó tạo một truy vấn để tìm dữ liệu. Trong trường hợp này là một truy vấn FLWOR
lặp qua thành phần
queryData/result của cột queryresults.query.
Truy vấn này thiết lập giá trị của
$r là: chỉ các dòng nào mà
requestDate mới hơn thời điểm giới hạn và
queryType và
queryUrl
mới được trả về. Sau đó chúng ta có thể thực thi
Statement,
rồi trả về kết quả là một
ResultSet.
Tiếp theo, đặt giá trị của
returnStr là
-1 và việc thay đổi giá trị của nó thành XML
được trả về nếu và chỉ nếu
ResultSet có ít nhất
một dòng dữ liệu được trả về.
Cuối cùng đóng kết nối đến cơ sở dữ liệu.
Sử dụng dữ liệu
Bạn có dữ liệu từ cơ sở dữ liệu và bạn cần sử dụng nó. Dùng phương thức
getData() như trong Ví dụ 23.
Ví dụ 23. Sử dụng dữ liệu đã lưu trữ
... public static Document getData (String query) { try { DocumentBuilder builder = DocumentBuilderFactory .newInstance().newDocumentBuilder(); String cached = checkCache(query); Document document; if (cached.equals("-1")){ //Using fresh data document = builder.parse(query); saveData(query, document); } else{ //Using cached data document cachedDocument; cachedDocument = builder.parse( new InputSource(new StringReader(cached))); } return document; } catch (Exception e) { System.out.println(e.getMessage()); return null; } } ...
Trước tiên bạn kiểm tra cơ sở dữ liệu bằng việc sử dụng phương thức
checkCache(). Nếu không tìm thấy dữ liệu có thể chấp nhận được trong cơ sở dữ liệu, phương thức trả về giá trị
-1. Vì vậy bạn chỉ cần yêu cầu dữ liệu làm mới như thường lệ. Mặt khác, nếu xâu là bất cứ thứ gì khác, bạn dùng nó để xây dựng tài liệu.
Theo cả hai cách, bạn trả về đối tượng
Document.
Tổng kết
Tổng hợp và định hướng tiếp theo
Chủ nhân của một dịch vụ web tất nhiên sẽ đánh giá cao những gì bạn đã làm được ở đây, bằng việc lưu trữ tạm thời các truy vấn thực hiện trên các máy chủ của họ, bạn đã làm giảm chi phí bảo trì và lưu lượng của họ cũng như làm cho trang web của riêng bạn nhanh hơn. Bạn đã thêm một cơ sở dữ liệu DB2 vào ứng dụng mashup để lưu trữ các phản hồi XML từ các dịch vụ web mà bạn sử dụng, cho phép bạn truy vấn đối với máy chủ DB2 cục bộ và tận dụng sức mạnh các đặc trưng pureXML mới. Sau khi lưu trữ vào cơ sở dữ liệu bạn truy vấn máy chủ của mình và đã tạo ra một đối tượng dữ liệu trong ứng dụng.
Trong phần 3, bạn bắt đầu thêm thông tin vào hệ thống qua việc sử dụng các bản thể luận, bắt đầu với Resource Definition Framework, RDF.
Tải về
Tài nguyên
Học tập
- Ultimate mashup – Các dịch vụ Web và Web ngữ nghĩa (semantic Web) Loạt các bài viết: Đọc các bài viết khác và và tạo các Mashup tùy ý.
- Web có thể lập trình Cập nhật các mashup gần nhất và Web 2.0 APIs mới.
- DB2 9: pureXML Overview and Fast Start (Cynthia M. Saracco và Don Chamberlin, IBM Redbooks, tháng 6 năm 2006): Đọc tài liệu này giới thiệu về các dịch vụ dữ liệu XML lai ghép trong DB2 9 cho hệ điều hành Linux,™, UNIX™, và Windows, bao gồm cả pureXML.
- Getting Started with XPath (hãy bắt đầu với XPath) (Bertrand Portier, developerWorks, tháng 5 năm 2004): Trong hướng dẫn này, hãy tìm phần giới thiệu về chuẩn W3C.
- Query XML Data with XQuery (truy vấn dữ liệu XML với XQuery) (Don Chamberlin and Cynthia M. Saracco, developerWorks, April 2006): Học cách truy vấn dữ liệu đã lưu trữ trong các cột XML sử dụng XQuery
- Query DB2 XML Data with SQL (Truy vấn dữ liệu XML DB2 với SQL) (Cynthia M. Saracco, developerWorks, March 2006): Học truy vấn dữ liệu đã lưu trữ ở các cột XML sử dụng SQL và SQL/XML
- DB2 9 Web site: tìm hiểu thêm về sự hỗ trợ XML trong DB2 9 (thường được biết đến là DB2 Viper)
- DB2 for Linux, UNIX and Windows trên developerWorks: Tìm các tài nguyên học tập, tải về, thông tin sản phẩm, và các hỗ trợ cho IBM DB2, hệ thống quản lý cơ sở dữ liệu quan hệ của IBM hiện có để cho các thông tin yêu cầu.
- Considering Ajax, Part 1: Cut through the hype (Chris Laffra, developerWorks, May 2006): Xem xét tập các điểm thảo luận này với mỗi người phát triển trước khi bạn sử dụng các kỹ thuật Ajax cho một trang web.
- Trang web Ajax Ghé thăm trang web được bảo trợ bởi Mozilla Development Center.
- DB2 and open source: Put yourself on the map with Google Maps API, DB2/Informix, and PHP on Linux (DB2 và nguồn mở: Tự đặt mình trên bản đồ Google Maps API, DB2/Informix và PHP trên Linux) (Marty Lurie and Aron Y. Lurie, developerWorks, March 2006): tạo một bản đồ dễ sử dụng (easy-to-use) có chứa dữ liệu của của bạn.
- Building Web service applications with the Google API (Xây dựng các ứng dụng dịch vụ web với Google API) (Nicholas Chase, developerWorks, May 2002): Học cách giấu các kết quả tìm kiếm Google và các thông tin khác ở các ứng dụng Java trong hướng dẫn này
- Second Generation Web Services (Các dịch vụ web thế hệ thứ hai): trên XML.com, tìm tin tức về kiến trúc REST
- REST and the Real World (REST và thế giới thực): Đọc thêm về REST (Representational State Transfer) từ trang XML.com
- Trang web W3C Semantic Web Activity: Đọc về web ngữ nghĩa
- W3C RDF Activity: Tìm hiểu này cho Framework mô tả tài nguyên mới nhất
- RSS là gì?: Từ trang XML.com, học về định dạng chung cho các bản tin, nội dung, và các weblog cá nhân
- Atom Overview: Đọc về nội dung web dựa trên XML và định dạng siêu dữ liệu và giao thức mức-ứng dụng từ AtomEnabled.org AtomEnabled.org.
- Introduction to XML (Giới thiệu về XML) (Doug Tidwell, developerWorks, August 2002): Đọc hướng dẫn này để có một nền tảng XML tốt.
- developerWorks Java zone: Học thêm về lập trình trong Java với các bài báo, các hướng dẫn, các diễn đàn, ...
- developerWorks XML zone: Tìm một phạm vi rộng lớn các bài báo và các gợi ý kỹ thuật, các chuẩn và các sách đỏ IBM (IBM Redbooks) về XML.
- IBM XML 1.1 certification- Chứng nhận IBM XML 1.1: làm thế nào để bạn có thể trở thành một người phát triển XML 1.1 được chứng nhận bởi IBM như thế nào và các kỹ thuật liên quan.
- developerWorks technical events and webcasts: Các sự kiện và thông cáo kỹ thuật.
Lấy sản phẩm và công nghệ
- W3C SOAP Specification Các đặc điểm kỹ thuật W3C SOAP: Cho phiên bản gần đây nhất
- Apache Geronimo: Tải về và cài đặt Geronimo. Tìm thêm thông tin về cài đặt Geronimo ở phần 1
- Rational Web Developer: Tải về một phiên bản dùng thử và làm cho việc phát triển web của bạn dễ dàng hơn
- DB2 Enterprise 9: Tải về một phiên bản dùng thử của DB2 hoặc DB2 Express-C 9, một phiên bản miễn phí của DB2 Express 9
Thảo luận
- diễn đàn deverloperWorks XML: Giao tiếp với những người phát triển XML khác để giải quyết các vấn đề giống như bạn
- developerWorks blogs: Tham gia vào nhóm developerWorks
Bình luận
-
Vùng dữ liệu trên developerWorks
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
-
Vùng mã nguồn mở trên developerWorks
Xem các bài viết về HTML, CSS, JavaScript,...
-
Điện toán đám mây
Tìm hiểu về điện toán đám mây

markdown:
## Trước khi bạn bắt đầu
Hướng dẫn này dành cho những người phát triển web muốn học cách sử dụng
và kết hợp các dịch vụ web từ quan điểm của XML và xuất dữ liệu XML
tới web. Điều đó có nghĩa là bạn đã biết về Java™, XML,
SQL, việc phát triển web và các khái niệm cơ bản của các dịch vụ web.
Sự hiểu biết về JDBC sẽ rất có ích. Nếu bạn cần nhớ lại các chủ đề đó
thì hãy xem lại phần
[Các tài nguyên](#resources) để có
thêm thông tin.
### Giới thiệu về loạt bài này
Bạn không thể thay đổi hoàn toàn trang web mà không nhảy vào một trang
web mà ở đó cho phép bạn truy cập đến các dữ liệu của nó thông qua một
API dựa trên các dịch vụ Web, hoặc sử dụng dữ liệu từ một trang khác
thu được thông qua API dựa trên các dịch vụ web. Khi bạn xem xét ưu
điểm của thông tin hiện có trong các ứng dụng của riêng bạn, điều đó
không chắc là có sự ngạc nhiên lớn nào. Điều đó không chỉ là vấn đề
thời gian trước khi ai đó bắt đầu kết hợp dữ liệu từ các hệ thống khác
nhau để tạo ra vài thông tin trọn vẹn. Các ứng dụng này được gọi là
các
*mashup*. Các mashup là ứng dụng gần đây nhất trên web, từ
các trang dựa trên cộng đồng tới các trang tìm kiếm chuyên biệt.
Hầu hết các Mashup đều rất hữu ích, chúng có điểm chung là được phát triển với tập các dịch vụ riêng biệt. Nếu một trong các dịch vụ thay đổi hoặc nếu sở thích của bạn với các loại dịch vụ thay đổi thì bạn sẽ có nhiều việc phải làm.
Mục đích của các bước hướng dẫn này là tạo nhanh một ứng dụng mashup để người dùng có thể thêm hoặc hủy các dịch vụ một cách tùy ý và hệ thống sẽ không biết được người dùng đã làm gì với chúng. Loạt bài tiến hành như sau:
Trong phần 1, Nicholas Chase đã giới thiệu các khái niệm của mashup, đã
chỉ ra các mashup làm việc như thế nào và chỉ dẫn bạn quá trình xây
dựng một phiên bản đơn giản như thế nào (xem
[Các tài nguyên](#resources)). Bạn cũng đã nhận thấy các vấn đề về hiệu
suất quan trọng khi thực hiện gọi hàng tá các trang web tiềm ẩn.
Trong phần 2, bạn giải quyết vài vấn đề đó bằng cách sử dụng khả năng pureXML™ mới của IBM® DB2® để xây dựng một nơi lưu trữ XML, nơi này lưu trữ các kết quả của các yêu cầu trước đó và cũng cho phép bạn lấy thông tin đặc trưng.
Cuối cùng, bạn sẽ cần sử dụng
*các bản thể luận (ontology)* hoặc
các từ vựng mà các khái niệm và mối quan hệ giữa chúng là xác định, do
đó trong phần 3 bạn bắt đầu quá trình đó bằng việc tìm hiểu về RDF và
RDFS, hai thành phần khóa của Web Ontology Language (OWL). Các vấn đề
này ta sẽ thảo luận trong phần 4. Ở phần 5, chúng tôi đưa ra các bản
thể luận mà bạn đã tạo ra ở phần 4 và sử dụng chúng để cho phép người
dùng thay đổi các nguồn thông tin.
Trong phần 6, những điều thú vị sẽ tăng lên. Tại đó, bạn có một ứng dụng đang thực thi và khung làm việc (framework) trong đó, do vậy hệ thống có thể sử dụng tùy ý suy dẫn ngữ nghĩa để hiểu các dịch vụ. Trong phần này, bạn đưa ra kiểm soát người dùng, cho phép họ ánh xạ các dịch vụ mới vào bản thể luận và nhấc hoặc chọn dữ liệu được dùng với một mashup tùy ý.
### Giới thiệu về bài viết này
Bài viết này là phần 2 trong một loạt bài gồm 6 bài viết về sử dụng và
kết hợp các dịch vụ web như thế nào từ quan điểm của XML và xuất dữ
liệu lên web. Trong phần 1, bạn đã học về việc lựa chọn XML từ các
dịch vụ sử dụng REST, nhưng các khái niệm về các dịch vụ SOAP là tương
tự (xem
[Các tài nguyên](#resources)). Bạn sẽ tiếp tục
loạt bài này với việc lưu trữ các dữ liệu XML đó vào một cơ sở dữ
liệu, tạo ra một bộ đệm lưu trữ các kết quả truy vấn. Hơn nữa bạn sẽ
lấy được các dữ liệu đã lưu trữ để sử dụng trong các ứng dụng Java của
bạn.
Sau bài viết này, bạn sẽ học cách cài đặt một máy chủ cơ sở dữ liệu (database server) như thế nào và sửa đổi nó để nhận dữ liệu cũng như là viết các câu truy vấn như thế nào để gắn một dữ liệu XML vào một cột XML một cách rõ ràng.
Bạn sẽ học về:
- Cài đặt DB2 Enterprise Edition
- Tạo một cơ sở dữ liệu DB2 9 mới, cấu hình nó để gắn với XML
- Tạo một bảng cơ sở dữ liệu sử dụng kiểu cột XML
- Chọn thông tin đã lưu dưới dạng XML trong cơ sở dữ liệu quan hệ sử dụng XPath
- Viết các câu truy vấn XML XQuery
- Viết các câu truy vấn SQL và XQuery lai ghép
Hướng dẫn này sử dụng Java, nhưng các khái niệm là giống nhau với bất kì ngôn ngữ lập trình hoặc hệ điều hành nào.
### Các điều kiện tiên quyết
Theo đoạn mã trong hướng dẫn này, bạn cần phải cài đặt và kiểm tra các phần mềm sau đây:
[IBM® DB2® 9 (thường được gọi là "Viper")](http://www.ibm.com/software/data/db2/v9/xml.html): Cơ sở dữ liệu quan hệ này cũng chứa đựng những khả năng XML quan trọng, bạn sẽ cần chúng. Bạn có thể tải về một phiên bản dùng thử của DB2 9 hoặc [DB2 Enterprise 9](http://www.ibm.com/developerworks/downloads/im/udb/?S_TACT=105AGY75)hoặc [DB2 Express-C 9](http://www.ibm.com/developerworks/downloads/im/udbexp/?S_TACT=105AGY75)một phiên bản miễn phí của máy chủ dữ liệu DB2 Express 9. [Apache Tomcat](http://tomcat.apache.org/)hoặc một máy servlet khác: Bạn sẽ xây dựng các ứng dụng web sử dụng các servlet, vì vậy bạn cần có một máy servlet chẳng hạn như Apache Tomcat. Nếu bạn chọn xây dựng ứng dụng trên một môi trường khác, hãy chắc chắn rằng bạn đã có nó trong tay. Tải về apache-tomcat-5.5.17.zip và cài đặt vào một thư mục với tên thư mục không chứa dấu cách.
- Java: Apache Tomcat 5.5 yêu cầu Java 1.5 hoặc cao hơn. Hãy tải về
[J2SE SDK](http://java.sun.com/j2se/1.5.0/download.jsp).
- Hãy làm cho mọi việc dễ dàng hơn, bạn có thể sử dụng một IDE chẳng
hạn như Eclipse hoặc IBM Rational Web Developer™.
Bạn có thể tải về Eclipse ở địa chỉ
[Eclipse.org](http://www.eclipse.org/), tải về một bản dùng thử Rational Web Developer ở địa chỉ [Rational Web Developer](http://www.ibm.com/developerworks/downloads/r/rwd/?S_TACT=105AGY75), hoặc bạn sử dụng một môi trường phát triển mà bạn thích. Tuy nhiên bạn sẽ không làm những gì quá sức với trình biên dịch và việc thực thi.
## Đi một ngày đàng học một sàng khôn
Trước khi chúng ta bắt đầu việc tạo các nơi lưu trữ, hãy kiểm tra dữ liệu hiện có. Bạn nên hiểu về bối cảnh của XML và các cơ sở dữ liệu.
### Truyền DB2 9 vào ứng dụng
Các dịch vụ web là tiện ích cho việc xem thông tin một cách nhanh
chóng. Ngày nay, nhiều trang web cho người dùng truy cập trên giao
diện hạn chế, đó là trình duyệt. Bây giờ họ có thể truy cập chúng
thông qua các dịch vụ web. Các dịch vụ web được phổ biến và được sử
dụng trong hầu hết các ứng dụng thứ cấp. Các ứng dụng này gọi là
*mashup*. Và các ứng dụng này nổi lên ở bất cứ đâu thông tin
có thể giúp giải quyết một vấn đề thích hợp.
Trong phần 1, bạn đã gặp mashup và đã bắt đầu lấy thông tin từ nhiều
hơn một vị trí nào đó, sửa đổi tập các dữ liệu vào các ứng dụng tùy ý
của bạn (xem
[Các tài nguyên](#resources)). Bây giờ
chúng ta muốn lưu tạm thời vào bộ đệm các tập dữ liệu để sử dụng chúng
một cách hợp lý. Tại sao phải lưu dữ liệu vào bộ đệm? Một lí do quan
trọng đó là các dịch vụ mà bạn kết nối có một lượng lớn các yêu cầu ở
mọi thời điểm. Bạn lấy các dữ liệu này miễn phí nên để lịch sự thì bạn
giảm số lượng yêu cầu mà bạn gửi đi trong suốt phiên làm việc của
người dùng trên ứng dụng của bạn. Bởi vì các ứng dụng không yêu cầu dữ
liệu thời gian thực, bạn có thể làm giảm tải băng thông một cách rõ
ràng. Bạn cũng có thể lợi dụng kho dữ liệu cục bộ, làm giảm thời gian
cho truy vấn thực hiện (và trong hầu hết trường hợp là nhiều truy
vấn).
Để đạt được các mục tiêu đó, bạn sẽ tận dụng máy chủ DB2 và các đặc tính mới của XML mà IBM đã giới thiệu trong phiên bản 9 cũng như vài mẹo Java để quản lý việc lưu trữ tạm thời của bạn.
### Dữ liệu quan hệ với dữ liệu XML
Một trong những lợi ích lớn nhất của việc sử dụng cơ sở dữ liệu quan hệ đó là tốc độ mà ở đó bạn có thể truy cập và thao tác dữ liệu. Các mô hình hệ thống quản lý cơ sở dữ liệu quan hệ RDBMS có thể phân tích lượng lớn dữ liệu trong các bảng qua vài cơ sở dữ liệu và trả về các truy vấn gần như ngay lập tức. Chẳng hạn bạn muốn biết "có bao nhiêu nắp cống đã được đặt ở Minneapolis MN bởi các nhà thầu khác nhau vào tháng chín trong vòng 5 năm?". Nếu bạn biết viết truy vấn và bạn có các cơ sở dữ liệu bạn có thể có câu trả lời trong nháy mắt. Một trở ngại đó là bạn cần bản thân dữ liệu và truy cập tới nó. Nhưng dữ liệu đã chờ sẵn trong cơ sở dữ liệu và bạn sẽ phải hiểu đưa nó tới nơi bạn cần như thế nào và hiểu nó theo cách của bạn như thế nào.
Lưu trữ dữ liệu dưới định dạng đọc được và có khả năng truyền từ nơi này đến nơi khác là một chức năng của XML. Khi dữ liệu được lưu trữ trong một cơ sở dữ liệu dưới dạng các bảng giống như bảng tính, nó thường được định dạng cho ứng dụng cụ thể. XML cho phép bạn lưu trữ dữ liệu ở phần mở rộng, con người có thể đọc được định dạng, điều đó chuẩn bị sẵn sàng cho sự trao đổi giữa các ứng dụng với con người. Bạn có thể sắp đặt tất cả các cách để phân chia dữ liệu và mang nó vào các ứng dụng. Ở đó bạn có thể bắt đầu thao tác lại dữ liệu. Đây chính là nền tảng để xây dựng khối mashup của bạn, khả năng tổ hợp dữ liệu từ hai ứng dụng rất khác nhau, cấu trúc lại nó và tạo các biến thể của riêng bạn.
Những thách thức mà bạn phải đối mặt là làm thế nào để kích hoạt tính năng XML để có thể xử lý một số các phân tích phức tạp hơn và làm thế nào để tận dụng lợi thế của máy chủ DB tốc độ cao?
Hầu hết các cơ sở dữ liệu quan hệ cố gắng xử lý dữ liệu XML từ đầu.
Nhưng hầu hết các lần, các kỹ thuật của chúng có một chút hỗn độn, bao
gồm việc lưu trữ dữ liệu văn bản hoặc phá vỡ nó vào nhiều bảng. Một
phần của vấn đề liên quan đến dữ liệu XML
*khứ hồi (round
tripping)*, hoặc lấy lại dữ liệu từ cơ sở dữ liệu theo cấu trúc
giống với trước khi lưu trữ và phần khác liên quan đến việc bạn sử
dụng các truy vấn quan hệ để truy cập dữ liệu đã được cấu trúc
XML.
Mặt khác, các cơ sở dữ liệu XML nguyên gốc thường lưu trữ XML trong cấu trúc chính xác ở chỗ mà chúng nhận được. Các cơ sở dữ liệu XML cũng cung cấp truy cập đến dữ liệu sử dụng ngôn ngữ truy vấn được thiết kế đặc biệt cho XML như XPath, XQuery và XUpdate.
Vì bạn đang làm việc với dữ liệu XML như là một phần của ứng dụng, bạn thực sự cần có khả năng về cơ sở dữ liệu XML nguyên thủy. May thay, bạn có pureXML.
### Dữ liệu XML lưu trữ trong DB2
pureXML là tên thuộc tính cho các bảng DB2. Các bảng này được thiết kế
để lưu các tài liệu XML được tổ chức tốt trong các cột, cùng với các
cột chứa dữ liệu quan hệ. Giống như các kiểu khác nhau của dữ liệu
quan hệ nhị phân, chẳng hạn như
LONG,
VARCHAR, hoặc
LOB,
được lưu trữ tách biệt với các nội dung khác của bảng, dữ liệu XML
được lưu trữ trong các cột của bảng có kiểu XML ở các đối tượng lưu
trữ XML mở rộng. Để sử dụng sức mạnh của các máy truy vấn của DB2 để
quản lý dữ liệu, bạn tách riêng XML với dữ liệu quan hệ mà bạn dùng để
chỉ số hóa nó. Một khi bạn lưu trữ XML và dữ liệu chỉ số quan hệ của
nó, bạn có thể truy cập nó qua một ngôn ngữ truy vấn đặc biệt.
XQuery là ngôn ngữ riêng của XML mà nó có thể truy cập dữ liệu XML sử dụng các biểu thức XPath thay vì SQL. Nó là thành quả của World Wide Web Consortium, bên cạnh XPath 2.0, trong những năm vừa rồi và đã đạt đến điểm mà các sản phẩm chủ đạo như DB2 bắt đầu hỗ trợ cho nó.
XQuery tổ hợp các thủ tục đơn giản (chẳng hạn như vòng lặp) với XPath một cách linh hoạt và mạnh mẽ cho việc lựa chọn và vận chuyển dữ liệu mà bạn không thể thực hiện được với chỉ XPath.
### Bạn định hoàn thành cái gì
Trong phần 1, bạn đã tạo ra một ứng dụng gọi tới một số dịch vụ, thu
nhận dữ liệu từ chúng như một luồng XML và chuyển đổi dữ liệu đó sang
dạng HTML để hiển thị trên trình duyệt (xem
[Các tài nguyên](#resources)). Bởi vì đó là một mashup nên bạn đang xử lý
các dịch vụ. Thực tế, trong trường hợp các dịch vụ con, bạn phải thực
hiện hàng tá hoặc hơn các truy vấn cho một trang. Nếu bạn chạy ví dụ ở
phần 1, bạn có thể khó chịu vì độ dài của các truy vấn đó như thế
nào.
Trong bài viết này, bạn sẽ tạo ra một hệ thống để lưu tạm thời các kết quả trả về từ các dịch vụ khác nhau mà bạn sử dụng. Dữ liệu sẽ chứa thông tin trên URL, thường là yêu cầu dữ liệu, ngày tháng, thời gian yêu cầu được thực hiện cũng như các dữ liệu thực tế trả ra cho yêu cầu.
Trong servlet, trước tiên bạn sẽ kiểm tra cơ sở dữ liệu này, và nếu dữ liệu không tồn tại bạn sẽ yêu cầu một bản sao mới nhất và lưu nó vào cơ sở dữ liệu trong lần tiếp theo.
Bằng cách làm này, bạn có khả năng chuyển một trang có thể chứa một tá hoặc hơn các yêu cầu web (và làm trong một phút hoặc thậm chí hơn) thành các kết quả nhanh chóng. Điều đó cũng dễ dàng hơn nhiều trên các dịch vụ tìm kiếm.
## Cài đặt
Khi bạn thêm vào một máy chủ DB2 thành một hỗn hợp, bạn sẽ cài "deamon" trên một máy chủ thuận tiện nhất. Bạn nên có Tomcat và Apache được cài đặt sẵn, nhưng bạn cũng sẽ cần kết nối Tomcat với cơ sở dữ liệu sử dụng JDBC.
### Cài đặt DB2
Tải về phiên bản dùng thử DB2 9 (xem
[Các điều kiện tiên quyết](#prereq)). Bạn
có thể đăng nhập vào developerWorks và truy cập đến phiên bản beta DB2
mới nhất miễn phí với khả năng hỗ trợ pureXML để lưu trữ XML. Chúng ta
sẽ sử dụng các đặc tính mới này để lưu trữ các đối tượng dữ liệu từ
các truy vấn của ứng dụng.
Một khi bạn đã tải về phần mềm, hãy
giải nén tệp ZIP và đặt tệp
**Setup.exe** vào thư mục
db2\ESE\image. Nhấn đúp chuột và bắt đầu quá trình cài đặt với thuật
sỹ cài đặt (setup wizard). Cửa số đầu tiên là **DB2 Setup
Launchpad** (xem [Hình 1](#fig1)).
##### Hình 1. Setup Launchpad
![ Setup Launchpad](fig01.jpg)
Danh sách bên trái ghi vài lựa chọn, chọn
**Installation
Prerequisites** và **Install a Product**. Các lựa chọn còn
lại chứa những chuyển đổi từ các sản phẩm khác sang và đưa ra các chú
thích cho phiên bản DB2 này. Nếu đây là cài đặt mới, thì sự chuyển đổi
không có tác dụng. Nhưng nếu muốn, bạn hãy tiếp tục và đọc các chú
thích đưa ra để có các thông tin cơ bản về phiên bản DB2
này.
Bắt đầu với Installation Prerequisites, đó là các cài đặt
quyết định thành công của DB2. Danh sách đó nằm ngoài phạm vi của bài
viết này. Bạn hãy cài đặt các thủ tục cập nhật và vá hệ thống. Chúng
tôi khuyên bạn theo dõi các liên kết đã cung cấp ở Setup Launchpad.
Các liên kết sẽ chỉ dẫn cho bạn các thông tin trong phạm vi của yêu
cầu. Các giới hạn thực hiện ở đây chính là việc chắc chắn rằng bạn cập
nhật và hỗ trợ tối thiểu các yêu cầu phần cứng như không gian đĩa và
RAM. Một khi bạn đã xác nhận rằng máy chủ của bạn đáp ứng được hãy
nhấn chọn
**Install a Product** và bắt đầu cài đặt
##### Hình 2. Cài đặt một Product
![ Cài đặt một Product](fig02.jpg)
Khi bạn chọn
**Install a Product** từ thực đơn bên trái, chương
trình cài đặt đưa cho bạn lựa chọn để tạo một cài đặt mới của máy chủ
(server) hoặc máy khách (client). Với các mục tiêu của bài viết này,
bạn sẽ cài đặt cả hai, cho bạn chức năng máy chủ và có khả năng quản
trị máy chủ của bạn sau khi nó được cài đặt. Bắt đầu với Enterprise
Server. Khi cửa sổ cài đặt installation Wizard bắt đầu, bạn chỉ cần
nhấn **Next** cho đến khi có hợp đồng đăng ký (license agreement).
Nếu hợp đồng phù hợp với bạn hãy chấp nhận và nhấn **Next** lần
nữa.
Tiếp theo bạn sẽ lựa chọn cài đặt đặc trưng (typical), rút
gọn (compact) hoặc tùy ý (custom). Chọn cài đặt
**typical** và nhấn
**Next** để di chuyển đến cửa sổ tiếp theo.
Hộp thoại
tiếp theo hỏi bạn nếu muốn cài đặt, hãy lưu lại các cài đặt phản hồi
từ cửa sổ wizard vào một tệp để sử dụng sau. Việc này có lợi khi bạn
cài đặt các server tương tự hoặc nếu bạn định sử dụng các đặc tính môi
trường cơ sở dữ liệu phân hoạch của DB2. Ngay bây giờ, bạn chọn
**Install DB2 Enterprise Server Edition** và nhấn
**Next**.
Ở hộp thoại tiếp theo trong
[hình
3](#fig3), hãy nhập vào đường dẫn nơi mà bạn muốn cài đặt server và
nhấn **Next**, nếu bị nhắc bạn hãy chọn một tên cho việc cài đặt cơ
sở dữ liệu. Trừ phi có lí do nào đó còn nếu không bạn có thể chấp nhận
tên mặc định là DB2_01 và thực hiện cài đặt mặc định này trên máy
tính.
##### Hình 3. Đặt hộp thoại thông tin người dùng
![ Đặt hộp thoại thông tin người dùng](fig03.jpg)
Nếu bạn đang dùng Windows™ XP hoặc NT, bước cài đặt tiếp theo yêu cầu tên miền (Domain) mà tài khoản người dùng của bạn sẽ là thành viên của tên miền đó. Nhưng bạn có thể sử dụng một người dùng hiện có. Cài đặt này sẽ tạo ra một người dùng phục vụ cho mục đích đó, tùy theo bất kỳ nhu cầu của bạn có nằm ngoài phạm vi của bài viết này. Trong bài viết này sử dụng các lựa chọn mặc định.
Chúng ta đang
cài đặt các công cụ phát triển ứng dụng trên cùng một máy, nên hãy
tiếp tục chọn
**None - user local user account** cho Domain và hủy
bỏ username mặc định. Nhập và xác nhận lại mật khẩu và chắc chắn rằng
hộp kiểm ở cuối đã được kiểm tra. Nhấn **Next**.
Bạn sẽ được
hỏi bạn muốn tạo ra máy chủ gì. Hãy sử dụng mặc định của
**DB2** và
nhấn **Next**.
Bạn có thể bỏ qua hộp các công cụ
**Prepare
the DB2 tools catalog** bằng cách không chọn gì ở hộp thoại tiếp
theo và nhấn **Next**.
Bạn không cần khai báo e-mail. Hãy xóa
hộp kiểm
**Set up your DB2 server to send notifications** và nhấn
**Next**.
Để bảo mật dịch vụ DB2 hơn, bạn có thể kích
hoạt người dùng và các nhóm quản trị như là những người nắm giữ hợp lệ
duy nhất đối với dữ liệu DB2 đã lưu trữ và phục vụ. Điều đó là không
cần thiết trong bài học này nhưng nó sẽ không làm tổn hại vì vậy hãy
để nguyên và nhấn
**Next**.
Cuối cùng bạn được xem hộp thoại
với tất cả các lựa chọn bạn đã làm. Nhấn
**Finish** để hoàn tất
việc cài đặt.
### Cài đặt JDBC
Để truy cập DB2 qua JDBC, bạn cần thực hiện một số phân lớp, bao gồm DB2 JDBC driver để hoạt động với Tomcat servlet. Bạn có thể thực hiện việc đó theo một số cách, bao gồm việc thêm vào nó một ứng dụng riêng của bạn. Cách khác là làm cho nó có thể dùng được với tất cả các ứng dụng chạy trên Tomcat. Để làm được điều đó hãy sao chép tệp <DB2_HOME>/sqllib/java/db2java.zip vào thư mục Tomcat's common/lib. Mặc dù đó là tệp zip chứ không phải tệp JAR, máy chủ sẽ tìm ra nó.
## Lưu trữ XML
Bây giờ hãy xem cách DB2 lưu trữ thông tin XML trong cơ sở dữ liệu
### Tạo cơ sở dữ liệu
Trước tiên bạn cần một cơ sở dữ liệu để lưu trữ các đối tượng XML đã trả về. Với các ưu điểm của thuộc tính XML trên DB2, bạn nên cân nhắc kỹ lưỡng để định hình một cơ sở dữ liệu mới. Vì vậy chúng ta sẽ thực hiện từng bước quá trình tạo cơ sở dữ liệu này
Trên thanh taskbar của Windows, trong khay hệ thống có một biểu tượng của máy chủ DB2 với tên là DB2.
Nhấn phải vào biểu
tượng đó và chọn
**DB2 Control Center** để mở DB2 Control Center. Ở
bên phải, bạn sẽ thấy một nhánh thực đơn với hai lựa chọn là All
Systems và All Databases. Nhấn phải chuột vào **All Databases**
chọn **Create Database>Standard**. Việc này sẽ mở ra cửa sổ
thuật sỹ tạo cơ sở dữ liệu được trình bày trong [Hình
4](#fig4).
##### Hình 4. Thuật sỹ (wizard) tạo cơ sở dữ liệu, bước 1
![ Thuật sỹ (wizard) tạo cơ sở dữ liệu, bước 1](fig04.jpg)
Tại đó, bạn được hỏi tên cơ sở dữ liệu là gì và bạn muốn lưu trữ nó ở
đâu. Với bài viết này, bạn dùng
**mashup_1** cho tên và định danh
của cơ sở dữ liệu. Bạn có thể thêm vào bất kỳ tên chú thích nào bạn
muốn.
Tiếp theo hãy chọn nơi bạn sẽ lưu trữ các tệp cơ sở dữ
liệu. Các cơ sở dữ liệu có thể chứa một lượng rất lớn dữ liệu. Hãy
chọn nơi mà có thể quản lý được khối lượng dữ liệu đó của ứng dụng của
bạn. Để phát triển ứng dụng này bạn chỉ lần khoảng 10-20MB bộ nhớ,
nhưng cũng có thể tăng thêm ở một môi trường lớn. Bây giờ hãy chọn một
nơi có không gian nhớ lớn hơn 10MB để có thể dùng được và tạo một thư
mục ở đó. Gõ vào đường dẫn thư mục ở trường
**Default path**. Bạn
có thể nhấn vào Browse và chọn một thư mục theo cách đó.
Nhấn
vào hộp kiểm
**Enable database for XML**. Hộp này yêu cầu bạn cài
đặt kiểu mã là UTF-8. Đó là khóa cho các yêu cầu của bạn.
Hãy
giữ các cài đặt mặc định còn lại và nhấn
**Next** (Xem [Hình 5](#fig5)).
##### Hình 5. Thuật sỹ tạo cơ sở dữ liệu, bước 2
![ Thuật sỹ tạo cơ sở dữ liệu, bước 2](fig05.jpg)
Trình cài đặt sẽ hỏi bạn nơi lưu trữ dữ liệu cho DB một lần nữa. Giữ
nguyên hộp kiểm
**Use the database path as a storage path** và nhấn
**Next** (Xem [Hình 6](#fig6)).
##### Hình 6. Thuật sỹ tạo cơ sở dữ liệu, bước 3
![ Thuật sỹ tạo cơ sở dữ liệu, bước 3](fig06.jpg)
Bạn gặp một chọn lựa quan trọng cho cơ sở dữ liệu mới, đó là sự địa
phương hóa (locale settings). Để các bản XML hoạt động, chúng yêu cầu
bảng mã UTF-8. Bạn có thể chọn bất kỳ mã quốc gia nào nhưng bạn phải
chọn UTF-8 ở danh sách đổ xuống
**Code set**. Để nguyên mục
**Collating Sequence** với các giá trị mặc định của nó và nhấn
**Next** (Xem [Hình 7](#fig7)).
##### Hình 7. Thuật sỹ tạo cơ sở dữ liệu, bước 4
![ Thuật sỹ tạo cơ sở dữ liệu, bước 4](fig07.jpg)
Cuối cùng bạn sẽ hoàn tất được việc cài đặt với màn hình tổng hợp. Hãy
nhấn nút
**Finish** và đợi trong giây lát để hệ thống tạo ra các
tệp khởi tạo và bắt đầu các tiến trình với cơ sở dữ liệu mới của bạn.
Khi cơ sở dữ liệu được hoàn thành, bạn sẽ tìm thấy nó ở cây All
Databases. Bạn có thể mở rộng **mashup_1** và nhìn thấy các thành
phần.
Bây giờ bạn đã có một nơi cho XML, bạn cần định dạng nó để chứa dữ liệu.
### Tạo bảng
Ở phần 1, bạn đã kết nối với hai dịch vụ web Yahoo!
News, Technorati và YouTube, để tập hợp dữ liệu XML và sửa đổi nó đưa
vào cơ sở dữ liệu của bạn (xem
[Các tài
nguyên](#resources)). Hai dịch vụ này cung cấp các định dạng dữ liệu rất
khác nhau nhưng bạn sẽ lưu tất cả chúng vào cùng bảng cơ sở dữ liệu.
Chọn **Tools>Command Editor** trên ứng dụng Control Center. Theo
thường lệ, cách nhanh nhất là sử dụng dòng lệnh và thực hiện các lệnh
trên đó. Trong Command Editor, chèn đoạn mã trong [Ví dụ
1](#c1)
vào.
##### Ví dụ 1. Tạo bảng queryResults
connect to MASHUP_1; create table queryresults (id INT generated always as identity, requestdate TIMESTAMP, query XML)
Sau
khi bạn nhập đoạn mã vào cửa sổ Command Editor, nhấn
**Execute** và
chờ thông báo "The SQL command completed successfully" thể hiện câu
lệnh SQL đã hoàn thành.
Cột id là khóa chính và cột requestdate
là cột quan hệ đặc thù biểu diễn ngày giờ của truy vấn gốc. Mặt khác,
cột query là một giá trị XML. Cấu trúc của nó biến đổi dựa trên dữ
liệu được trả về cho truy vấn. Ví dụ, bạn có thể có hai dòng cơ sở dữ
liệu khác nhau như trong
[Ví dụ
2](#c2).
##### Ví dụ 2. Các dòng cơ sở dữ liệu mẫu
1, 2006-07-25-13.26.46,<?xml version="1.0" encoding="ISO-8859-1"?> <tv source-info-url="http://labs.zap2it.com/" source-info-name="TMS Data Direct Service" generator-info-name="XMLTV" generator-info-url="http://www.xmltv.org/"> <programme start="20060714043000 -0400" stop="20060714050000 -0400" channel="I21883.labs.zap2it.com"> <title lang="en">Flintstones</title> <sub-title lang="en">The Gravelberry Pie King</sub-title> <desc lang="en">Fred gets fired and enters the pie-baking business.</desc> <credits> <actor>Alan Reed</actor> <actor>Jean Vander Pyl</actor> <actor>Mel Blanc</actor> <actor>Gerry Johnson</actor> <actor>Don Messick</actor> </credits> <date>19651112</date> <category lang="en">Children</category> <category lang="en">Animated</category> <category lang="en">Series</category> <episode-num system="dd_progid">EP001648.0149</episode-num> <episode-num system="onscreen">65149</episode-num> <subtitles type="teletext" /> <rating system="VCHIP"> <value>TV-G</value> </rating> </programme> <programme start="20060714050000 -0400" stop="20060714053000 -0400" channel="I21883.labs.zap2it.com"> <title lang="en">Dastardly & Muttley</title> <sub-title lang="en">Muttley On the Bounty</sub-title> <category lang="en">Children</category> <category lang="en">Animated</category> <category lang="en">Series</category> <episode-num system="dd_progid">EP001168.0006</episode-num> <episode-num system="onscreen">6901</episode-num> <rating system="VCHIP"> <value>TV-G</value> </rating> </programme> </tv> 2, 2006-07-25-13.38.46,<tapi version="1.0"> <document> <result> <url>http://www.chaosmagnet.com</url> <inboundblogs></inboundblogs> <inboundlinks>25</inboundlinks> <rankingstart>0</rankingstart></result> <item> <weblog> <name>Gary Said... ( The blog of Gary LaPointe )</name> <url>http://garysaid.com</url> <rssurl>http://garysaid.com/index.rdf</rssurl> <atomurl></atomurl> <inboundblogs>60</inboundblogs> <inboundlinks>2161</inboundlinks> <rank></rank> <lastupdate>2006-07-24 20:26:25 GMT</lastupdate> </weblog> <nearestpermalink>http://garysaid.com</nearestpermalink> <excerpt>Doug Dave (goodness) Angela (fluid) Tonya Martha Racheline Heather (dooce) ZuDfunck Ryan (fait) Eleanor alisa Kristin Elizabeth Sherri Meg Jacqueline Melissa (geek) James (american) Nicholas Lorna Evie Rachael Kachina Jeff (geekable) Tim Samantha SarahB Melissa (stars) David Kates Christine (pink) Kristine Psychbloke KelliDiane Clancy Molly.com Ryan (rant) Todd Nikita</excerpt> <linkcreated>2006-07-14 19:59:03 GMT</linkcreated> <linkurl>http://www.chaosmagnet.com/blog/</linkurl> </item> </document> </tapi>
Cho dù các dòng đều có cấu trúc cơ sở dữ liệu như nhau, không có hạn chế nào áp đặt cho cấu trúc XML được chứa trong các cột truy vấn.
Nhưng đôi khi đó không phải là những gì bạn muốn.
### Dữ liệu hợp lệ
Các chuyên gia cơ sở dữ liệu đôi khi lo lắng về chất lượng dữ liệu khi dùng XML vì tính tự nhiên linh hoạt của nó. Do chúng ta có thể lưu trữ bất kỳ tài liệu XML nào vào bất kỳ cột nào được xác định bởi một kiểu dữ liệu XML mới trong DB2, nên bạn có thể dễ dàng rơi vào hậu quả là các cấu trúc dữ liệu XML bị thay đổi hoặc mâu thuẫn với sự logic ứng dụng của bạn. Nhà cung cấp dữ liệu có thể thay đổi cấu trúc của XML đầu ra mà không hề thông báo cho bạn. Mashup của bạn dùng ba nguồn dữ liệu khác nhau với ba cấu trúc tệp khác nhau và ngay lập tức sự thay đổi thể hiện trên bản thân nó. Trong khi bạn đang cân nhắc tạo ra một kết quả trong một cột XML chứa các dữ liệu khác nhau, DB2 cho phép bạn có thể liên kết một lược đồ với một cột cơ sở dữ liệu và cho phép chèn hoặc cập nhật dữ liệu một cách hợp lệ trước khi thêm nó vào cơ sở dữ liệu.
Trước khi bạn có thể làm cho dữ liệu trong
bảng XML thành hợp lệ, bạn cần định nghĩa một lược đồ XML mà chỉ ra
các thành phần XML, thứ tự của chúng và kiểu dữ liệu, ... có thể chấp
nhận được. Bạn có thể tạo một lược đồ XML theo nhiều cách, và các nhà
cung cấp dữ liệu đôi khi sẽ cung cấp một liên kết tới một lược đồ XML
trong tài liệu XML của họ. Các đặc tả của một lược đồ XML nằm ngoài
phạm vi của bài viết này, vì vậy hãy chuyển đến bước tiếp theo và đăng
kí lược đồ XML hợp lệ của bạn (Xem
[Ví dụ
3](#c3)).
##### Ví dụ 3. Đăng kí một lược đồ XML
connect to another database; register xmlschema 'http://mysample.org' from 'C:/XMLFILES/bigxmlfile.XSD' as user1.mysample complete;
Trong Command Editor, kết nối đến cơ sở dữ liệu và đưa ra lệnh để đăng kí cho bigxmlfile.xsd như là một lược đồ với tên user1.mysample. Thao tác này được lưu lại kho bên trong của DB2 dưới lược đồ SQL có tên user1 và lược đồ XML có tên mysample. Mệnh đề complete cho biết DB2 hoàn thành việc đăng kí và thực hiện lược đồ với dữ liệu hợp lệ đã được chèn vào bảng user1.
Sự hợp lệ không tự động mà sẽ yêu cầu bạn
chỉ rõ cơ sở dữ liệu hợp lệ với các lược đồ của bạn khi bạn dùng câu
lệnh INSERT. Khi chèn tệp XML vào một trường XML bạn sẽ cần dùng hàm
XMLVALIDATE(). Hàm này chỉ ra lược đồ
đã đăng kí trước đó hợp lệ với cái gì. Nếu tệp không phù hợp với lược
đồ, cơ sở dữ liệu trả về một lỗi thay vì thêm một dòng vào cơ sở dữ
liệu.
Vì bạn có thể chọn một lược đồ ở thời điểm chèn, bạn có thể dùng hàm này để hợp lệ dữ liệu với mỗi dịch vụ khác. Nhưng chúng ta sẽ để nó như là một bài tập cho người đọc.
### Chèn XML sử dụng SQL
Giờ bạn đã có cấu trúc mẫu cho dữ liệu của mình để tập trung vào nó. Bạn có thể thực hiện câu lệnh INSERT trước tiên để đặt dữ liệu vào. Bạn sẽ dùng SQL để chèn dữ liệu vào bảng, từ đó bạn sẽ không thực thi bất kì thao tác nào trên đó cho đến khi nó đã đúng vị trí. Để làm điều này bạn dùng lại Command Editor và gửi một truy vấn SQL tới máy chủ có chứa các tệp XML của mình và đặt nó vào bảng.
##### Ví dụ 4. Chèn câu trả lời Yahoo!
connect to MASHUP_1; connect to MASHUP_1;
INSERT INTO queryResults (requestdate, query) VALUES(CURRENT TIMESTAMP,XMLPARSE(documentcast('<queryData><queryType>REST</queryType> <queryUrl>http://api.search.yahoo.com/NewsSearchService/ V1/newsSearch?appid=mashupid&type=all&query=New+York </queryUrl> <result> <Title>Star Wars force falls for Hasbro</Title><Summary>Falling sales of lightsabers and other Star Wars merchandise has dented US toymaker Hasbro's revenues.</Summary><Url>http://news.bbc.co.uk/go/rss/- /1/hi/business/5212750.stm</Url><ClickUrl>http://news.bbc.co.uk /go/rss/ -/1/hi/business/5212750.stm</ClickUrl><NewsSource>BBC News</NewsSource><NewsSourceUrl>http://news.bbc.co.uk/ </NewsSourceUrl><Language>en</Language><PublishDate> 1153835696</PublishDate><ModificationDate>1153835698 </ModificationDate></result></queryData>' as clob) preserve whitespace))
Nhìn bề ngoài, đây là một truy vấn SQL chuẩn, chỉ rõ các cột và các giá trị. Giá trị thứ nhất, giá trị TIMESTAMP là ngày giờ hiện tại. Giá trị thứ hai, query, là một giá trị XML. Để chèn vào, bạn cần có một đối tượng XML, cái mà bạn nhận được khi gọi hàm XMLPARSE với tham số kiểu đối tượng (document) và đối tượng để phân tích. Để làm cho văn bản có giá trị, đoạn mã sử dụng nó như một CLOB hoặc đối tượng lớn kí tự.
Đây là một câu lệnh chèn (insert) chuẩn của SQL nếu bỏ qua phần chuyển đổi trên.
Sau khi nhập đoạn mã đó và cửa sổ Command
Editor, nhấn
**Execute** và chờ thông điệp "The SQL command
completed successfully" nói rằng câu lệnh SQL đã được hoàn
thành.
Hãy vào Control Center và mở Database. Mở rộng các bảng
và cuốn qua các bảng mặc định. Khi bạn tìm thấy bảng
**queryResults** hãy chọn nó. Ở phía dưới panel, chọn
**actions open** để xem bảng hộp thoại Open table dialogue.
Trước tiên, chọn dòng duy nhất mà bạn đã thêm SQL và nhấn **Fetch
XML**. Bạn nhấn vào nút có nhãn **...** để mở hộp thoại chứa
lược đồ XML và cấu trúc nút mà bạn đã vừa mới thêm.
Chúc mừng! Bạn vừa mới cài đặt xong một máy chủ cơ sở dữ liệu, đã tạo ra một cơ sở dữ liệu và cuối cùng đưa dữ liệu XML vào cơ sở dữ liệu. Bây giờ hãy xem làm thế nào để đưa dữ liệu lại cho ứng dụng sử dụng.
## Tạo các truy vấn
Bây giờ bạn đã có dữ liệu trong cơ sở dữ liệu, hãy xem lại chúng.
### SQL hay XQuery?
Như chúng tôi đã đề cập trước đó, DB2 cung cấp công cụ hỗ trợ cho ngôn
ngữ truy vấn của W3C được gọi là XQuery. Bạn có thể thực hiện các truy
vấn phức tạp đối với dữ liệu XML đã lưu trữ, tận dụng sức mạnh của các
biểu thức. Các biểu thức trong một XQuery được biểu diễn là các mệnh
đề hoặc các mệnh đề lồng nhau. Mệnh đề đầu tiên trong số các mệnh đề
đó là mệnh đề tương tự như kiểu câu lệnh SQL "SELECT FROM WHERE", được
gọi là một biểu thức FLWOR. Một biểu thức XPath giống như một đường
dẫn dữ liệu ở một tệp tin hệ thống, các bước qua các nút con của lược
đồ XML cho đến khi một điểm dữ liệu được tìm thấy. Với một bộ làm mới
trên XPath, xem phần 1 của loạt bài này (xem
[Các tài nguyên](#resources)). Trong khi bạn vẫn có thể sử dụng SQL để truy
cập vào dữ liệu XML trong DB2, XQuery cho các đặc trưng bổ sung riêng
cho XML. Bạn có thể sử dụng các ưu điểm đó trong mashup của mình.
### FLWOR
FLWOR là những chữ cái đầu giành riêng cho biểu thức trong ngôn ngữ XQuery:
FOR: Lặp qua một chuỗi đầu vào, liên kết một biến với lần lượt mỗi mục đầu vào
LET: Khai báo một biến và gán cho nó một giá trị, giá trị có thể là một danh sách các mục
WHERE: Xác định rõ phạm vi lọc các kết quả truy vấn
ORDER BY: Xác định rõ trật tự sắp xếp các kết quả
RETURN: Xác định kết quả được trả về
Xem
[Ví dụ 5](#c5) để thấy FLWOR
##### Ví dụ 5. Ví dụ truy vấn FLWOR
for $statement in document(https://www.sample.com/sample.xml)//post let $comment := $statement/comment where $statement/postedby = 'userBob' return <quoteBob>{$comment}</quoteBob>
Đoạn mã trong
[ví dụ 5](#c5) gán tất cả các phần tử post
trong một tài liệu XML được tìm thấy ở https://www.sample.com//post
vào một biến được gọi là
$statement sử dụng
câu lệnh
FOR. Câu lệnh
LET cho thêm một biến
$comment
lưu lần lượt mỗi thành phần <comment> của phần tử post, nhưng
chỉ trong điều kiện của
WHERE giá trị các
phần tử <postedby> là userBob. Sau đó chúng ta trả về thông tin
trên XML, lặp đi lặp lại qua các kết quả, và tạo nên đầu ra qua mệnh
đề
RETURN. Các kết quả giống như
[Ví dụ 6](#c6) sau đây.
##### Ví dụ 6. mẫu đầu ra từ một truy vấn FLWOR
<quoteBob<Man, this is insightful.</quoteBob< <quoteBob>Riveting. Absolutely riveting.</quoteBob< <quoteBob>My eyes! My eyes!!!</quoteBob<
Hãy tìm hiểu qua mỗi loại mệnh đề một cách kỹ lưỡng
FOR
Câu lệnh
FOR lặp qua mỗi nốt trong một chuỗi
đầu vào, gắn các nốt đó với một biến và sau đó chuyển đến bước tiếp
theo (xem
[Ví dụ 7](#c7)).
##### Ví dụ 7. Ví dụ về câu lệnh
FOR
<results> { for $result in document("http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid =mashupid&type=all&query=star+wars")/ResultSet/Result return <articles> { <article> { $$result/Title }: {$result/Summary} </article> } </results>
Nếu bạn đã dùng câu lệnh giống như trong
[Ví dụ 7](#c7), bạn
sẽ có đầu ra là một nốt <article> với mỗi Title và Summary được
trả về bằng ResultSet/Result giống như trong [Ví dụ
8](#c8).
##### Ví dụ 8. Đầu ra của câu lệnh
FOR
<results> <results> <article> 'Star Wars' sales cut Hasbro results': YESTERDAY Close $19.16 Change $1.66 52-WEEK High $22.10 Low $17.00 Hasbro Inc., the nation's second-largest toy maker, said yesterday that earnings and revenue declined in the second quarter, due in part to an anticipated drop in "Star Wars" product sales. </article> <article> 'Star Wars' toys hit Hasbro profit: Hasbro said quarterly profits fell 8% on lower sales of "Star Wars" toys. </article> </results>
Đây là một khác biệt với mệnh đề
LET trong
trường hợp quan trọng.
LET
LET kết nối một biến vào một chuỗi các nốt
và có thể kết nối nhiều hơn một biến từ nhiều hơn một đường dẫn. Hãy
xem
[Ví dụ 9](#c9).
##### Ví dụ 9. Ví dụ câu lệnh
LET
<results> { let $t := document("http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid =mashupid&type=all&query=star+wars")/ResultSet/Result/title $s := document("http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid =mashupid&type=all&query=star+wars")/ResultSet/Result/summary return <articles> { $t } { $s } </articles> </results>
Ví dụ này trả về một nốt <articles> với vài nốt con, đó là một
danh sách các tiêu đề và các bản tóm tắt.
LET trả về tất cả các kết quả và không có trùng lặp. Bạn
có thể nhận thấy đầu ra của câu lệnh này giống như trong
[Ví dụ 10](#c10).
##### Ví dụ 10. Đầu ra
<results> <articles> <title>Star Wars Sales Cut Hasbro results</title> <title> Star Wars force falls for Hasbro</title> <summary> Falling sales of lightsabers and other Star Wars merchandise has dented US toymaker Hasbro's revenues.</summary> <summary> YESTERDAY Close $19.16 Change $1.66 52-WEEK High $22.10 Low $17.00 Hasbro Inc., the nation's second-largest toy maker, said yesterday that earnings and revenue declined in the second quarter, due in part to an anticipated drop in "Star Wars" product sales.</summary> </articles> </results>
WHERE
Mệnh đề
WHERE đánh giá dữ liệu ở một nốt mỗi
lần câu lệnh cố gắng
RETURN (trả lại) thông
tin (Xem
[Ví dụ 11](#c11)).
##### Ví dụ 11. Ví dụ truy vấn
WHERE
<results> { for $result in document("http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid =mashupid&type=all&query=star+wars")/ResultSet/Result where $result/newssource = "BBC News" return <article> { $$result/Title }: {$result/Summary} </article> </results>
Mỗi lần câu lệnh chuẩn bị trả thông tin về, đó là từng nốt /bib/book
trong tệp bib.xml, mệnh đề
WHERE kiểm tra
xem nốt book/year có lớn hơn 1992 không. Trong trường hợp này, bạn
giới hạn đầu ra từ tệp XML vào những sách ở các nốt thỏa mãn điều
kiện. Mệnh đề
WHERE của XQuery hoạt động
giống như mệnh đề
WHERE trong SQL. Hơn nữa,
vì bạn giới hạn các kết quả, nên các kết quả được trả về tương ứng kết
quả mỗi lần lặp, giống như mệnh đề
FOR.
RETURN
Mệnh đề
RETURN cho phép bạn định dạng đầu ra
XML khi cần thiết (Xem
[Ví dụ 12](#c12)).
##### Ví dụ 12. Ví dụ về
RETURN
return <article> { $$result/Title }: {$result/Summary} </article>
Trong ví dụ này, các định dạng trả về các kết quả bên trong một nốt XML có tên <bookInfo> nhưng bạn có thể tạo bất kỳ định dạng đầu ra nào bạn muốn.
### Sử dụng XQuery
Để sử dụng XQuery như là một ngôn ngữ truy vấn trực tiếp thay cho SQL,
bạn phải xác định ngay từ đầu với phát biểu
xquery (Xem
[Ví dụ 13](#c13)).
##### Ví dụ 13. Một mẫu XQuery
connect to mashup_1; xquery db2-fn:xmlcolumn('QUERYRESULTS.QUERY')
Như thường lệ, trước tiên bạn phải kết nối với cơ sở dữ liệu DB khi
chúng ta đang dùng Command Editor. Bạn có thể sử dụng phương pháp khác
kết nối đến cơ sở dữ liệu, chẳng hạn như khi bạn truy cập JDBC trong
mã Java. Phần cốt yếu của ví dụ này là
Xquery. Trước tiên, bạn bắt đầu câu Xquery để chuẩn bị máy
chủ cho cái gì sẽ đến tiếp theo. Bạn đưa ra bối cảnh của cơ sở dữ liệu
và bạn đang trả lời cho loại dữ liệu gì, trong trường hợp này là một
XMLCOLLUMN. Tiếp theo bạn đưa ra đường dẫn đến cơ sở dữ liệu, đó là
trong bảng: QUERYRESULTS và cột:QUERY. Điều đó sẽ trả về ví dụ XML đã
lưu trữ trước đó của bạn. Trong trường hợp này hàm
db2-fn:xmlcolumn() giống như hàm
document() của XPath.
## Kết hợp XML với SQL
Bạn có thể truy cập dữ liệu trong DB2 theo nhiều cách. Tùy theo mục đích của bạn mà bạn có thể dùng cách nào đó. Bạn có thể kết hợp các câu lệnh FLWOR với các SQL truyền thống cho phép bạn chọn các bản ghi dựa trên cả dữ liệu quan hệ và dữ liệu XML.
### Trả về dữ liệu (bao gồm cả XML) dựa trên dữ liệu quan hệ
Trong ứng dụng của mình, bạn sử dụng dữ liệu quan hệ ở trong lược đồ
của mình. Chúng cho phép bạn kiểm tra tính chất mới của một bản ghi
bằng cách giữ một timestamp. Thay vì trả về tất cả dữ liệu XML trong
bảng, bạn có thể lọc các thông tin được trả về dựa trên các cột
resultDate của bảng queryResults như trong
[Ví dụ
14](#c14).
##### Ví dụ 14. Lọc các thông tin được trả về
select id, xmlserialize(query as clob) from QUERYRESULTS where requestDate > '2006-07-23-07.45.00'
Sử dụng hàm
xmlserialize() sau đó bạn có thể
phân tích cú pháp một đối tượng nếu cần thiết.
Bạn cũng có thể chỉ chọn một phần của dữ liệu XML đã yêu cầu sử dụng
các lệnh XPath như trong
[Ví dụ 15](#c15).
##### Ví dụ 15. Một câu lệnh XPath
select requestdate, xmlquery('$q//queryUrl' passing query as "q") from queryresults where requestDate >'2006-07-23-07.45.00'
Hàm
xmlquery() cho biết cơ sở dữ liệu xử lý
một truy vấn XQuery. Trong trường hợp này là một biểu thức XPath đơn
giản.
### Trả về dữ liệu (bao gồm cả XML) dựa trên dữ liệu XML
Bạn cũng có thể truy vấn dựa trên nội dung XML. Thí dụ, bạn có thể chọn
tất cả các ngày và giờ bạn đã yêu cầu từ một kiểu truy vấn riêng, như
trong
[Ví dụ 16](#c16).
##### Ví dụ 16. Chọn các ngày và giờ.
Select requestDate from QUERYRESULTS where xmlexists('$c/queryData[queryType="REST"]' passing queryresults.query as "c")
Bạn có thể sử dụng câu truy vấn này để chọn cả requestDate và cột
queryUrl từ XML (xem
[Ví dụ 17](#c17)).
##### Ví dụ 17. Chọn requestDate và queryUrl
select requestdate, xmlquery('$q/queryData/result' passing query as "q") from queryresults where requestDate > '2006-07-23-07.45.00' and xmlexists('$c/queryData[queryType="REST"]' passing queryresults.query as "c") and xmlexists('$c/queryData[queryUrl="http://api.search.yahoo.com/NewsSearchSer vice/V1/newsSearch?appid=mashupid&type=all&query=New+York"]' passing queryresults.query as "c")
Ở
[ví dụ 17](#c17) đoạn mã yêu cầu cột requestdate và
phần tử kết quả từ cột truy vấn với tất cả các bản
ghi thỏa mãn cả 3 thành phần của mệnh đề where: requestDate, nội dung
của phần tử
queryType và nội dung của
queryData.
(Chú ý rằng có thể tổ hợp các yêu cầu XML-quan hệ vào một câu lệnh XPath đơn nhưng nếu làm như vậy bạn phải tìm XML đã trả về trong một cấu trúc ngắn gọn).
### Sử dụng XQuery trong câu lệnh SQL
Sử dụng XQuery trong một câu lệnh SQL là việc kết hợp nó vào câu lệnh
SELECT, như trong
[Ví dụ
18](#c18).
##### Ví dụ 18. Sử dụng XQuery trong câu lệnh SQL
select XMLSERIALIZE(xmlquery('for $r in $c/queryData/result return $r ' passing queryresults.query as "c") AS CLOB) from queryresults where requestDate > '2006-07-23-07.45.00' and xmlexists ('$c/queryData[queryType="REST"]' passing queryresults.query as \"c\")
Trong ví dụ này, bạn sử dụng câu lệnh XQuery giống như khi bạn đã từng
dùng nó trước đó, nhưng bạn chứa nó trong hàm
xmlquery() để có thể sử dụng nó trong một lệnh SELECT
thông thường.
### Xóa và cập nhật dữ liệu XML
Để xóa và cập nhật các bản ghi DB2 có chứa XML cũng giống như thực thi các thao tác đó đối với một bảng DB2 điển hình. Không may, bạn không thể chỉ biến đổi một phần của một cột XML. Thay vào đó, bạn phải cập nhật giá trị của cột XML với toàn bộ tài liệu cho dù chỉ một ít văn bản thay đổi.
Bạn sẽ không thực hiện bất kỳ phép xóa và cập nhật nào ở phiên bản này của mashup.
## Tích hợp với mashup
Giờ bạn đã hiểu các truy vấn làm việc như thế nào, bạn có thể thêm chúng vào mashup servlet. Thực thi các truy vấn là việc thực hiện các truy vấn JDBC đơn giản nhưng với các truy vấn XML-quan hệ thay vì SQL truyền thống. Cũng như vậy, thay vì các giá trị đơn giản, ta lấy về một chuỗi XML đã cấp phát và sau đó bạn có thể đặt chúng vào một đối tượng của mô hình đối tượng tài liệu DOM (Document Object Model).
### Dự án của bạn đặt ở đâu.
Bạn đang có một servlet. Nó lặp qua một nhóm các dịch vụ xác định trước, gọi dữ liệu ra từ
URL của chúng và chuyển vào một trang web phù hợp. Trước khi thực hiện các thay đổi với
cơ sở dữ liệu, xem đoạn mã trong
[ví dụ 19](#c19).
##### Ví dụ 19. Đoạn mã
import java.io.IOException; import import java.io.IOException; import java.io.StringReader; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; public class MashupClientServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { public MashupClientServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().print("<html>"); ... response.getWriter().print("</html>"); }
public static Document getData (String query) { try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document; document = builder.parse(query); return document; } catch (Exception e) { System.out.println(e.getMessage()); return null; } }public static Node renderService(String query, Service svc, Document hostDoc){ Document document = getData(svc.baseURL+query); if (document != null){ try { Node serviceElement = hostDoc.createElement("span"); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); XPath xpath = XPathFactory.newInstance().newXPath(); String expression = svc.recordExp; NodeList recordNodes = (NodeList) xpath.evaluate( expression, document, XPathConstants.NODESET); Node toImport = null; for (int i=0; i < recordNodes.getLength(); i++) { Document templateDoc = builder.parse( new InputSource(new StringReader(svc.template))); ... } toImport = hostDoc.importNode( templateDoc.getDocumentElement(), true); serviceElement.appendChild(toImport); } return serviceElement; } catch (Exception e){ e.printStackTrace(); return null; } } else { System.out.println( "Get Data returned null. What do we do now?"); return null; } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String query = request.getParameter("query").toString(); try { DocumentBuilder builder = DocumentBuilderFactory .newInstance().newDocumentBuilder(); Service[] svcs = Service.getServices(); Document hostDoc = builder.parse( new InputSource(new StringReader("<results/>"))); Node hostRoot = hostDoc.getDocumentElement(); for (int k=0; k < svcs.length; k++){ Service svc = svcs[k]; Node renderedService = renderService(query, svc, hostDoc); if (renderedService != null){ Element nameElement = hostDoc.createElement("h1"); nameElement.appendChild( hostDoc.createTextNode(svc.name)); Node serviceElement = hostDoc.createElement("span"); serviceElement.appendChild(nameElement); serviceElement.appendChild(renderedService); hostRoot.appendChild(serviceElement); hostRoot.appendChild(hostDoc.createTextNode("\n")); } } DOMSource source = new DOMSource(hostDoc); StreamResult result = new StreamResult(response.getWriter()); TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer transformer = transFactory.newTransformer(); transformer.transform(source, result); } catch (Exception e){ e.printStackTrace(response.getWriter()); } } }
Bạn có thể xem toàn bộ ví dụ trong các tệp mã nguồn mà bạn
[tải về](#download)
cho bài viết này, nhưng [ví dụ 19](#c19) cho bạn ý tưởng chung nhất về việc bạn đang
làm việc với cái gì. Bạn nên hiểu ít nhất một thay đổi từ đoạn mã khi nó đã đặt ở cuối phần 1
(xem [Tài nguyên](#resources)); Servlet có được dữ liệu thực tế bằng các
phương pháp riêng của nó. Nếu bạn đang xây dựng sản phẩm thực sự, bạn có thể thực hiện các
thay đổi để làm tăng độ bền vững của việc xử lý các trường hợp ngoại lai, v.v.. Cấu trúc này
có hai ưu điểm. Thứ nhất, nó làm cho việc bẫy các lỗi dễ hơn khi tải các thông tin đầu vào (feed)
(chẳng hạn một dịch vụ mà bị ngưng hoặc trả về XMl không hợp lệ). Thứ hai, nó làm cho việc thêm
vào chức năng mới thuận tiện hơn.
Nhưng các tính năng mới đó là gì?
Các tính năng có hai dạng. Thứ nhất, servlet kiểm tra cơ sở dữ liệu với dữ liệu đã lưu trữ có tương ứng với truy vấn hiện tại hay không trước khi thừa nhận việc nó cần phải tải về bản sao mới. Nếu nó tìm ra dữ liệu đã lưu trữ, nó dùng dữ liệu đó thay vì thực hiện một yêu cầu mới. Việc này có thể tiết kiệm vài phút cho mỗi trang nếu trang đó có nhiều yêu cầu dịch vụ được kết nối bên trong.
Thứ hai, nó ghi dữ liệu vào cơ sở dữ liệu ở vị trí đầu tiên. Hãy bắt đầu với dạng thứ hai này.
### Chuẩn bị ghi dữ liệu
Bước thứ nhất là ghi lại mỗi yêu cầu mới được tải về vào cơ sở dữ liệu. Xem
[ví dụ 20](#c20).
##### Ví dụ 20. Lưu dữ liệu vào cơ sở dữ liệu
...
public static void saveData(String queryUrl, Document document){ try{ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document saveDocument = builder.parse( new InputSource(new StringReader("<queryData/>"))); Element typeElement = saveDocument.createElement("queryType"); typeElement.appendChild(saveDocument.createTextNode("REST")); Element queryUrlElement = saveDocument.createElement("queryUrl"); queryUrlElement.appendChild( saveDocument.createTextNode(queryUrl.replaceAll("&", "[[ampersand]]"))); Element rootElement = saveDocument.getDocumentElement(); rootElement.appendChild(typeElement); rootElement.appendChild(queryUrlElement); Element resultData = saveDocument.createElement("result"); Node dataToSave = saveDocument.importNode( document.getDocumentElement(), true); resultData.appendChild(dataToSave); saveDocument.getDocumentElement().appendChild(resultData); DOMSource domSource = new DOMSource(saveDocument); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.transform(domSource, result); String dataString = writer.toString(); } catch (Exception e){ e.printStackTrace(); } }public static Node renderService(String query, Service svc, Document hostDoc){ ...
Bạn có thể gói gọn tất cả các thao tác vào một phương thức
savedata(). Đối số của phương thức là URL truy vấn gốc và tài liệu được trả về bởi dịch vụ web. Để bắt đầu hãy tạo một tài liệu mới với một phần tử gốc
queryData và sau đó thêm
queryType và các phần tử
queryUrl. Chú ý rằng XML có sử dụng kí tự đặc biệt là kí tự & Bạn không thể sử dụng chúng ở truy vấn XPath. (Vì bạn sẽ không sử dụng dữ liệu gọi một cách trực tiếp bất kì dịch vụ nào) để viết nội dung của thành phần
queryUrl bạn thay kí tự
& bằng
[[ampersand]]. Miễn là bạn làm một việc tương tự khi tìm kiếm. Bạn sẽ tìm ra dữ liệu. Từ đó bạn tạo thành phần kết quả và nhập dữ liệu vào đối tượng Document mới để bạn có thể thêm nó vào thành phần mới.
Khi bạn đã thêm thành phần kết quả vào saveDocument thì bạn đã sẵn sàng cho việc chèn dữ liệu vào cơ sở dữ liệu. Để làm điều đó bạn cần một xâu biểu diễn của Document. Bạn có thể có nó bằng việc tạo ra một đối tượng StringWriter và sử dụng nó như là kết quả của phép biến đổi đồng nhất.
Giờ bạn có thể lưu nó vào cơ sở dữ liệu.
### Lưu dữ liệu
Việc lưu dữ liệu vào cơ sở dữ liệu là liên quan đến truy vấn, cũng giống như bạn làm với bất kì thao tác JDBC nào. Trong trường hợp này, dễ nhất là sử dụng một PreparedQuery. Hãy xem
[ví dụ 21](#c21).
##### Ví dụ 21. Lưu dữ liệu vào cơ sở dữ liệu
import java.io.IOException; import java.io.StringReader;
import java.io.StringWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.sql.PreparedStatement; import java.util.Properties;... public class MashupClientServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { ... public static void saveData(String queryUrl, Document document){ try{ ... saveDocument.getDocumentElement().appendChild(resultData); DOMSource domSource = new DOMSource(saveDocument); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.transform(domSource, result); String dataString = writer.toString(); String alias = "mashup_1"; String userId = "myuserid"; String password = "mypassword"; Properties props = new Properties(); String url = "jdbc:db2:" + alias; Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance(); props.setProperty("user", userId); props.setProperty("password", password); props.setProperty("CONNECTNODE", "0"); Connection con = DriverManager.getConnection( url, props ); con.setAutoCommit(false); PreparedStatement stmt = con.prepareStatement( "INSERT INTO queryResults (requestdate, query) " + "VALUES(CURRENT TIMESTAMP,XMLPARSE(" + "document cast(? as clob) preserve whitespace))"); stmt.setString(1, dataString); stmt.execute(); stmt.close(); con.commit(); con.close(); } catch (Exception e){ e.printStackTrace(); } }public static Document getData (String query) { try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document; document = builder.parse(query); saveData(query, document);return document; } catch (Exception e) { System.out.println(e.getMessage()); return null; } } public static Node renderService(String query, Service svc, Document hostDoc){ ...
Như ở bất kỳ ứng dụng JDBC nào khác, bạn bắt đầu bằng việc định nghĩa các thuộc tính
của kết nối và thiết bị được sử dụng cho kết nối đó. (Lớp thiết bị đó là một phần
của tệp db2java.zip mà bạn đã thêm vào Tomcat.) Sau đó bạn có thể tạo một kết nối
thực tế và thiết lập trạng thái an toàn. (Bởi vì bạn không sử dụng các giao tác
(transactions) nên bạn có thể dễ dàng đặt
autoCommit là true.)
Từ đó bạn tạo một
PreparedStatement mà chứa một câu lệnh
SQL giống như ở
[ví dụ 4.](#c4) Sự khác biệt ở đây đó là:
bạn có thể chứa một placeholder, như được chỉ ra bằng dấu hỏi chấm (?) vào trong
cái mà bạn có thể thiết lập dữ liệu sử dụng phương thức
setString().
Trong trường hợp này bạn chuyển hướng dữ liệu vào một CLOB (đối tượng lớn dữ liệu).
Sau đó sử dụng hàm
XMLPARSE() chuyển dữ liệu vào một Document.
Khi bạn đã tạo và định vị
PreparedStatement bạn có thể
thực hiện và đóng nó lại, sau đó xác nhận câu lệnh và ngắt kết nối.
Tất cả điều đó xảy ra khi bạn gọi hàm
saveData() ngay
lập tức sau khi lấy dữ liệu mới.
### Kiểm tra bộ đệm dữ liệu
Khi bạn có dữ liệu trong cơ sở dữ liệu, bạn cần phải kiểm tra nó. Bạn thực hiện
điều đó với phương thức
checkCache(). Phương thức lấy
một truy vấn và tìm kiếm dữ liệu từ truy vấn đó trong cơ sở dữ liệu với các
khoảng thời gian riêng. Ví dụ, tìm kiếm dữ liệu từ truy vấn
http://www.technorati.com/tag=Java đã lưu trong giờ qua. Bạn có thể xem truy vấn
này làm việc như thế nào trong
[ví dụ 22](#c22).
##### Ví dụ 22. Kiểm tra nơi lưu trữ
... import org.w3c.dom.NodeList; import org.xml.sax.InputSource;
import java.util.Calendar; import java.text.SimpleDateFormat;public class MashupClientServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { public MashupClientServlet() { super(); } ... public static String checkCache(String query){ try{ String alias = "mashup_1"; String userId = "myusername"; String password = "mypassword"; Properties props = new Properties(); String url = "jdbc:db2:" + alias; Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance(); props.setProperty("user", userId); props.setProperty("password", password); props.setProperty("CONNECTNODE", "0"); Connection con = DriverManager.getConnection( url, props ); con.setAutoCommit(false); Statement stmt = con.createStatement(); Calendar oldestRequestTime = Calendar.getInstance(); oldestRequestTime.add(Calendar.MINUTE, -60); SimpleDateFormat sdf = (SimpleDateFormat)SimpleDateFormat.getDateTimeInstance(); sdf.setCalendar(oldestRequestTime); sdf.applyLocalizedPattern("yyyy-MM-dd-HH.mm.ss"); String sdfStr = sdf.format(oldestRequestTime.getTime()); Statement stmt = con.createStatement(); String sql = "select XMLSERIALIZE(xmlquery(" + "'for $r in $c/queryData/result return $r' "+ "passing queryresults.query as \"c\") AS CLOB) "+ "from queryresults where requestDate > '"+sdfStr+"' "+ "and xmlexists ('$c/queryData[queryType=\"REST\"]' "+ "passing queryresults.query as \"c\") and "+ "xmlexists ('$c/queryData[queryUrl=\""+ query.replaceAll("&", "[[ampersand]]")+ "\"]' passing queryresults.query as \"c\")"; "+ "order by queryresults.requestDate desc"; ResultSet result = stmt.executeQuery(sql); String returnStr = "-1"; if (result.next()){ //Using cached data! returnStr = result.getString(1); } con.commit(); con.close(); return returnStr; } catch (Exception e){ e.printStackTrace(); return "-1"; } }public static void saveData(String queryUrl, Document document){ try{ ...
Trước tiên, bạn kết nối với cơ sở dữ liệu. Sau đó, bạn xác định rõ thời điểm nào dữ
liệu quá cũ để dùng. Để làm được điều đó bạn bắt đầu với việc tạo một đối tượng
Calendar. Đối tượng này nắm giữ ngày giờ hiện tại,
cộng thêm -60 phút (hoặc 60 phút trước) và đưa nó vào một xâu. Mặt khác, bạn
sẽ tìm kiếm dữ liệu với một
queryData lớn hơn 60
phút trước thời điểm hiện tại.
Để thực hiện tìm kiếm đó, trước tiên bạn tạo một đối tượng
Statement.
Sau đó tạo một truy vấn để tìm dữ liệu. Trong trường hợp này là một truy vấn FLWOR
lặp qua thành phần
queryData/result của cột queryresults.query.
Truy vấn này thiết lập giá trị của
$r là: chỉ các dòng nào mà
requestDate mới hơn thời điểm giới hạn và
queryType và
queryUrl
mới được trả về. Sau đó chúng ta có thể thực thi
Statement,
rồi trả về kết quả là một
ResultSet.
Tiếp theo, đặt giá trị của
returnStr là
-1 và việc thay đổi giá trị của nó thành XML
được trả về nếu và chỉ nếu
ResultSet có ít nhất
một dòng dữ liệu được trả về.
Cuối cùng đóng kết nối đến cơ sở dữ liệu.
### Sử dụng dữ liệu
Bạn có dữ liệu từ cơ sở dữ liệu và bạn cần sử dụng nó. Dùng phương thức
getData() như trong
[Ví dụ 23](#c23).
##### Ví dụ 23. Sử dụng dữ liệu đã lưu trữ
... public static Document getData (String query) { try { DocumentBuilder builder = DocumentBuilderFactory .newInstance().newDocumentBuilder();
String cached = checkCache(query);Document document; if (cached.equals("-1")){//Using fresh data document = builder.parse(query); saveData(query, document); } else{ //Using cached data document cachedDocument; cachedDocument = builder.parse( new InputSource(new StringReader(cached))); }return document; } catch (Exception e) { System.out.println(e.getMessage()); return null; } } ...
Trước tiên bạn kiểm tra cơ sở dữ liệu bằng việc sử dụng phương thức
checkCache(). Nếu không tìm thấy dữ liệu có thể chấp nhận được trong cơ sở dữ liệu, phương thức trả về giá trị
-1. Vì vậy bạn chỉ cần yêu cầu dữ liệu làm mới như thường lệ. Mặt khác, nếu xâu là bất cứ thứ gì khác, bạn dùng nó để xây dựng tài liệu.
Theo cả hai cách, bạn trả về đối tượng
Document.
## Tổng kết
### Tổng hợp và định hướng tiếp theo
Chủ nhân của một dịch vụ web tất nhiên sẽ đánh giá cao những gì bạn đã làm được ở đây, bằng việc lưu trữ tạm thời các truy vấn thực hiện trên các máy chủ của họ, bạn đã làm giảm chi phí bảo trì và lưu lượng của họ cũng như làm cho trang web của riêng bạn nhanh hơn. Bạn đã thêm một cơ sở dữ liệu DB2 vào ứng dụng mashup để lưu trữ các phản hồi XML từ các dịch vụ web mà bạn sử dụng, cho phép bạn truy vấn đối với máy chủ DB2 cục bộ và tận dụng sức mạnh các đặc trưng pureXML mới. Sau khi lưu trữ vào cơ sở dữ liệu bạn truy vấn máy chủ của mình và đã tạo ra một đối tượng dữ liệu trong ứng dụng.
Trong phần 3, bạn bắt đầu thêm thông tin vào hệ thống qua việc sử dụng các bản thể luận, bắt đầu với Resource Definition Framework, RDF.
## Tải về
|Mô tả||Tên||Kích thước|
|Part 2 source code|
## Tài nguyên
### Học tập
[Ultimate mashup – Các dịch vụ Web và Web ngữ nghĩa (semantic Web)](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp?search_by= Ultimate+mashup+–+Các+dịch+vụ+Web)Loạt các bài viết: Đọc các bài viết khác và và tạo các Mashup tùy ý. [Web có thể lập trình](http://www.programmableweb.com/)Cập nhật các mashup gần nhất và Web 2.0 APIs mới. [DB2 9: pureXML Overview and Fast Start](http://www.redbooks.ibm.com/redbooks/SG247298/wwhelp/wwhimpl/java/html/wwhelp.htm)(Cynthia M. Saracco và Don Chamberlin, IBM Redbooks, tháng 6 năm 2006): Đọc tài liệu này giới thiệu về các dịch vụ dữ liệu XML lai ghép trong DB2 9 cho hệ điều hành Linux,™, UNIX™, và Windows, bao gồm cả pureXML. [Getting Started with XPath (hãy bắt đầu với XPath)](http://www.ibm.com/developerworks/edu/x-dw-xxpath-i.html?S_TACT=105AGY75)(Bertrand Portier, developerWorks, tháng 5 năm 2004): Trong hướng dẫn này, hãy tìm phần giới thiệu về chuẩn W3C. [Query XML Data with XQuery (truy vấn dữ liệu XML với XQuery)](http://www.ibm.com/developerworks/db2/library/techarticle/dm-0604saracco?S_TACT=105AGY75/)(Don Chamberlin and Cynthia M. Saracco, developerWorks, April 2006): Học cách truy vấn dữ liệu đã lưu trữ trong các cột XML sử dụng XQuery [Query DB2 XML Data with SQL (Truy vấn dữ liệu XML DB2 với SQL)](http://www.ibm.com/developerworks/db2/library/techarticle/dm-0603saracco2/?S_TACT=105AGY75)(Cynthia M. Saracco, developerWorks, March 2006): Học truy vấn dữ liệu đã lưu trữ ở các cột XML sử dụng SQL và SQL/XML [DB2 9 Web site](http://www.ibm.com/software/data/db2/v9/xml.html): tìm hiểu thêm về sự hỗ trợ XML trong DB2 9 (thường được biết đến là DB2 Viper) [DB2 for Linux, UNIX and Windows](http://www.ibm.com/developerworks/db2/zones/db2udb/?S_TACT=105AGY75)trên developerWorks: Tìm các tài nguyên học tập, tải về, thông tin sản phẩm, và các hỗ trợ cho IBM DB2, hệ thống quản lý cơ sở dữ liệu quan hệ của IBM hiện có để cho các thông tin yêu cầu. [Considering Ajax, Part 1: Cut through the hype](http://www.ibm.com/developerworks/xml/library/wa-ajaxtop1?S_TACT=105AGY75)(Chris Laffra, developerWorks, May 2006): Xem xét tập các điểm thảo luận này với mỗi người phát triển trước khi bạn sử dụng các kỹ thuật Ajax cho một trang web. [Trang web Ajax](http://developer.mozilla.org/en/docs/AJAX)Ghé thăm trang web được bảo trợ bởi [Mozilla Development Center](http://developer.mozilla.org/en/docs/Main_Page). [DB2 and open source: Put yourself on the map with Google Maps API, DB2/Informix, and PHP on Linux (DB2 và nguồn mở: Tự đặt mình trên bản đồ Google Maps API, DB2/Informix và PHP trên Linux)](http://www.ibm.com/developerworks/db2/library/techarticle/dm-0602lurie/?S_TACT=105AGY75)(Marty Lurie and Aron Y. Lurie, developerWorks, March 2006): tạo một bản đồ dễ sử dụng (easy-to-use) có chứa dữ liệu của của bạn. [Building Web service applications with the Google API (Xây dựng các ứng dụng dịch vụ web với Google API)](http://www.ibm.com/developerworks/edu/ws-dw-wsgoog-i.html?S_TACT=105AGY75)(Nicholas Chase, developerWorks, May 2002): Học cách giấu các kết quả tìm kiếm Google và các thông tin khác ở các ứng dụng Java trong hướng dẫn này [Second Generation Web Services (Các dịch vụ web thế hệ thứ hai)](http://www.xml.com/pub/a/ws/2002/02/06/rest.html): trên XML.com, tìm tin tức về kiến trúc REST [REST and the Real World (REST và thế giới thực)](http://webservices.xml.com/pub/a/ws/2002/02/20/rest.html): Đọc thêm về REST (Representational State Transfer) từ trang XML.com
- Trang web
[W3C Semantic Web Activity](http://www.w3.org/2001/sw/): Đọc về web ngữ nghĩa [W3C RDF Activity](http://www.w3.org/RDF/): Tìm hiểu này cho Framework mô tả tài nguyên mới nhất [RSS là gì?](http://www.xml.com/pub/a/2002/12/18/dive-into-xml.html): Từ trang XML.com, học về định dạng chung cho các bản tin, nội dung, và các weblog cá nhân [Atom Overview](http://www.atomenabled.org/developers/syndication/): Đọc về nội dung web dựa trên XML và định dạng siêu dữ liệu và giao thức mức-ứng dụng từ AtomEnabled.org [AtomEnabled.org](http://www.atomenabled.org/). [Introduction to XML (Giới thiệu về XML)](http://www.ibm.com/developerworks/edu/x-dw-xmlintro-i.html?S_TACT=105AGY75)(Doug Tidwell, developerWorks, August 2002): Đọc hướng dẫn này để có một nền tảng XML tốt. [developerWorks Java zone](http://www.ibm.com/developerworks/java?S_TACT=105AGY75): Học thêm về lập trình trong Java với các bài báo, các hướng dẫn, các diễn đàn, ... [developerWorks XML zone](http://www.ibm.com/developerworks/xml?S_TACT=105AGY75): Tìm một phạm vi rộng lớn các bài báo và các gợi ý kỹ thuật, các chuẩn và các sách đỏ IBM (IBM Redbooks) về XML. [IBM XML 1.1 certification- Chứng nhận IBM XML 1.1](http://www.ibm.com/certify/certs/xmsdreltop.shtml): làm thế nào để bạn có thể trở thành một người phát triển XML 1.1 được chứng nhận bởi IBM như thế nào và các kỹ thuật liên quan. [developerWorks technical events and webcasts](http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGY75): Các sự kiện và thông cáo kỹ thuật.
### Lấy sản phẩm và công nghệ
[W3C SOAP Specification Các đặc điểm kỹ thuật W3C SOAP](http://www.w3.org/TR/soap): Cho phiên bản gần đây nhất [Apache Geronimo](http://geronimo.apache.org/downloads.html): Tải về và cài đặt Geronimo. Tìm thêm thông tin về cài đặt Geronimo ở [phần 1](http://www.ibm.com/developerworks/vn/edu/x-ultimashup1/) [Rational Web Developer](http://www.ibm.com/developerworks/downloads/r/rwd/?S_TACT=105AGY75): Tải về một phiên bản dùng thử và làm cho việc phát triển web của bạn dễ dàng hơn [DB2 Enterprise 9](http://www.ibm.com/developerworks/downloads/im/udb/?S_TACT=105AGY75): Tải về một phiên bản dùng thử của DB2 hoặc [DB2 Express-C 9](http://www.ibm.com/developerworks/downloads/im/udbexp/?S_TACT=105AGY75), một phiên bản miễn phí của DB2 Express 9
### Thảo luận
[diễn đàn deverloperWorks XML](http://www.ibm.com/developerworks/forums/dw_xforums.jsp?S_TACT=105AGY75): Giao tiếp với những người phát triển XML khác để giải quyết các vấn đề giống như bạn [developerWorks blogs](http://www.ibm.com/developerworks/blogs/?S_TACT=105AGY75): Tham gia vào nhóm developerWorks
## Bình luận
[Vùng dữ liệu trên developerWorks](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp)
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
[Vùng mã nguồn mở trên developerWorks](http://www.ibm.com/developerworks/vn/views/opensource/libraryview.jsp)
Xem các bài viết về HTML, CSS, JavaScript,...
[Điện toán đám mây](http://www.ibm.com/developerworks/vn/views/cloud/libraryview.jsp)
Tìm hiểu về điện toán đám mây

Content-Language: en-US

Kp-eeAlive: timeout=10, max=62