非常詳細的JSP DAO設計模式

原文地址:http://just-do-myself.iteye.com/blog/655227


DAO(Data Access Objects)設計模式是屬於J2EE體系架構中的數據層的操作。

一、爲什麼要用DAO?

     比較在JSP頁面中使用JDBC來連接數據庫,這樣導致了JSP頁面中包含了大量的HTML代碼和JSP代碼,將顯示和功能代碼混在一起,難以維護。並且在JSP頁面中使用JDBC代碼,必須導入相應的"java.sql.*"包。基於使得JSP頁面專注於數據的表現的思想,我們只是希望JSP主要負責數據的顯示,而不需要關注數據的來源和途徑。同時在JSP進行JDBC操作,重複編碼太多。如,不同的頁面連接同一個數據庫時需要在每個頁面中都進行JDBC編碼。

  DAO設計模式提供了一種通用的模式,來簡化大量的代碼,增強程序的可移植性。

 

二、DAO組成

  DAO由5個重要部分組成:數據庫連接類、VO、DAO接口、DAO實現類和DAO工廠類。

 


1、數據庫連接類(DBConn):一個Java類。負責與後臺數據庫進行連接。提供了至少三個方法:

   構造方法 public DBConn():進行數據庫連接,得到一個Connection對象。

   返回數據庫連接Connection的public Connection getConnection():提供一個外部獲取連接的方法,返回一個Connection對象。

   關閉數據庫連接public void close():關閉數據庫連接,Connection對象調用close方法。。

 

在JDBC中,進行數據庫連接需要四個參數:數據庫驅動類DBDriver、數據庫連接URL、用戶名、密碼。注意需要在項目的構建路徑下放入相應的數據庫連接驅動軟件包。

 

例:連接MySQL數據庫下的JavaWeb數據庫,用戶名爲root、密碼爲admin。

 DataBaseConnection.java

 

 

Java代碼  收藏代碼
  1. package db;  
  2.   
  3. import java.sql.* ;  
  4.   
  5. // 主要功能就是連接數據庫、關閉數據庫  
  6. public class DataBaseConnection{  
  7.     //定義數據庫驅動類  
  8.     private final String DBDRIVER = "com.mysql.jdbc.Driver" ;  
  9.     //定義數據庫連接URL  
  10.     private final String DBURL = "jdbc:mysql://localhost:3306/javaweb" ;  
  11.     //定義數據庫連接用戶名  
  12.     private final String DBUSER = "root" ;  
  13.     //定義數據庫連接密碼  
  14.     private final String DBPASSWORD = "admin" ;  
  15.     //定義數據庫連接對象  
  16.     private Connection conn = null ;  
  17.     //構造方法,加載驅動  
  18.     public DataBaseConnection(){  
  19.         try{  
  20.             Class.forName(DBDRIVER) ;  
  21.             this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;    
  22.         }  
  23.         catch (Exception e){  
  24.             System.out.println("加載驅動失敗");  
  25.         }  
  26.     }  
  27.     // 取得數據庫連接  
  28.     public Connection getConnection(){  
  29.         return conn ;  
  30.     }  
  31.     // 關閉數據庫連接  
  32.     public void close(){  
  33.         try{  
  34.             conn.close() ;  
  35.         }catch (Exception e){  
  36.             System.out.println("數據庫連接關閉失敗");  
  37.         }         
  38.     }  
  39. }  

 

 

 同樣,需要在項目的構建路徑下放入Mysql的JDBC數據庫驅動包:mysql-connector-java.jar.在附件中已上傳了相應Jar包。

 

 

 

 

 

 

 

 

 

 

 

 

 

2、VO(Value Objects)值對象:與數據庫表一一對應的Java類。含有與數據庫表字段一一對應的屬性,相應屬性的getter和setter方法。甚至還有一些驗證方法。VO提供了一個面向對象的方法來操作數據庫。以後我們的DAO接口就是通過調用VO來進行數據庫操作的。

例:對應於數據庫表T_User:三個字段,id、username、password。相應的VO類

User.java

