山頂洞人日記 - 回歸到最純樸的開發

30
山山山山山山 山山山山山山山山山 山山山 [email protected] (Email/MSN) twitter://qing_wang http://blog.qing.tw 2008/5/16

Upload: koji-lin

Post on 10-Jun-2015

3.651 views

Category:

Technology


4 download

DESCRIPTION

2008/05/17 TWJUG slides

TRANSCRIPT

Page 1: 山頂洞人日記 -  回歸到最純樸的開發

山頂洞人日記 - 回歸到最純樸的開發山頂洞人日記 - 回歸到最純樸的開發

王建興[email protected]

(Email/MSN)twitter://qing_wanghttp://blog.qing.tw

2008/5/16

Page 2: 山頂洞人日記 -  回歸到最純樸的開發

審視你的需求審視你的需求

慾望總是超過真實需求 威力強大的東西難免複雜 選擇開發工具要在複雜度與威力之間選擇一個適合你

的平衡點

Page 3: 山頂洞人日記 -  回歸到最純樸的開發

山頂洞人過的日子山頂洞人過的日子

WinCVS EditPlus Ant MySQL Tomcat JavaDoc of API

Page 4: 山頂洞人日記 -  回歸到最純樸的開發

簡易級 Java Web 應用程式開發簡易級 Java Web 應用程式開發

不用 IDE 用 Editplus 來編輯原始碼 用 WinCVS 來做 project browsing 用 Ant 來做自動化建構

用 JSP 來寫 action 不用 Struts 不用 Spring

利用 LWDBA 來存取資料庫 不用 Hibernate 不用 EJB

Page 5: 山頂洞人日記 -  回歸到最純樸的開發

關於 Ant關於 Ant

為各種類型的專案建立不同 build.xml 的 template Library Web applications Standalone application

每次建立新的專案時,依照 template 建立固定的目錄結構

Page 6: 山頂洞人日記 -  回歸到最純樸的開發

瀏覽專案瀏覽專案

Page 7: 山頂洞人日記 -  回歸到最純樸的開發

問題在設計問題在設計

問題不在你使用什麼 framework 問題在於你的設計對不對

Page 8: 山頂洞人日記 -  回歸到最純樸的開發

劃分出系統架構中的各層劃分出系統架構中的各層

Presentation JSP 實作

Action JSP/Servlet 實作 使用 JSP 的優點在於 script language 的動態優勢

Façade 封裝事務邏輯 一般人最欠缺的

Data Access Layer LWDBA

Page 9: 山頂洞人日記 -  回歸到最純樸的開發

何謂 Facade何謂 Facade

Façade 就是建築物正面的入口 The Façade pattern simplifies access to a related sets of

objects by providing one object that all objects outside the set use to communicate with the set.

Page 10: 山頂洞人日記 -  回歸到最純樸的開發

你需要的只是 Code Gen 嗎?你需要的只是 Code Gen 嗎?

許多 framework 會強調 CRUD 應用程式的快速建立 可是…

許多應用程式的本質並不在 CRUD CRUD 程式碼的快速產生,似乎只對開發 ERP 之類的

系統比較有幫助

Page 11: 山頂洞人日記 -  回歸到最純樸的開發

有些 Web Application 的問題在於有些 Web Application 的問題在於

問題在於設計 缺乏了 Façade layer 使用 Struts 之類的 framework 來實作 MVC 使用諸如 Hibernate 的 framework 存取資料 事務邏輯未封裝 於 Action 類別中直接操作 DAO

問題所在

Page 12: 山頂洞人日記 -  回歸到最純樸的開發

LWDBALWDBA

輕量級的資料庫存取( Light-Weight Database Access )

目標:簡化存取關聯性資料庫的動作,提供最普遍的資料存取需求

No ORM, No Code Gen

Page 13: 山頂洞人日記 -  回歸到最純樸的開發

對資料庫存取的需求對資料庫存取的需求

容易設定 支援 Connection Pooling 簡化 SQL 操作 簡易的 DAO 支援 Query Caching

Page 14: 山頂洞人日記 -  回歸到最純樸的開發

資料庫的設定資料庫的設定

記錄於 CLASSPATH 中的 system.properties

lwdb.pool.default.type=mysql

lwdb.pool.default.driverClassName=org.gjt.mm.mysql.Driver

lwdb.pool.default.driverURL=jdbc:mysql://localhost:3306/lwdba

lwdb.pool.default.userName=root

lwdb.pool.default.password=root

lwdb.pool.default.maxConnectionCount=32

lwdb.pool.default.encoding=UTF-8

lwdb.pool.default.sqlFile=sql

Page 15: 山頂洞人日記 -  回歸到最純樸的開發

LWDBA 對 SQL 的態度LWDBA 對 SQL 的態度

一般人不在程式中使用 SQL 的原因? 資料庫相依性 schema change 帶來的影響

LWDBA 對 SQL statement 的觀點 在程式中使用 SQL statement 但在程式中看不到 SQL statement

做法 SQL statement composer SQL 抽離至外部的設定檔

Page 16: 山頂洞人日記 -  回歸到最純樸的開發

SQL 操作 - DBRow (1/3)SQL 操作 - DBRow (1/3)

tw.qing.lwdba.DBRow public DBRow(String _tableName, String _pkName) public DBRow(String _tableName, String _pkName[]) public void setColumn(String columnName, Object value) public Object getColumn(String columnName) public void removeColumn(String columnName) public HashMap getRow() public void setRow(HashMap hm)

