首先,做一點(diǎn)說明。Flex是不能直接連接數(shù)據(jù)庫的,這一點(diǎn)大家需要知道,它只能間接地連接數(shù)據(jù)庫。Flex中提供了三種方式:HttpService,WebService 和RemoteObject。其中HttpService可以直接獲取XML中的數(shù)據(jù),還可以通過JSP,ASP以及PHP讀取數(shù)據(jù)庫中的數(shù)據(jù),這個(gè)比較簡(jiǎn)單,而且網(wǎng)上也有很多例子,我就不多說了。WebService我不懂,請(qǐng)自己查資料。我一直用的是JAVA對(duì)象連接數(shù)據(jù)庫,感覺這個(gè)挺方便,而且J2EE的技術(shù)已經(jīng)很成熟。今天的教程就是以 Flex + JAVA + SQLServer獲取數(shù)據(jù)庫公告信息為例簡(jiǎn)單說一下RemoteObject的用法。
前提
1.確保你安裝了Flex Data Service。這個(gè)對(duì)于單個(gè)CUP無限APP是免費(fèi)的,可以去Adobe下載。如果只是讀取XML文件是不需要這個(gè)的,連接數(shù)據(jù)庫就需要它了。
2.安裝了Flex Builder或者有Flex SDK。我這里使用的是Flex Builder(IDE就是方便啊 ^_^)。
3.安裝了SQLServer數(shù)據(jù)庫。
4.安裝了JRUN或者tomcat或其它的J2EE容器,因?yàn)榘l(fā)布的時(shí)候我們的程序要運(yùn)行在J2EE平臺(tái)上。
5.安裝了JDK。
第一步:創(chuàng)建數(shù)據(jù)庫
這里我們有一個(gè)公告表,表名為Bulletin。結(jié)構(gòu)如下:
字段名稱 字段類型 說明
ID 自動(dòng)編號(hào) 自動(dòng)編號(hào)
title Nvarchar(100) 題目
date datatime 日期
author Nvarchar(20) 作者
content ntext 內(nèi)容
在數(shù)據(jù)庫中創(chuàng)建這個(gè)表。保存之后進(jìn)入下一步。
第二步:在JAVA中編寫獲取公告的代碼
首先,我們要?jiǎng)?chuàng)建一個(gè)公告類來專門保存獲取的公告信息,代碼如下。
NoticeInfo.java
package net.zhuoqun.connectDB;
import java.util.Date;
public class NoticeInfo {
private String title; // 標(biāo)題
private String author; // 作者
private String content;// 內(nèi)容
private Date dates; // 時(shí)間
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
……………… // 其它get 和 set 方法。
}
創(chuàng)建好這個(gè)之后我們要?jiǎng)?chuàng)建一個(gè)數(shù)據(jù)查詢類:DataServiceImpl.java來查詢數(shù)據(jù)庫,并將查詢結(jié)果傳給將要?jiǎng)?chuàng)建的Flex程序。由于我們不清楚有多少條記錄,所以就借助一下JAVA中的ArrayList這個(gè)類,它位于java.util 包中。先創(chuàng)建一個(gè)ArrayList:
ArrayList noticeList = new ArrayList();
查詢數(shù)據(jù)庫之后,每讀取一條記錄就添加到 noticeList。
while(rs.next()){
NoticeInfo temp = new NoticeInfo();
temp.setAuthor(rs.getString("author"));
temp.setContent(rs.getString("content"));
temp.setDates(rs.getDate("date"));
temp.setTitle(rs.getString("title"));
noticeList.add(temp);
}
查詢完畢之后你就可以把這個(gè)noticeList傳回去,你也可以傳回去一個(gè) NoticeInfo 數(shù)組:
NoticeInfo[] notices = new NoticeInfo[noticeList.size()];
for(int i=0;i<noticeList.size();i++){
notices = (NoticeInfo)noticeList.get(i);
}
return notices;
我這里用的是后一種方法。如果你直接把noticeList傳回去的話,記住一點(diǎn),JAVA的ArrayList類型的對(duì)象到了Flex中會(huì)變成ArrayCollection類型的。
現(xiàn)在JAVA部分的代碼就寫好了。
DataServiceImpl.java 的全部代碼如下:
package net.zhuoqun.connectDB;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
public class DataServiceImpl {
private Connection conn = null;
private Statement stmt = null;
// 以下是數(shù)據(jù)庫以及驅(qū)動(dòng)信息
public final static String DRIVER = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
public final static String CONN_STR_PRE = "jdbc:microsoft:sqlserver://";
public final static String HOST_NAME = "localhost:1433;";
public final static String DATABASE_NAME = "DatabaseName=mydata";
public final static String USERNAME = "aaa";
public final static String PASSWORD = "aaa";
public DataServiceImpl(){
}
// 查詢數(shù)據(jù)庫
private ResultSet executeQuery(String sqlText){
try{
Class.forName(DRIVER);
}catch(ClassNotFoundException e){
e.printStackTrace();
}
try{
conn = DriverManager.getConnection(CONN_STR_PRE + HOST_NAME + DATABASE_NAME, USERNAME, PASSWORD);
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sqlText);
return rs;
}catch(SQLException e){
e.printStackTrace();
}
return null;
}
// 查詢公告. 這個(gè)是本程序的關(guān)鍵代碼
public NoticeInfo[] getNotices(){
ArrayList noticeList = new ArrayList();
String sqlText = "select author,content,date,title from Bulletin";
ResultSet rs = executeQuery(sqlText);
try{
while(rs.next()){
NoticeInfo temp = new NoticeInfo();
temp.setAuthor(rs.getString("author"));
temp.setContent(rs.getString("content"));
temp.setDates(rs.getDate("date"));
temp.setTitle(rs.getString("title"));
noticeList.add(temp);
}
NoticeInfo[] notices = new NoticeInfo[noticeList.size()];
for(int i=0;i<noticeList.size();i++){
notices = (NoticeInfo)noticeList.get(i);
}
return notices;
}catch(SQLException e){
e.printStackTrace();
return null;
}
}
}
第三步: 配置Flex Data Service
1,把剛才寫的JAVA文件編譯。打開FDS的安裝文件夾,將編譯的文件拷貝到\jrun4\servers\default\flex\WEB-INF\classes 文件夾中,進(jìn)行下面的配置。
2.打開FDS的安裝文件夾。進(jìn)入jrun4\servers\default\flex\WEB-INF\flex 目錄。里面是關(guān)于FlexData Service的配置文件,我們這里只看RemoteObject如何配置,其它配置信息請(qǐng)自己看幫助。現(xiàn)在我們打開里面的remoting-config.xml文件。向里面添加如下信息,作為<service>的子標(biāo)簽:
程序代碼
<destination id="dataService">
<properties>
<source>net.zhuoqun.connectDB.DataServiceImpl</source>
</properties>
</destination>
當(dāng)你設(shè)定了 destination的時(shí)候,你就引用了了可以用來連接相應(yīng)類的信息通道(messaging channel)。它的id必須在文件中是獨(dú)一無二的。source屬性是指你編譯的JAVA類在classes文件夾中的路徑。由于我的DataServiceImpl類在classes\net\zhuoqun\connectDB中,所以source的值為net.zhuoqun.connectDB.DataServiceImpl。記住,不要寫.class后綴。<properties>標(biāo)簽還可以有一個(gè)<scope>子標(biāo)簽,其作用我在這里就不說了,大家自己看相關(guān)文檔(關(guān)于FDS的配置其實(shí)有很多東西,這些在幫助文檔里都有,我這里不多說了,也說不過來,自己看吧)。
現(xiàn)在我們已經(jīng)配置好了后臺(tái)的 FDS,做完了整個(gè)程序的大部分工作,接下來就是前臺(tái)Flex程序調(diào)用的事情了。
第四步:創(chuàng)建Flex程序
打開Flex Builder,新建一個(gè)工程 ConnectDB。菜單欄中 File -> New -> Flex Project,這時(shí)會(huì)彈出一個(gè)對(duì)話框,選擇 Flex Data Service,創(chuàng)建了一個(gè)Flex工程。
第五步:通過 RemoteObject 訪問數(shù)據(jù)庫
打開工程中生成的主文件 ConnectDB.mxml,聲明一個(gè) RemoteObject :
程序代碼
<mx:RemoteObjectid="getData" destination="dataService"result="proccessResult(event.result)"fault="Alert.show(event.fault.faultString,'Error')"/>
其中destination 的值是剛才我們?cè)谂渲?FDS 的時(shí)候設(shè)定的 destination。 result 表示在這個(gè)RemoteObject成功返回之后所要做的動(dòng)作,這里我們調(diào)用一個(gè)方法 proccessResult()來處理返回的數(shù)據(jù),它的參數(shù) event.result就是從服務(wù)器段獲得的數(shù)據(jù),數(shù)據(jù)是作為一個(gè)對(duì)象傳過來的。 fault表示在這個(gè)RemoteObject請(qǐng)求失敗時(shí)要做的處理,這里我們會(huì)彈出一個(gè)顯示錯(cuò)誤信息的對(duì)話框。接下來我們要聲明一個(gè)DataGrid控件來顯示公告的標(biāo)題和發(fā)布日期:
程序代碼
<mxataGrid id="myDG">
<mx:columns>
<mxataGridColumn headerText="標(biāo)題" dataField="title"/>
<mxataGridColumn headerText="發(fā)布日期" dataField="dates" labelFunction="formatDate"/>
</mx:columns>
</mx:DataGrid>
其中headerText是顯示在上方的表頭,dataField表示要顯示的數(shù)據(jù)域,為什么數(shù)據(jù)域是title和dates呢?因?yàn)槲覀儌骰氐氖且粋€(gè)NoticeInfo 對(duì)象數(shù)組,雖然它是作為一個(gè)對(duì)象傳回來的,但是其中的數(shù)據(jù)結(jié)構(gòu)并沒有變,那些數(shù)據(jù)域的名字也沒有變,所以我們可以根據(jù)NoticeInfo 中的變量設(shè)定dataField。labelFunction屬性是用來格式化顯示的,因?yàn)閭骰貋淼氖歉窳滞螘r(shí)間,所以我們需要將其格式化然后顯示出來。注意,這里只是顯示兩個(gè)數(shù)據(jù)域,并不代表其它的數(shù)據(jù)都沒有了,它們?nèi)匀淮嬖?,只是沒有顯示出來。
接下來,在 <mx:Script> 標(biāo)簽中編寫proccessResult()方法和格式化日期的 formatDate方法:
程序代碼
private function proccessResult(result:Object):void
{
myDG.dataProvider = ArrayUtil.toArray(result);
}
private function formatDate(item:Object,column:DataGridColumn):String
{
return df.format(item.dates);
} // df 是一個(gè) DateFormatter,在下面會(huì)給出。關(guān)于如何格式化DataGrid的顯示
// 以及DateFormatter這里就不討論了,幫助里寫得很清楚
這個(gè)函數(shù)只是簡(jiǎn)單地將獲得的數(shù)據(jù)傳給 myDG 的 dataProvider。result的類型是Object,因?yàn)閿?shù)據(jù)是作為一個(gè)對(duì)象傳過來的。之所以調(diào)用 ArrayUtil.toArray()這個(gè)方法,是因?yàn)榉祷氐挠涗浛赡苤挥幸粭l,而myDG 的 dataProvider顯示單個(gè)對(duì)象的時(shí)候可能會(huì)出錯(cuò),所以安全起見先將其轉(zhuǎn)換成數(shù)組。
最后,我們編寫調(diào)用 RemoteObject 的方法,使其在程序啟動(dòng)時(shí)就調(diào)用。
程序代碼
private function initApp():void
{
getData.getNotices();
}
其中 getData 是RemoteObject的id,getNotices()是DataServiceImpl.java中的方法。在這里可以直接調(diào)用它。當(dāng)然,如果DataServiceImpl.java有其它方法,也可以通過這種方式直接調(diào)用。接下來設(shè)定組件創(chuàng)建完畢時(shí)調(diào)用 initApp()方法,在<mx:Application>中添加一個(gè)creationComplete屬性:
程序代碼
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" fontSize="12" creationComplete="initApp()">
ConnectDB.mxml的全部代碼:
程序代碼
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" fontSize="12" creationComplete="initApp()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.utils.ArrayUtil;
private function initApp():void
{
getData.getNotices();
}
private function proccessResult(result:Object):void
{
myDG.dataProvider = ArrayUtil.toArray(result);
}
private function formatDate(item:Object,column:DataGridColumn):String
{
return df.format(item.dates);
}// df 是一個(gè) DateFormatter,在下面會(huì)給出。關(guān)于如何格式化DataGrid的顯示
// 以及DateFormatter這里就不討論了,幫助里寫得很清楚
]]>
</mx:Script>
<mx:DateFormatter id="df" formatString="YYYY-MM-DD"/>
<mx:RemoteObject id="getData" destination="dataService"result="proccessResult(event.result)"fault="Alert.show(event.fault.faultString,'Error')"/>
<mx:DataGrid id="myDG">
<mx:columns>
<mx:DataGridColumn headerText="標(biāo)題" dataField="title"/>
<mx:DataGridColumn headerText="發(fā)布日期" dataField="dates" labelFunction="formatDate"/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
整個(gè)工程終于完成,啟動(dòng)JRUN,然后運(yùn)行程序,查看程序結(jié)果
如果是其他數(shù)據(jù)庫,只需要改一下數(shù)據(jù)庫驅(qū)動(dòng)信息就可以了