Java代碼  收藏代碼
  1. package db;  
  2.   
  3. public class User {  
  4.     //用戶id  
  5.     private int userid;  
  6.     //用戶姓名  
  7.     private String username;  
  8.     //用戶密碼  
  9.     private String password;  
  10.     //獲得用戶id  
  11.     public int getUserid(){  
  12.         return userid;  
  13.     }  
  14.     //設置用戶id  
  15.     public void setUserid(int userid){  
  16.         this.userid = userid;  
  17.     }  
  18.     //獲得用戶名  
  19.     public String getUsername() {  
  20.         return username;  
  21.     }  
  22.     //設置用戶名  
  23.     public void setUsername(String username) {  
  24.         this.username = username;  
  25.     }  
  26.     //獲得用戶密碼  
  27.     public String getPassword() {  
  28.         return password;  
  29.     }  
  30.     //設置用戶密碼  
  31.     public void setPassword(String password) {  
  32.         this.password = password;  
  33.     }  
  34. }  

 

 

3、DAO接口:定義了所有的用戶的操作,如添加記錄、刪除記錄和查詢記錄等。這不是一個具體的實現類,而是一個接口,僅僅定義了相應的操作(方法),這是給後來的具體實現提供一種靈活性和易維護性。具體的實現需要具體實現類實現這個接口的方法來實現。

例:對上面的T_User表進行CRUD操作。

UserDAO.java

Java代碼  收藏代碼
  1. package db ;  
  2.   
  3. import java.util.* ;  
  4.   
  5. // 定義數據庫操作方法  
  6. public interface UserDAO{  
  7.     // 增加操作  
  8.     public void insert(User user) throws Exception ;  
  9.     // 修改操作  
  10.     public void update(User user) throws Exception ;  
  11.     // 刪除操作  
  12.     public void delete(int userid) throws Exception ;  
  13.     // 按ID查詢操作  
  14.     public User queryById(int userid) throws Exception ;  
  15.     // 查詢全部  
  16.     public List queryAll() throws Exception ;  
  17. }  

  

 

4、DAO實現類:這裏纔是具體的操作的實現。需要實現DAO接口以及相應的方法。

同樣,一個DAO接口可以由多個實現。例如,上例中的可以有Mysql數據庫來實現,也可以使用oracle數據庫來實現。

同理,也可以是對同一數據庫的不同實現。

例:DAO的Mysql實現。

UserDAOImpl.java