Page 17: 山頂洞人日記 -  回歸到最純樸的開發

SQL 操作 - DBRow (2/3)SQL 操作 - DBRow (2/3)

public String toInsertString() public String toDeleteString() public String toUpdateString() public String toQueryString()

Page 18: 山頂洞人日記 -  回歸到最純樸的開發

SQL 操作 - DBRow (3/3)SQL 操作 - DBRow (3/3)

DBRow dr = new DBRow("Customer", "seqNo");

dr.setColumn("name", name);

dr.setColumn("phone", phone);

dr.setColumn("address", address);

System.out.println(dr.toInsertString());

Page 19: 山頂洞人日記 -  回歸到最純樸的開發

SQL 操作 - SQLManager (1/4)SQL 操作 - SQLManager (1/4)

SQLManager 是 lwdba 為了避免將 SQL 敘述 hardcode在程式中的類別

SQLManager 會依據 system.properties 中所設定的sqlFile 來決定實際使用的 SQL 敘述設定檔 例如: sql.properties

針對不同的資料庫組態,都提供一份外掛的 SQL 敘述設定檔

程式中若想使用 SQL 敘述,則務必透過 SQLManager來取得 SQL 敘述

當系統欲切換所使用的資料庫類型時,便毋需徹底修改程式中漫於四處的 SQL 敘述

Page 20: 山頂洞人日記 -  回歸到最純樸的開發

SQL 操作 - SQLManager (2/4)SQL 操作 - SQLManager (2/4)

SQL 設定檔中的每一行文字行皆代表一組 SQL 敘述,並且皆為 name=value 的對應 例如: user.getUserPassword=select password from

UserAccount where id={0}

Page 21: 山頂洞人日記 -  回歸到最純樸的開發

SQL 操作 - SQLManager (3/4)SQL 操作 - SQLManager (3/4)

SQL 敘述的命名,除了 SQL 敘述本身的意義之外,在前頭冠上子系統(對應至 Facade )的名稱

SQL 敘述中如果有參數的部份,是程式執行過程中動態傳入的,以 {0} 、 {1} 、…、 {n} 來依序代表傳入的第 0 個、第 1 個、以及第 n 個參數

在撰寫 SQL 敘述時,大小寫有別

Page 22: 山頂洞人日記 -  回歸到最純樸的開發

SQL 操作 - SQLManager (4/4)SQL 操作 - SQLManager (4/4)

SQLManager 提供 getSQL()族系的方法來取得 SQL 設定檔的內容String getSQL(String key)String getSQL(String key, Object arg)String getSQL(String key, Object arg1, Object arg2)String getSQL(String key, Object arg1, Object arg2,

Object arg3)String getSQL(String key, Object arg1, Object arg2,

Object arg3, Object arg4)String getSQL(String key, Object[] arg)

Page 23: 山頂洞人日記 -  回歸到最純樸的開發

存取 Database - DBFacade存取 Database - DBFacade

tw.qing.lwdba.DBFacade DBFacade() DBFacade(String poolName) public QueryResult sqlQuery(String query) public int sqlUpdate(String update) public QueryResult sqlQuery(String query, int idxRow, int

count, boolean fReturnTotal) public ArrayList sqlQueryRows(String query) public ArrayList sqlQueryRows(String query, int idxRow,

int count)

Page 24: 山頂洞人日記 -  回歸到最純樸的開發

查詢結果 - QueryResult查詢結果 - QueryResult

tw.qing.lwdba.QueryResult public ArrayList getRows() public int getTotalRowCount()

Page 25: 山頂洞人日記 -  回歸到最純樸的開發

取得查詢結果取得查詢結果

LWDBA 將查詢結果置於 ArrayList 中 ArrayList 中的每個元素都是 HashMap

用 HashMap 表示 ResultSet 中的一筆結果 HashMap即為通用性質的 DAO 可直接將 ArrayList 及 HashMap整合快取系統

Page 26: 山頂洞人日記 -  回歸到最純樸的開發

取得查詢結果 - 範例取得查詢結果 - 範例

StatisticsFacade facade = StatisticsFacade.getInstance();

ArrayList al = PPTVStatisticsFacade.listStatistics(n);

<%

for(int i=0;i<al.size();i++)

{

HashMap hm = (HashMap) al.get(i);

%>

<tr>

<td><%=hm.get("seqNo")%></td>

<td><%=hm.get("uid")%></td>

<td><%=hm.get("remoteHost")%></td>

<td><%=hm.get("type")%></td>

<td><%=hm.get("createTime")%></td>

</tr>

<%

}

%>

Page 27: 山頂洞人日記 -  回歸到最純樸的開發

基於 LWDBA 的設計基於 LWDBA 的設計

依據資料的處理特性,劃分你的子系統 AdFacade AnnouncementFacade HotelFacade MemberFacade OrderFacade ZipCodeFacade …

Page 28: 山頂洞人日記 -  回歸到最純樸的開發

撰寫 Facade撰寫 Facade

繼承自 DBFacade 參考 PPTVStatisticsFacade

Page 29: 山頂洞人日記 -  回歸到最純樸的開發

使用 Façade 的優點使用 Façade 的優點

將事務邏輯封裝於特定的層次 Action class 不再充斥著事務邏輯

降低相依性 提昇因為變動所造成的影響

Action class 所面對的是 business service ,而非直接操作資料

Page 30: 山頂洞人日記 -  回歸到最純樸的開發

Thanks!Q&A

Thanks!Q&A