摘要:該文介紹了Java語言訪問數據庫的JDBC技術以及對數據庫操作的過程。在此基礎上,從編程的通用性方面,提出了增加配置文件和編寫通用類的方法改進數據庫的操作。這些方法對用Java語言開發數據庫項目提供了一些借鑒作用。
關鍵詞:數據庫;JDBC;類
中圖分類號:TP311文獻標識碼:A 文章編號:1009-3044(2008)34-1545-02
Universal Method of Accessing Database Based on the JDBC
FAN Xin-hua, MENG Bo
(Computer Center, Northeastern University, Shenyang 110004, China)
Abstract: This article describes the JDBC technology of Java language and accessing and operating database based on it. On this basis, we propose two methods such as configuration file and general operating class to improve the operation of the database from the programming versatility. These methods provide some reference to develop the other database projects.
Key words: database; JDBC; Class
1 引言
Java語言不僅是一種面向對象的高級編程語言,而且它還是一個平臺(Platform)。應用Java語言更易開發出高
效、安全、穩定以及跨平臺的應用程序。Java語言能夠實現“一次編程,到處運行”(Write Once ,Run Anywhere)的目標,現已成為網絡編程的首選的編程語言。
數據庫的應用目前已經非常普遍,在應用程序開發過程中,經常會涉及到訪問數據庫。Java使用JDBC(Java Database Connectivity)技術進行數據庫的訪問。JDBC定義了一個底層的API,用來支持獨立于任何特定SQL實現的基本SQL功能。這意味著重要的是執行原SQL語句,然后檢索它們的結果。
簡單地說,JDBC主要完成以下3種功能[1]:
1) 與數據源建立連接:包括數據庫或者電子表格等。
通過DriverManager類建立起與數據源的連接,這個連接將作為一個數據操作的起點,同時也是連接會話事務操作的基礎。
2) 向數據庫發送SQL命令
通過Statement或者PreparedStatement類向數據源發送SQL命令。在發送SQL命令后,調用類中相應的execute方法來執行SQL命令。
3) 處理數據源返回的結果
數據庫處理了提交的SQL命令后,將返回處理結果。對于DDL和DML操作返回被修改的記錄數量,通過這個數量我們可以知道對多少條記錄進行了操作;對于數據查詢等操作將返回ResultSet結果集,通過遍歷ResultSet結果集獲得所需要的查詢結果。
2 常用的訪問數據庫的編程方法
采用JDBC技術操作數據庫,其主要的流程是:加載驅動→連接→SQL操作→關閉。其中連接數據庫主要有兩種方式,第一種是用JDBC-ODBC橋連接,對數據庫訪問的流程:應用程序→JDBC API→JDBC-ODBC→ODBC API→ODBC層→數據源;第二種是用相關廠商提供的相應驅動程序來連接,對數據庫訪問的流程:應用程序→JDBC API→驅動程序→數據源。
下面采用MS Access數據庫,Database名稱為DBAddressBook,Table名稱為TblAddressBook。表結構如下:
字段名類型
編號 Text(8)
姓名 Text(10)
電話 Text(15)
地址 Text(50)
參照上表設計數據庫,并配置ODBC的DSN名稱為AddressBook。
由于兩種連接數據庫方式的編程類似,以第一種方式為例進行說明JDBC數據庫訪問的操作步驟:
1) 引入java.sql與javax.sql軟件包
import java.sql.*;
import javax.sql.*;
2) 加載連接數據庫的JDBC驅動程序庫
Class.forName(\"sun.jdbc.odbc.JdbcOdbcDriver\");
3) 用Connection接口建立一個到數據庫的連接對象
String url=\"jdbc:odbc:AddressBook\";
Connection con=DriverManager.getConnection(url,\"Login\",\"Password\");//根據具體情況設用戶名和密碼
4) 通過SQL語句建立一個Statement對象,通過Statement執行數據庫操作
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery(\"select * from TblAddressBook\");
5) 獲取數據庫數據或更新數據庫數據
String no=rs.getString(\"編號\");
String name=rs.getString(\"姓名\");
String tele=rs.getString(\"電話\");
String addr=rs.getString(\"地址\");
6) 關閉結果集對象ResultSet、Statement對象與Connection對象。(注意關閉的順序先rs再stmt最后為con)
rs.close();
stmt.close();
con.close();
在上面的操作過程中,對于不同類型的數據庫要加載不同的連接驅動程序,操作不同的數據庫要建立不同的連接對象。如果上述的數據庫類型或者操作的數據庫發生改變,則要改變程序代碼并編譯程序。這樣,給編程人員帶來了一定的負擔,并且效率低下。
3 通用性方面的改進
3.1 增加配置文件[2]
一旦所訪問的數據庫類型改變后,必須修改程序中的驅動程序名稱和數據庫URL,重新編譯后才能運行。這對于應用程序的用戶是不能接受的,另一方面也削減了JDBC數據庫編程獨立于數據庫類型的優點。為了解決這個問題,我們可以采用配置文件來解決這個問題:提供一個配置界面,用戶可以在界面中指定驅動程序的名稱以及數據庫URL,并將結果保存到一個配置文件中。應用程序進行數據庫連接時使用配置文件中的信息,這樣可以提高應用程序的靈活性。如在應用程序所在的目錄中創建一個配置文件db.cfg,該文件中的內容為:
dbDriver=com.microsoft.jdbc.sqlserver.SQLServerDriver
dbUrl=jdbc:Microsoft:sqlserver
dbIP=127.0.0.1
dbPort=1433
dbUserName=admin
dbPassword=xyz
Java語言中提供了一個類java.util.Properites,該類中提供了load()方法,可以從輸入流中讀入配置文件中的屬性值。從配置文件db.cfg中讀入配置信息存放在對象prop中。如:
Properties prop=new Properties();
Prop.load(new FileInputStream(\"db.cfg\"));
從配置文件中讀入配置信息是以(關鍵字,屬性值)對的形式存放在對象prop中的。要取得關鍵字的屬性值,可以使用getProperty()方法:
String driver=prop.getProperty(\"dbDriver\");
為了提高應用程序的安全性,可以對配置文件中的用戶名和用戶密碼進行加密操作。
3.2 編寫通用類
Java編程語言中提供了用于數據庫訪問的各種API,但是一些API總是要組合在一起使用。例如,要建立一個數據庫連接,總是需要先載入數據庫驅動程序,然后使用驅動程序管理器建立連接。為此,我們可以將一些常用的數據庫的操作編寫成通用類。這里我們從兩方面來說明通用類的編寫,第一是以SQL語句為參數操作數據庫,在通用類中封裝對數據庫常用的操作;第二種是以關系數據庫的抽象來構建的對數據庫的操作類。
3.2.1 以SQL為參數的方式
在通用類中包含有連接數據庫、執行更新操作、執行查詢操作、顯示記錄、關閉數據庫等方法以及這些方法所用到的參數。如下代碼所示:
package creator.common.db;
import java.io.InputStream;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
public class DbBean {
//定義參數
public java.sql.Connection conn = 1;
public ResultSet rs = 1;
public Statement stmt = 1;
public PreparedStatement prepstmt = 1;
private String drivers = 1;
private String url = 1;(下轉第1554頁)
(上接第1546頁)
private String user = 1;
private String password = 1;
//連接數據庫
public DbBean(){ … }
//數據庫操作
public void prepareStatement(String sql) throws SQLException { … }
public ResultSet executeQuery(String sql) throws SQLException { … }
public void executeUpdate(String sql) throws SQLException { … }
public void addBatch(String value) throws SQLException { … }
public void setAutoCommit(boolean value) throws SQLException{ … }
public void commit() throws SQLException{ … }
public void rollback() throws SQLException{ … }
//關閉數據庫
public void close(){ … }
}
這里只給出了通用類的框架,具體的實現由讀者可以自行完成,也可根據實際開發項目的情況,在其基礎上增加所需要的功能。
3.2.2 以關系數據庫的抽象方式[3-5]
由于關系型數據庫的數據是由Database、Table、RowSet和Row組織起來的,所以可以使每一個類映射到一個基本的RDBMS概念上,同時也映射到一個JDBC類上。此類的設計思想如下:
把DBMS抽象成類Database,這個類負責管理數據庫連接以及提供表對象。當使用 JDBC 與數據庫建立連接時,必須告訴 JDBC 在何處可以找到實際的數據。因為不同的數據庫引擎有不同的訪問方法和描述這些方法的不同語法,所以有不止一種方法來指定數據源。在JDBC中,統一資源標識符(Uniform Resource Identifier,URI)字符串是用來指定數據源的,而這個字符串的結構是依賴于數據庫的。Database 類的主要目的就是封裝這個字符串,還有建立連接操作時可能需要的任何用戶名/密碼信息。
把數據庫中的一張或多張表抽象成類Table,這個類中提供對表的添加、修改、刪除的JDBC封裝。在API中的一個簡化設想是,當您從表的一行讀取數據時,您會得到整行的數據。換句話說,表的一行是作為讀寫一塊數據的最小單位。
將數據庫表中的一條記錄抽象成類Row,Row 是在 RDBMS 中表示表中一行的字段名和值的集合。這個類用HashMap保存關系數據庫中表內的一行數據的字段名和值,并提供一些相關操作。不同于 RDBMS 值可以是不同的類型,Row僅包含一種類型,即字符串類型。另外這個類還提供了靜態方法,用于在Row對象和ValueObject之間進行方便的轉換。
有一些查詢可以返回多個 Row,這樣就會得到一個RowSet,這個類中用一個vector把多個Row對象保存起來并提供一些相關操作。
上述所講述的通用類的方法,可以起到了程序代碼的復用,減輕編程人員的負擔,以達到事半功倍的效果。同時可應用在其它的數據庫項目開發中。
4 結束語
在實際的應用開發過程中,數據庫方面的應用占有相當大的比重,尤其是網絡數據庫。對于網絡數據庫應用系統來說,有多種數據庫可以選擇,由于不同類型的數據庫產品,其驅動程序都有所不同,通用性不強。針對程序的通用性從兩方面進行改進:第一,本文提出了在配置文件中寫入相關的配置信息,這樣就可以在訪問不同類型數據庫時,只修改配置文件中的信息,而不用修改程序;第二,對于數據庫的操作來說,連接數據庫、更新數據庫、查詢數據庫、顯示結果、關閉數據庫是其最基本的操作,我們可以利用Java語言的特點將其編寫成類,這樣在其它的應用系統也可以同樣使用這些類。對其它網絡數據庫的開發具有一定的借鑒作用。
參考文獻:
[1] 朱喜福,郭逢昌,趙璽編.Java網絡應用編程入門[M].北京:人民郵電出版社,2005.
[2] 於東軍,楊靜宇,李千目,王國全.Java程序設計與應用開發[M].北京:清華大學出版社,2005.
[3] Greg Travis.一個簡單的JDBC包裝器[EB/OL].http://www.ibm.com/developerworks/cn/java/j-jdbcwrap/index.html.
[4] 宗鋒.對一個簡單的JDBC包裝器的擴展及應用[EB/OL].http://www.ibm.com/developerworks/cn/java/l-jdbcwrap/.
[5] 一個簡單實用的數據庫操作框架[EB/OL].http://blog.csdn.net/arielxp/archive/2004/08/12/72608.aspx.