前篇文章介紹了如何將Tomcat及Web應用程式部署到Windows Azure,凡事只要起了頭,接下來的工作就相對簡單許多,本篇文章接續前篇,介紹如何透過JDBC來存取SQL Azure。
Access SQL Azure with JDBC/Hibernate
文/黃忠成
Using JDBC with SQL Azure
前篇文章介紹了如何將Tomcat及Web應用程式部署到Windows Azure,凡事只要起了頭,接下來的工作就相對簡單許多,本篇文章接續前篇,介紹如何透過JDBC來存取SQL Azure。
開始之前,請透過Windows Azure的管理網站建立SQL Azure資料庫。
圖1
於其中建立PersonData資料庫,接著建立PERSONS資料表,其結構如下圖。
圖2
接下來只要透過SQL Azure的JDBC Driver便可連結到SQL Azure了,而安裝Windows Azure SDK Plug-In for Eclipse時,附帶安裝了MS SQL Server 的JDBC Driver,
這個Driver也支援SQL Azure,所以讀者們不需額外下載,只需將其加入Web Project的Library即可。
圖3
圖4
另外,別忘記當封裝WAR時,除了專案本體外,其餘引用的Library是不會一併封入的,所以必須額外設定。
圖5
圖6
圖7
完成後修改index.jsp來連結至SQL Azure並列出資料庫中的資料。
<%@ page language="java" contentType="text/html; charset=BIG5"
pageEncoding="BIG5"%>
<%@ page import="java.util.*" %>
<%@ page import="java.sql.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Insert title here</title>
</head>
<body>
<%
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection con = DriverManager.getConnection("jdbc:sqlserver://c95ouvaxn9.database.windows.net;DatabaseName=PersonData;"+
user=code6421@c95ouvaxn9;password=...;
// Create and execute an SQL statement that returns some data.
String SQL = "SELECT * FROM dbo.PERSONS";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(SQL);
// Iterate through the data in the result set and display it.
while (rs.next()) {
out.print(rs.getString(1) + " " + rs.getString(2)+"<br/>");
}
}catch(Exception e){
out.print("Error message: "+ e.getMessage());
}
%>
<b>Hello Azure</b>
</body>
</html>
執行後便可看到結果,為了測試,我事先在PERSONS資料表中添加了一筆資料。
圖8
當然,在Windows Azure模擬器上執行的結果也一樣。
圖9
Access SQL Azure with Hibernate
能透過JDBC連結SQL Azure的話,有名的OR Mapping Framework:Hibernate自然也可以使用囉,但過程有些小細節需要注意一下。
先將Hibernate所需要的Library加入。
圖10
別忘記,Deployment Assembly也要一併處理。
圖11
接著加入Hibernate Configuration檔案。
圖12
圖13
圖14
這裡要注意一下,Hibernate Plug-In(需額外安裝)產生的組態檔對於SQL Server的JDBC Driver描述有誤,需修改如下。
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEhibernate-configurationPUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<propertyname="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<propertyname="hibernate.connection.url">jdbc:sqlserver://c95ouvaxn9.database.windows.net;DatabaseName=PersonData</property>
<propertyname="hibernate.connection.password">.....</property>
<propertyname="hibernate.connection.username">code6421@c95ouvaxn9</property>
<propertyname="hibernate.default_catalog">dbo</property>
<propertyname="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
</session-factory>
</hibernate-configuration>
最大的差異在於driver_class部分,Plug-In產生的是錯誤的。
組態檔修改完後便可以建立Mapping Class。
package com.myazure.mapping;
public class Person {
private String PERSON_ID;
public String getPERSON_ID() {
return PERSON_ID;
}
public void setPERSON_ID(String pERSON_ID) {
PERSON_ID = pERSON_ID;
}
public String getNAME() {
return NAME;
}
public void setNAME(String nAME) {
NAME = nAME;
}
private String NAME;
}
然後透過Plug-In來產生Mapping檔案。
圖15
最後修改Hibernate Configuration檔案來連結Mapping檔案。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver://c95ouvaxn9.database.windows.net;DatabaseName=PersonData</property>
<property name="hibernate.connection.password">.....</property>
<property name="hibernate.connection.username">code6421@c95ouvaxn9</property>
<property name="hibernate.default_catalog">dbo</property>
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<mapping resource="com/myazure/mapping/Person.hbm.xml"/>
</session-factory>
</hibernate-configuration>
緊接著是重頭戲,修改index.jsp如下。
<%@ page language="java" contentType="text/html; charset=BIG5"
pageEncoding="BIG5"%>
<%@ page import="java.util.*" %>
<%@ page import="java.sql.*" %>
<%@ page import="org.hibernate.Session" %>
<%@ page import="com.myazure.*" %>
<%@ page import="com.myazure.mapping.*" %>
<%@ page import="org.hibernate.Criteria" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Insert title here</title>
</head>
<body>
<%
try{
Session sess = HBSessionFactory.getSessionFactory().openSession();
Criteria criteria = sess.createCriteria(Person.class);
Iterator persons = criteria.list().iterator();
while(persons.hasNext()) {
Person p = (Person)persons.next();
out.print("ID: " + p.getPERSON_ID()+"<br/>");
out.print("NAME: " + p.getNAME()+"<br/>");
}
}catch(Exception e){
out.print("Error message: "+ e.getMessage());
}
%>
<b>Hello Azure</b>
</body>
</html>
完成並執行後,你應該會看到Hibernate抱怨找不到對應的JDBC Driver,這是因為Hibernate 4.12讀取JDBC Driver的方式改變了,解決方法只要手動加上一行Class.forName就可。
<%@ page language="java" contentType="text/html; charset=BIG5"
pageEncoding="BIG5"%>
<%@ page import="java.util.*" %>
<%@ page import="java.sql.*" %>
<%@ page import="org.hibernate.Session" %>
<%@ page import="com.myazure.*" %>
<%@ page import="com.myazure.mapping.*" %>
<%@ page import="org.hibernate.Criteria" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=BIG5">
<title>Insert title here</title>
</head>
<body>
<%
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); //for hibernate 4.12
Session sess = HBSessionFactory.getSessionFactory().openSession();
Criteria criteria = sess.createCriteria(Person.class);
Iterator persons = criteria.list().iterator();
while(persons.hasNext()) {
Person p = (Person)persons.next();
out.print("ID: " + p.getPERSON_ID()+"<br/>");
out.print("NAME: " + p.getNAME()+"<br/>");
}
}catch(Exception e){
out.print("Error message: "+ e.getMessage());
}
%>
<b>Hello Azure</b>
</body>
</html>
完成後測試,沒問題的話應該可看到以下畫面。
圖16
在Windows Azure模擬環境下自然也是OK的。
圖17
有圖有真相, 在真實的Windows Azure環境下自然也是OK的。
圖18