前篇文章介紹了如何將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
	