您好,登錄后才能下訂單哦!
封裝數據訪問對象
1:通過分析總結,所有對數據庫表的操作都可以總結為通過JDBC對表的增刪改查,為了減少冗余代碼,
使得每次操作表時,不必都寫JDBC程序,所以將對一張表的所有數據訪功能,封裝在數據訪問對象
(Data Access Object)中,方便調用。
2:為了方便數據傳輸,往往會將java程序中所有相關操作的零散字段值,封裝成一個實體對象--entity。
實體封裝原則:
表----實體類
字段---屬性
實現序列化
提供set,get方法。
以下代碼就是利用Dao數據訪問對象寫出的JDBC程序,利用封裝簡化了JDBC開發步驟。
試想一下,如果,有10個添加,20個刪除的請求,還像JDBC1.0,2.0版本那樣寫的話,要寫10遍,20遍大量相似代碼,
基本一致的代碼。這不僅耗時耗力,也不符合JAVA三大特性。所以,利用Dao數據訪問層,將對表的常用操作,
封裝成方法,這樣再有10個添加或20個刪除,我們只需要調用10次,20次這個封裝好的添加或刪除方法,
而不用再寫那么多遍方法,大大簡化了開發工作量。
以下是利用Dao思想實現的JDBC3.0是3.0版本后面還有更好的版本娓娓道來!>_<
JDBC_Dao.java
public class JDBC_Dao {
/**
* 向account表增加一條記錄
*/
public void add(Account account){
Connection conn = null;
PreparedStatement pstm = null;
try {
//1加載驅動
Class.forName("com.mysql.jdbc.Driver");
//2創建連接
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/zdx?serverTimezone=UTC",
"root",
"root");
//3準備sql
String sql = "insert into account values(?,?,?,?)";
//4創建Statement,發送sql
pstm = conn.prepareStatement(sql);
pstm.setString(1,account.getCardId());
pstm.setString(2, account.getPassword());
pstm.setDouble(3, account.getBalance());
pstm.setString(4, account.getPhone());
int i = pstm.executeUpdate();
//5如果是查詢的話,處理結果集
} catch (Exception e) {
e.printStackTrace();
}
finally{
//6釋放資源
try {
pstm.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 向account表查詢一條記錄
* @param account
* @return
*/
public Account query(Account account){
Connection conn = null;
PreparedStatement pstm =null;
ResultSet rs = null;
try {
//1加載驅動
Class.forName("com.mysql.jdbc.Driver");
//2創建連接
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/zdx?serverTimezone=UTC",
"root",
"root");
//3準備sql
String sql = "select * from account where "
+ "card_id = ? and password = ?";
//4創建Statement發送語句
pstm = conn.prepareStatement(sql);
pstm.setString(1, account.getCardId());
pstm.setString(2, account.getPassword());
rs = pstm.executeQuery();
//5處理結果集
while (rs.next()) {
account.setCardId(rs.getString("card_id"));
account.setPassword(rs.getString("password"));
account.setBalance(rs.getDouble("balance"));
account.setPhone(rs.getString("phone"));
}
} catch (Exception e) {
e.getStackTrace();
}
finally{
//6釋放資源
try {
rs.close();
pstm.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return account;
}
}
以上代碼依舊使用account表,需要再寫一個實體對象用來承載數據,一個test類用來調用方法,
,這些最基礎的,這里就不贅述了,不清楚的同學就要自行參閱java語言了。
如果我查詢A卡,B卡,C卡,三張銀行卡信息,按照JDBC2.0要寫三個查詢方法,現在,只需要把參數傳遞過去,
調用三次query()方法就好了!
總結:可見利用Dao數據訪問層封裝JDBC常用方法,可以大大簡化方法步驟,不用重復寫方法,只需重復調用。
這就是JDBC3.0版本
=============================華麗麗的分割線================
但是仔細的讀者一定發現了,這里還存在不少缺陷,沒錯,我們還可以改進它。
在JDBC3.0版本里,可以發現,查詢,添加方法,存在大量冗余代碼,比如:
①同的加載驅動, ②相同的創建連接,③相同的釋放資源。
在上個版本的代碼里我只寫了添加查詢方法,如果還有刪除,修改,查詢所有等方法呢,
沒錯這些方法,也存在相同的創建連接,釋放鏈接。找見了問題,就好解決了。
那么解決的辦法還是----封裝。
我們可以嘗試把1注冊驅動,2創建連接,6釋放資源,這三個步驟做成工具類-----JDBCutil
這樣,我們在Dao層里面的JDBC方法,在遇到1,2,6等步驟時,不用再去寫代碼,只需調用封裝好的工具即可。
沒錯程序員都是很懶得!
以下是JDBC4.0是4.0版本,后面還有更完善的版本娓娓道來!
public class JDBC_Util {
/**
* @return 返回鏈接
*/
public static Connection getConnection() throws Exception {
Connection conn = null;
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/zdx?serverTimezone=UTC",
"root",
"root");
return conn;
}
/**
* 釋放資源
*/
public static void release(ResultSet rs,
Statement stm,
Connection conn){
try {
if(rs!=null){rs.close();}
if(stm!=null){stm.close();}
if(conn!=null){conn.close();}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public class JDBC_Dao2 {
/**
* 向account表增加一條記錄
*/
public void add(Account account){
Connection conn = null;
PreparedStatement pstm = null;
try {
conn = JDBC_Util.getConnection();
//3準備sql
String sql = "insert into account values(?,?,?,?)";
//4創建Statement,發送sql
pstm = conn.prepareStatement(sql);
pstm.setString(1,account.getCardId());
pstm.setString(2, account.getPassword());
pstm.setDouble(3, account.getBalance());
pstm.setString(4, account.getPhone());
int i = pstm.executeUpdate();
//5如果是查詢的話,處理結果集
} catch (Exception e) {
e.printStackTrace();
}
finally{
//6釋放資源
JDBC_Util.release(null, pstm, conn);
}
}
/**
* 向account表查詢一條記錄
* @param account
* @return
*/
public Account query(Account account){
Connection conn = null;
PreparedStatement pstm =null;
ResultSet rs = null;
try {
conn = JDBC_Util.getConnection();
//3準備sql
String sql = "select * from account where " + "card_id = ? and password = ?";
//4創建Statement發送語句
pstm = conn.prepareStatement(sql);
pstm.setString(1, account.getCardId());
pstm.setString(2, account.getPassword());
rs = pstm.executeQuery();
//5處理結果集
while (rs.next()) {
account.setCardId(rs.getString("card_id"));
account.setPassword(rs.getString("password"));
account.setBalance(rs.getDouble("balance"));
account.setPhone(rs.getString("phone"));
}
} catch (Exception e) {
e.getStackTrace();
}
finally{
//6釋放資源
JDBC_Util.release(rs, pstm, conn);
}
return account;
}
}
細心地讀者會發現在代碼里原本創建連接和釋放資源的位置都變成了方法調用。
conn = JDBC_Util.getConnection();
JDBC_Util.release(rs, pstm, conn);
4.0版本通過工具類調用的方式進一步精簡了代碼,那么4.0版本還有沒有缺陷了呢。
=======================華麗麗的分割線============================
對于JDBC_Util.java來說,還有許多不足。
1:
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/zdx?serverTimezone=UTC",
"root",
"root");
比如創建連接的方式,是在代碼里寫死的用戶名和密碼,以及連接url,而java文件運行的時候,會編譯成class文件
也就是說,JDBC_Util最終會是JDBC_Util.class文件,那么一旦數據庫改變密碼,用戶名,或改換數據庫,
整個文件還需要重新編譯執行。對此,我們可以把經常變動的代碼放到properties配置文件里去。
2:每次調用獲得連接的方法都需要加載驅動,
Class.forName("com.mysql.jdbc.Driver");
調用10次則加載10次,大大浪費了JVM內存,其實對于加載驅動只需要加載一次,我們可以嘗試把加載驅動放到
靜態代碼塊里。靜態代碼塊在類加載時執行,只執行一次。
properties配置文件簡介及使用:
1: InputStream is = new FileInputStream("配置文件路徑");
BufferedReader br = bew BufferedReader(new InputStramReader(is));
String as = br.readLine();
2:properties 是Map的實現類:
1:獲得配置文件的輸出流。
2:調用load(is);加載配置文件里的信息至Properties對象中。
下面的JDBC5.0版本是對JDBC_Util的改進。采用了靜態代碼塊加讀取配置文件的優化方案。
包括test.java,JDBC_Util2.java,JDBC_Dao2.java,properties文件,共四個。
JDBC_Uril2.java
public class JDBC_Util2 {
private static final Properties prop = new Properties();
static{
InputStream is = null;
try {
is = JDBC_Util2.class.getResourceAsStream("jdbc.properties");
prop.load(is);
String driverName = prop.getProperty("driverName");
Class.forName(driverName);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @return 返回鏈接
*/
public static Connection getConnection() throws Exception {
Connection conn = null;
String user = prop.getProperty("user");
String password = prop.getProperty("password");
String url = prop.getProperty("url");
conn = DriverManager.getConnection(url,user,password);
return conn;
}
/**
* 釋放資源
*/
public static void release(ResultSet rs,
Statement stm,
Connection conn){
try {
if(rs!=null){rs.close();}
if(stm!=null){stm.close();}
if(conn!=null){conn.close();}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
JDBC_Dao2.java
public class JDBC_Dao2 {
/**
* 向account表增加一條記錄
*/
public void add(Account account){
Connection conn = null;
PreparedStatement pstm = null;
try {
conn = JDBC_Util2.getConnection();
//3準備sql
String sql = "insert into account values(?,?,?,?)";
//4創建Statement,發送sql
pstm = conn.prepareStatement(sql);
pstm.setString(1,account.getCardId());
pstm.setString(2, account.getPassword());
pstm.setDouble(3, account.getBalance());
pstm.setString(4, account.getPhone());
int i = pstm.executeUpdate();
//5如果是查詢的話,處理結果集
} catch (Exception e) {
e.printStackTrace();
}
finally{
//6釋放資源
JDBC_Util2.release(null, pstm, conn);
}
}
/**
* 向account表查詢一條記錄
* @param account
* @return
*/
public Account query(Account account){
Connection conn = null;
PreparedStatement pstm =null;
ResultSet rs = null;
try {
conn = JDBC_Util2.getConnection();
//3準備sql
String sql = "select * from account where "
+ "card_id = ? and password = ?";
//4創建Statement發送語句
pstm = conn.prepareStatement(sql);
pstm.setString(1, account.getCardId());
pstm.setString(2, account.getPassword());
rs = pstm.executeQuery();
//5處理結果集
while (rs.next()) {
account.setCardId(rs.getString("card_id"));
account.setPassword(rs.getString("password"));
account.setBalance(rs.getDouble("balance"));
account.setPhone(rs.getString("phone"));
}
} catch (Exception e) {
e.getStackTrace();
}
finally{
//6釋放資源
JDBC_Util2.release(rs, pstm, conn);
}
return account;
}
}
jdbc.properties文件
driverName=com.mysql.jdbc.Driver
user=root
password=root
url=jdbc:mysql://localhost:3306/zdx?serverTimezone=UTC
Test_Dao.java
public class Test_Dao {
public static void main(String[] args) {
JDBC_Dao2 jd = new JDBC_Dao2();
Account account = new Account("10004","44444",99,"12345678900");
jd.add(account);
}
}
解決了依賴注入,冗余代碼,資源浪費等問題之后,JDBC5.0完畢。這個版本可以算得上是較為完善的版本了,但是還有瑕疵。
后面關于JDBC的問題涉及到事務,以及MVC模式,這里由于篇幅問題,無法細細詳談,但我會竟可能詳細的寫。
請小伙伴自行閱讀有關oracle事務一章節,還有有關mvc編程思想書籍。
============================華麗麗的分割線======================
由于篇幅原因,后續部分請大家閱讀由淺到深學習JDBC三
不妥之處懇請讀者批評指正,共同進步。>_<
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。