2010/11/13

應用開發的簡化

容易的方式

雖然常把實用新穎的技術簡化, 想辦法放入既有系統中, 讓夥伴、客戶都能上手使用, 但現實中卻還是不夠。

前幾天幫客戶除錯, 看問題時, 才知道他們做了什麼 … 有點類似 Web Services (偽), 卻是用 PHP。他們在生產過程中, 要把某個事件記錄在另一個資料庫。當然用 PHP 沒什麼問題, 只是把所有執行相關工作都寫在一個檔案裡頭的做法, 很明顯是從書上抄下來的範例, 再改一改的成果。

對許多人來說, 書上有類似的範例, 能照本宣科就拿來用就好。這大概是某些語言長年佔據 排行榜 的原因, 但時至今日這股『只要能動』的風潮漸漸改變。在 Web 時代大部分拿 SQL 就直接用, 到了 Web Services 時代, 分工愈來愈細, 要求愈來愈多, 許多程式的運作都以物件為基礎。並非談物件的優劣, 而是評估現實中若使用物件比 SQL 方便, 比如資料的呈現(xml, json), 處理(鷹架), 以及檢核這些作業, 自然而然趨勢也跟著改變。

這裡還有一個關鍵點, 以上面出問題的 PHP 來說, 不管怎樣只要一個檔案就做完收工。原有系統在程式方面雖然也能簡單做到, 但要連到他們內部使用的資料庫(MySQL)這種配置就不太容易。因為原系統採 N 階層架構, 要多接個資料庫, 雖然可做到, 但得更動不少層。
或許從仿 PHP 單一檔案開發起個頭, 比較容易些。

簡單的實現

PHP 帶領 LAMP 的風潮, 在 約定優於配置 之前, 受到許多開發人員喜愛。著重四個方面: 簡單編寫, 簡單散佈, 本機開發, 便宜且到處可託管。除了最後一個外, 前三項直接讓開發的人獲得好處。預設與 MySQL 搭配(以 5.3.3 來說, 還有 PostgreSQL, Oracel, Sqlite), 因此只要資料庫能夠運作, 程式就能寫, 能動, 能測。程式執行後, 也能立即從資料庫看看結果是否正確。

再複雜些的系統, 除了語言本身, 還得準備更多暖身課程。

在今天之前, 也一直覺得 PHP 劃下簡單的境界, 是無法挑戰的。原本的 Groovy 知識, 只想做到很接近, 但查了查資料, 發現結果還不錯。

前提是有個 MySQL 在正常運作, 假設有資料庫 mydb 以及表格 mytbl 如下:
simp_mysql.png

有兩欄(name, tel), 以及兩列資料。

先確定裝妥 JDK 1.6 以上版本, 再到 Groovy 首頁 下載 1.7 之後版本, 然後執行 bin/ 目錄下的 groovyConsole 能直接寫程式。

拷貝、貼上程式碼:


@Grapes([
@Grab('mysql:mysql-connector-java:5.1.13'),
@GrabConfig(systemClassLoader=true)
])
import groovy.sql.Sql

def dbUrl="jdbc:mysql://localhost/mydb?useUnicode=yes&characterEncoding=UTF-8"
def driverClass="com.mysql.jdbc.Driver"
def sql=Sql.newInstance(dbUrl,"root","root",driverClass)
sql.eachRow("select * from mytbl") {
println it
}


注意, 資料庫位置 localhost, 名稱 mydb, 帳號/密碼 root/root, 還有表格名稱 mytbl 可能需要置換。然後選擇執行, 可用工具列右邊屬來第二個圖示, 或選單裡頭 Script/Run。第一次可能久一點, 因為缺少連接 db 的程式庫(不像 PHP 有附加), 要花些時間下載, 之後就正常。LAMP 要義的第一項簡單編寫, 第三項本機開發, 可順利達成。整個結果, 應該和下圖差不多:
simp_groovy.png

除了讀取資料庫, 其它新增、更新、刪除的 SQL 也都有, 請參考 Groovy SQL。確定沒問題, 就存檔保留。

不過這時候或許有人會問: PHP 在命令列(command line)下執行很快的, Groovy 那能比? 那請試試 GroovyServ, 雖然有點作弊, 但就像 IE 比其他瀏覽器快, Office 比其他工具快, 差不多就是那種的方式 …

換不同資料庫, 應該只要改上面截圖中第 2 列程式庫, 第 7 列連接資料庫網址, 第 8 列資料庫套件名稱, 可能再加上第 9 列的帳號、密號, 其它步驟類推即可。

以上示範, 算真正的單一檔案寫完收工, 也簡單到少有的地步。

那放到網站是否很複雜?

在 Java 使用 Tomcat 會比 LAMP 中 Apache 容易。相同方式 tomcat 5, 6, 7 版本可通用, 這裡以 tomcat 6.0.29 示範。下載後解開, 把長長的目錄改為 tomcat6/。

在 tomcat6/ 下的 webapps/ 裡頭建 groovy/ 目錄, 再建 WEB-INF/。

把 Groovy 1.7 的 lib/ 複製到 WEB-INF/ 裡頭。

在 WEB-INF/ 增加 web.xml 檔案, 內容如下:


<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<display-name>Groovy Web Apps</display-name>

<servlet>
<servlet-name>Groovy</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Groovy</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>
</web-app>


而把上面讀取資料庫的 groovy 程式, 前幾列 @Grab 改一些 (有點尷尬, 之前寫法在 Web 不能用), 不過下列是通用的。(日後應該會針對此點修補 @Grab 才是)


ClassLoader.systemClassLoader.class.name = 'groovy.lang.GroovyClassLoader'
groovy.grape.Grape.grab(classLoader:ClassLoader.systemClassLoader
,group:'mysql', artifact:'mysql-connector-java', version:'5.1.13')
import groovy.sql.Sql

def dbUrl="jdbc:mysql://localhost/mydb?useUnicode=yes&characterEncoding=UTF-8"
def driverClass="com.mysql.jdbc.Driver"
def sql=Sql.newInstance(dbUrl,"root","root",driverClass)
sql.eachRow("select * from mytbl") {
println it
}


整個做法的結果應該和下圖相同:
simp_tomcat.png

以上方法做完, 執行 tomcat 6 … 一般用 bin/catalina.sh run 即可。

此時瀏覽器看到結果如下:
simp_web.png

單機寫完應用程式, 執行驗證完後, 隨即放上網站目錄去, LAMP 要義第二項的簡單散佈也可達陣。

簡單還要更簡單

原先想寫關於資料庫程式遷徙到 grails 的方式, 因為客戶的問題轉到另一個題目上, 與 PHP 的某種(通用?)做法比劃一下。

除此之外, 還有更積極的意義 … PHP 固然是寫資料庫和網頁程式的主流, 其相關資源可略窺一二。但 Java 連接的 IT 資源更廣泛, 像負責生產管理的 MES, 或財務處理的 AIS, 都由於加上 Groovy 的協助, 讓原本的系統有更大彈性, 也讓部份客製門檻降低, 例如一些報表、檢核的作業讓更多 IT 人員參與。可以想像一下 … 上面 SQL 資料讀入與 Web 輸出部份, 換成來自不同系統流程的資料, 以及 csv, xml, xls 或 pdf 輸出, 輔以適當的權限與稽核, 就可讓原本要獨立開發的程式變成簡單的腳本擋。

且如同 PHP 一般即改即用, 很簡單的滿足許多需求。

參考

0 comments: