一個簡單實用的數據庫操作框架
|
前言
學習JDBC以來一直想實現一個簡單的封裝來方便編程但是由于水平有限一直沒有較好的辦法,看了IBM開發網上的兩篇文章以后感覺作者的設計思想很好一定能擴充成一個實用的JDBC封裝。所以我在文章提供的源碼基礎上加了一些功能這些功能包括支持多種數據類型,處理了空值,利用反射方便的在Row對象和值對象之間進行轉換,還有加了一個我自認為通用的DAO類來方便用戶的操作。
我把源碼提供出來有兩個目的一個是希望能幫助比我還初學的初學者熟悉JDBC,另外就是請各位高手不吝賜教,改進程序中的錯誤如果能將你們的對JDBC的封裝方法提供出來那就更好了(不要說你們只用EJB或者Hibernate,JDO什么的?)。
設計思想
把DBMS抽象成類Database,這個類負責管理數據庫連接以及提供表對象。
把數據庫中的一張或多張表抽象成類Table,這個類中提供對表的添加,修改,刪除的JDBC封裝。
將數據庫表中的一條記錄抽象成類Row,這個類用HashMap保存關系數據庫中表格中一行數據的字段名和值并提供一些相關操作。另外這個類還提供了兩個靜態方法用于在Row對象和ValueObject之間進行方便的轉換。
把對個Row的集合抽象成RowSet,這個類中用一個vector把多個Row對象保存起來并提供一些相關操作。
代碼分析
由于已經給出源碼所以我只對代碼中關鍵的和需要注意的地方加以說明,大家可以執行源碼一邊演示一邊體會。
Database類源碼如下:
package com.gdrj.util.database; import java.sql.*; import javax.sql.*; import com.gdrj.util.servicelocator.*; public class Database { /** * 這個數據庫連接成員只有在與數據庫直接建立連接的情況下是有效的 */ private Connection conn = null; /** * 當這個參數有效時,表明程序是直接與數據庫建立的連接而不是從連接池里取得連接 */ private String url, user, password; /** * 當這個參數有效時,表明程序是從連接池里取得連接。 */ private String datasource; /** * 用數據庫地址,用戶名,密碼初始化數據庫對象,這個構造器用于程序是直接 * 與數據庫建立連接的情況。 * @param url * @param user * @param password */ public Database(String url, String user, String password) { this.url = url; this.user = user; this.password = password; } /** * 用JNDI數據源名初始化數據庫對象,這個構造器用于從連接池取數據庫連接的情況。 * @param datasource */ public Database(String datasource) { this.datasource = datasource; } /** * 得到數據庫連接,對于是否從連接池里取連接做了自動處理即根據用戶調用了哪個構造器 * 來判斷是否直接與數據庫建立連接還是從連接池里取連接。 * 對于用戶來說不用考慮程序是從那里取得連接,他只管正確的初始化數據庫對象。 * @return * @throws SQLException */ public Connection getConnection() throws Exception { if (datasource == null) { //直接與數據庫建立連接 if (conn == null) { conn = DriverManager.getConnection(url, user, password); } } else { //從應用服務器的連接池里取得連接 ServiceLocator sl = ServiceLocator.getInstance(); DataSource ds = sl.getDataSource(datasource); return ds.getConnection(); //每調用一次都返回一個連接池中的數據庫連接 } return conn; } /** * 釋放連接,如果是直接與數據庫連接的情況則什么也不做 * 如果是從連接池中取得的連接那么釋放傳來的連接 * @param conn */ public void disConnect(Connection connection) { if (datasource != null) { //只處理從連接池取連接的情況 try { if (connection != null) { connection.close(); } } catch (Exception ex) {} } } /** * 得到與參數名對應的表對象,注意這里不作任何數據庫操作 * @param name * @return */ public Table getTable(String name) { return new Table(this, name); } } |
這個類是對DBMS的抽象,所以使用時應用程序中只要有一個Database對象就夠了,如果你是以與數據庫之間建立連接的方式使用那么你用Database(String url, String user, String password)構造器進行初始化。如果是從應用服務器的連接池中取得連接的方式使用那么用Database(String datasource)構造器初始化,這樣以后你使用這個對象進行getConnection和disConnection時就不用去考慮始終保持一個連接(C/S方式),還是將連接返回連接池了因為在disConnection中已經做了處理。集體使用方法將Table類。在getConnection中的從連接池中取連接的代碼你只要參考以下《J2EE核心模式》中的服務定位器模式就知道是怎么回事了,你在用Database(String url, String user, String password)初始化時其中的代碼不起作用。