JDBC學習(四、DAO思想和重構設計上)
一、DAO設計思想
什麼是DAO:主要就包括CRUD(增刪改查操作)DAO(Data Access Object)是一個數據訪問介面,資料訪問:顧名思義就是與資料庫打交道。夾在業務邏輯與資料庫資源中間。
在核心J2EE模式中是這樣介紹DAO模式的:為了建立一個健壯的J2EE應用,應該將所有對資料來源的訪問操作抽象封裝在一個公共API中。
用程式設計的語言來說,就是建立一個介面,介面中定義了此應用程式中將會用到的所有事務方法。
在這個應用程式中,當需要和資料來源進行互動的時候則使用這個介面,並且編寫一個單獨的類來實現這個介面在邏輯上對應這個特定的資料儲存。
上圖的DAO設計的示意圖中,分析:
首先:以及解決了客戶端功能程式碼重複問題。
-------------------------------------------------------------------
提出新的問題: 設計save和get方法.
void save(String name,Integer age);
問題:如果需要儲存的學生有多個資訊,此時引數就有N多.
設計方法時,引數最好不要超過5,6個.
問題如何解決?
String get(Long id):根據學生的主鍵來查詢學生資訊
此時因為需要返回學生的多個資訊,此時的返回型別設計是不合理的。
問題如何解決?
解決方案:使用封裝思想,把學生的多個資訊封裝成一個物件。
儲存操作:
void save(Student stu);
查詢操作:
Student get(Long id);
二、DAO的設計規範
DAO元件包含DAO介面和DAO實現類以及DAO的測試類:分包規範:
package 域名倒寫.模組名稱.元件名;
com.hyxy.javabean; 儲存的javabean物件
com.hyxy.dao; 儲存dao介面檔案
com.hyxy.dao.impl; 儲存dao實現類檔案
com.hyxy.test; 臨時儲存測試類
起名規範:
javabean類: 描述物件的,一把使用英文單詞來表示:Xxx,比如:Employee.
DAO接 口: IXxxDAO/IXxxDao, 如:IEmployeeDAO/IEmployeeDao.
DAO實現類: XxxDAOImpl/XxxDaoImpl, 如:EmployeeDAOImpl,EmployeeDaoImpl. 注意:實現類一定要實現DAO介面。
DAO測試類: 根據DAO介面生成測試類, XxxDAOTest/XxxDaoTest,如:EmployeeDAOTest,EmplyeeDaoTest.
建立DAO物件規範:
1):DAO物件起名,統統叫做xxxDAO.
2):面向介面程式設計,把DAO物件賦給DAO介面型別(向上轉型)。
IEmployeeDAO employeeDAO= new EmployeeDAOImpl();
三、DAO操作步驟
1:先建立一張表。
2:根據表的結構,建立javabean物件。
3):建立DAO介面,並提供DAO方法(CRUD)。
4):建立DAO實現類,覆蓋介面中的方法,但是暫時不實現。
5):編寫測試類DAO測試類。
6):完成DAO實現類中的方法,並測試通過。
7):思考和總結。
四、重構設計
重構(Refactoring)就是通過調整程式程式碼,改善軟體的質量、效能,使其程式的設計模式和架構更趨合理,提高軟體的擴充套件性和維護性。
問題1:每個DAO方法中都會寫:驅動名稱/url/賬號/密碼,不利於維護。
如果現在我們從MySQL遷移到Oracle中去,此時就得修改每一個DAO方法的驅動名稱/url/賬號/密碼。
解決方案:
此時DAO程式碼:
問題2:我們在開放中會存在N個DAO實現類,那麼此時每一個DAO實現類中都得提供連線資料庫的四個基本要素的成員變數
解決方案:現在需要完成在多個類中共享驅動名稱/url/賬號/密碼四個資訊,我們可以定義一個類(JdbcUtil),把這四個資訊儲存在該類中,並且使用public static修飾。
問題3: 問題2是完美解決了,但是存在一些遺憾。
1):JdbcUtil中的四個欄位應該私有化起來,體現封裝.
2):其實在DAO實現類中,僅僅需要獲取一個Connection物件即可,至於該物件如何建立,可以不關心.
解決方案:我們在JdbcUtil類中提供一個靜態方法,用於返回Connection物件.
問題4:我們分析右圖JdbcUtil類中的getConn方法的程式碼,發現,每次呼叫getConn方法都需要載入註冊驅動,而我們其實就只需要在最初載入一次即可。
解決方案:在靜態程式碼塊中去載入和註冊資料庫驅動即可。
問題5:每一個DAO方法最後,都需要釋放資源,該程式碼沒有技術含量,又臭又長。
DML操作: 關閉Connection和Statement物件.
DQL操作: 關閉Connection和Statement以及ResultSet物件.
解決方案:在JdbcUtil類中提供close方法用於關閉三個資源物件.
問題6:在JdbcUtil類中提供了四個欄位分別表示連線資料庫的四要素(驅動類名,URL,賬號,密碼),存在硬編碼,如果需要修改連線的資料庫,就只能來修改該原始碼。
解決方案: 我們一般把資料庫的連線資訊存放到屬性檔案中(db.properties).
接下來再通過Properties類來載入資原始檔,並讀取其中的資訊即可.
問題7:在DAO方法中拼接SQL語句,很噁心(使用PreparedStatement解決)。
問題8:在每一個DAO方法中都建立一個新的Connection物件,使用之後,就立刻釋放了,也就是說沒有充分利用Connection物件,而建立Connection物件的成本非常大(資料庫連線池技術DataSource)。
問題9:DML操作模板是相同的,DQL操作模板也是相同的(重構設計下)。