Java代碼  收藏代碼
  1. package db;  
  2.   
  3. import java.sql.PreparedStatement;  
  4. import java.sql.ResultSet;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7.   
  8. import com.javaweb.ch08.Person;  
  9.   
  10. public class UserDAOImpl implements UserDAO {  
  11.     //添加操作  
  12.     public void insert(User user) throws Exception {  
  13.         String sql = "INSERT INTO user(username,password) VALUES(?,?)" ;  
  14.         PreparedStatement pstmt = null ;  
  15.         DataBaseConnection dbc = null ;  
  16.         // 下面是針對數據庫的具體操作  
  17.         try{  
  18.             // 連接數據庫  
  19.             dbc = new DataBaseConnection() ;  
  20.             pstmt = dbc.getConnection().prepareStatement(sql) ;  
  21.             pstmt.setString(1, user.getUsername());  
  22.             pstmt.setString(2, user.getPassword());  
  23.             // 進行數據庫更新操作  
  24.             pstmt.executeUpdate() ;  
  25.             pstmt.close() ;  
  26.         }catch (Exception e){  
  27.             throw new Exception("操作出現異常") ;  
  28.         }  
  29.         finally{  
  30.             // 關閉數據庫連接  
  31.             dbc.close() ;  
  32.         }  
  33.     }  
  34.     //修改操作  
  35.     public void update(User user) throws Exception {  
  36.         String sql = "UPDATE user SET username=?,password=? WHERE userid=?" ;  
  37.         PreparedStatement pstmt = null ;  
  38.         DataBaseConnection dbc = null ;  
  39.         // 下面是針對數據庫的具體操作  
  40.         try{  
  41.             // 連接數據庫  
  42.             dbc = new DataBaseConnection() ;  
  43.             pstmt = dbc.getConnection().prepareStatement(sql) ;           
  44.             pstmt.setString(1, user.getUsername());  
  45.             pstmt.setString(2, user.getPassword());  
  46.             pstmt.setInt(3,user.getUserid());  
  47.             // 進行數據庫更新操作  
  48.             pstmt.executeUpdate() ;  
  49.             pstmt.close() ;  
  50.         }  
  51.         catch (Exception e){  
  52.             throw new Exception("操作出現異常") ;  
  53.         }  
  54.         finally{  
  55.             // 關閉數據庫連接  
  56.             dbc.close() ;  
  57.         }  
  58.     }  
  59.     //刪除操作  
  60.     public void delete(int userid) throws Exception {  
  61.         String sql = "DELETE FROM user WHERE userid=?" ;  
  62.         PreparedStatement pstmt = null ;  
  63.         DataBaseConnection dbc = null ;  
  64.         // 下面是針對數據庫的具體操作  
  65.         try{  
  66.             // 連接數據庫  
  67.             dbc = new DataBaseConnection() ;  
  68.             pstmt = dbc.getConnection().prepareStatement(sql) ;           
  69.             pstmt.setInt(1,userid) ;  
  70.             // 進行數據庫更新操作  
  71.             pstmt.executeUpdate() ;  
  72.             pstmt.close() ;  
  73.         }catch (Exception e){  
  74.             throw new Exception("操作出現異常") ;  
  75.         }  
  76.         finally{  
  77.             // 關閉數據庫連接  
  78.             dbc.close() ;  
  79.         }  
  80.     }  
  81.     //按ID查詢  
  82.     public User queryById(int userid) throws Exception {  
  83.         User user = null ;  
  84.         String sql = "SELECT * FROM user WHERE userid=?" ;  
  85.         PreparedStatement pstmt = null ;  
  86.         DataBaseConnection dbc = null ;  
  87.         // 下面是針對數據庫的具體操作  
  88.         try{  
  89.             // 連接數據庫  
  90.             dbc = new DataBaseConnection() ;  
  91.             pstmt = dbc.getConnection().prepareStatement(sql) ;           
  92.             pstmt.setInt(1, userid);  
  93.             // 進行數據庫查詢操作  
  94.             ResultSet rs = pstmt.executeQuery() ;  
  95.             if(rs.next())  
  96.             {  
  97.                 // 查詢出內容,之後將查詢出的內容賦值給user對象  
  98.                 user = new User() ;  
  99.                 user.setUserid(rs.getInt(1));  
  100.                 user.setUsername(rs.getString(2));  
  101.                 user.setPassword(rs.getString(3));  
  102.             }  
  103.             rs.close() ;  
  104.             pstmt.close() ;  
  105.         }catch (Exception e){  
  106.             throw new Exception("操作出現異常") ;  
  107.         }  
  108.         finally{  
  109.             // 關閉數據庫連接  
  110.             dbc.close() ;  
  111.         }  
  112.         return user ;  
  113.     }  
  114.     public List<User> queryAll() throws Exception {  
  115.         List<User> all = new ArrayList<User>() ;  
  116.         String sql = "SELECT * FROM user " ;  
  117.         PreparedStatement pstmt = null ;  
  118.         DataBaseConnection dbc = null ;  
  119.   
  120.         // 下面是針對數據庫的具體操作  
  121.         try{  
  122.             // 連接數據庫  
  123.             dbc = new DataBaseConnection() ;  
  124.             pstmt = dbc.getConnection().prepareStatement(sql) ;   
  125.             // 進行數據庫查詢操作  
  126.             ResultSet rs = pstmt.executeQuery() ;  
  127.             while(rs.next()){  
  128.                 // 查詢出內容,之後將查詢出的內容賦值給user對象  
  129.                 User user = new User() ;  
  130.                 user.setUserid(rs.getInt(1));  
  131.                 user.setUsername(rs.getString(2));  
  132.                 user.setPassword(rs.getString(3));  
  133.   
  134.                 // 將查詢出來的數據加入到List對象之中  
  135.                 all.add(user) ;  
  136.             }  
  137.             rs.close() ;  
  138.             pstmt.close() ;  
  139.         }  
  140.         catch (Exception e){  
  141.             throw new Exception("操作出現異常") ;  
  142.         }  
  143.         finally{  
  144.             // 關閉數據庫連接  
  145.             dbc.close() ;  
  146.         }  
  147.         return all ;  
  148.     }  
  149. }  

  

5、DAO工廠類:在沒有DAO工廠類的情況下,必須通過創建DAO實現類的實例才能完成數據庫的操作。這時要求必須知道具體的實現子類,對於後期的修改十分不便。如後期需要創建一個該DAO接口的Oracle實現類。這時就必須修改所有使用DAO實現類的代碼。如果使用DAO工廠類的一個靜態方法(不需要創建對象即可調用)來獲取DAO實現類實例,這時替換DAO實現類,只需修改DAO工廠類中的方法代碼,而不需要修改所有的調用DAO實現的代碼。

DAO工廠類是一個單例模式,這樣避免的數據庫的不一致。

例:通過DAO工廠類來獲取具體的DAO實現類。

DAOFactory.java

Java代碼  收藏代碼
  1. package db;  
  2.   
  3. public class DAOFactory{  
  4.     public static UserDAO getUserDAOInstance(){  
  5.         return new UserDAOImpl() ;  
  6.     }  
  7. }  

  

這裏若改變爲Oracle實現類UserDAOOracleImpl來實現DAO,只需在DAOFactory中修改

Java代碼  收藏代碼
  1. package db;  
  2.   
  3. public class DAOFactory{  
  4.     public static UserDAO getUserDAOInstance(){  
  5.         <span style="background-color: #ff0000;">return new UserDAOOracleImpl()</span> ;  
  6.     }  
  7. }  

 

 有了上面五個部分,就可以通過DAO工廠類獲取DAO實現類實例。通過調用DAO實現類實例中的方法就可以完成相應的數據庫的CRUD操作。

 

三、表示層調用通過DAO工廠類獲取DAO實現類實例的方法完成相應的操作。

1、添加記錄:AddUserDemo.jsp

Jsp代碼  收藏代碼
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <html>  
  4. <head>  
  5.     <title>添加用戶記錄</title>  
  6. </head>  
  7. <body>  
  8.     <%  
  9.         //通過DAO工廠獲得DAO實現類實例  
  10.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  11.         //設置需要添加的用戶  
  12.         User user = new User();  
  13.         user.setUsername("dao");  
  14.         user.setPassword("123");  
  15.         userDAO.insert(user);  
  16.     %>  
  17. </body>  
  18. </html>  

 

2、更新記錄:UpdateUserDemo.jsp

 

Jsp代碼  收藏代碼
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <html>  
  4. <head>  
  5.     <title>更新用戶記錄</title>  
  6. </head>  
  7. <body>  
  8.     <%  
  9.         //通過DAO工廠獲得DAO實現類實例  
  10.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  11.         //設置需要更新的用戶  
  12.         User user = new User();  
  13.         user.setUserid(10);  
  14.         user.setUsername("dao");  
  15.         user.setPassword("123456");  
  16.         //執行更新操作  
  17.         userDAO.update(user);  
  18.     %>  
  19. </body>  
  20. </html>  

 

3、刪除記錄:DeleteUserDemo.jsp

Jsp代碼  收藏代碼
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <html>  
  4. <head>  
  5.     <title>刪除用戶記錄</title>  
  6. </head>  
  7. <body>  
  8.     <%  
  9.         //通過DAO工廠獲得DAO實現類實例  
  10.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  11.         //執行刪除操作  
  12.         userDAO.delete(10);  
  13.     %>  
  14. </body>  
  15. </html>  

 

4、按ID查詢記錄:QueryByIdDemo.jsp

Jsp代碼  收藏代碼
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <html>  
  4. <head>  
  5.     <title>按ID查詢記錄</title>  
  6. </head>  
  7. <body>  
  8.     <%  
  9.         //通過DAO工廠獲得DAO實現類實例  
  10.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  11.         //指定按ID查詢  
  12.         User user = userDAO.queryById(2);  
  13.         out.println("用戶名:" + user.getUsername() + "<br>");  
  14.         out.println("密碼:" + user.getPassword());  
  15.     %>  
  16. </body>  
  17. </html>  

 

5、查詢所有記錄:QueryAllUserDemo.jsp

Jsp代碼  收藏代碼
  1. <%@ page language="java" contentType="text/html;charset=gb2312"%>  
  2. <%@ page import="db.*"%>  
  3. <%@ page import="java.util.*"%>  
  4. <html>  
  5. <head>  
  6.     <title>查詢所有記錄</title>  
  7. </head>  
  8. <body>  
  9.     <%  
  10.         //通過DAO工廠獲得DAO實現類實例  
  11.         UserDAO userDAO = DAOFactory.getUserDAOInstance();  
  12.         //查詢所有用戶  
  13.         List<User> all = userDAO.queryAll();  
  14.         Iterator<User> iter = all.iterator();  
  15.         //遍歷輸出所有用戶信息  
  16.         while(iter.hasNext()) {  
  17.             User user = iter.next();  
  18.             out.println("用戶名:" + user.getUsername());  
  19.             out.println(",密碼:" + user.getPassword() + "<br>");  
  20.         }  
  21.     %>  
  22. </body>  
  23. </html>  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章