jsp DAO設計模式


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

一、為什么要用DAO?

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

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

二、DAO組成

在這個模式中DAO主要完成數據的操作,客戶端依靠DAO接口進行操作,服務端要將接口進行具體實現。DAO的主要組成由以下幾個部分組成。

        1、DatabaseConnection:專門負責數據庫打開與關閉操作的類。

        2、VO:主要由屬性、setter、getter方法,VO類中的屬性與數據表中的字段相對應。每一個VO對象相當於表中的一條記錄。

        3、DAO接口:主要定義數據庫操作的接口,定義數據庫的原子性操作,如增刪改,按ID查詢。

        4、Impl:DAO的具體實現類,完成具體的數據庫操作,但是不負責數據庫的打開和關閉,接口類的名稱首字母用“I”,表示其是一個接口。

        5、Proxy:代理實現類。主要完成數據庫的打開和關閉,並調用Impl類對象(真實對象類)的操作,之所以增加代理類是為了以后的拓展,如果一個程序可以A-B,那么中間最好加一個過渡,使用A-C-B的形式,可以有效減少程序的耦合度,使開發結構更加清晰。

        6、Factory:工廠類,通過工廠類取得一個DAO的實例化對象,編寫工廠類也是為了降低代碼的耦合度,工廠類產生實例的方法通常是靜態函 數,這樣一來就可以通過工廠類名直接生成實例。

 

用戶登錄源碼    DAOModel

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

構造方法 public DataBaseConnection():進行數據庫連接,得到一個Connection對象。
返回數據庫連接Connection的public Connection getConnection():提供一個外部獲取連接的方法,返回一個Connection對象。
關閉數據庫連接public void close():關閉數據庫連接,Connection對象調用close方法。。

在JDBC中,進行數據庫連接需要四個參數:數據庫驅動類DBDriver、數據庫連接URL、用戶名、密碼。

注意需要在項目的構建路徑下放入相應的數據庫連接驅動, mysql-connector-java-5.1.6-bin

連接MySQL數據庫下的test數據庫,用戶名為root、密碼為123456。

 DataBaseConnection.java

// 本類只用於數據庫連接及關閉操作  
package cn.hist.test.dbconn;

import java.sql.* ;  

//主要功能就是連接數據庫、關閉數據庫  
public class DataBaseConnection{  
  //定義數據庫驅動類  
  private final String DBDRIVER = "org.gjt.mm.mysql.Driver";  
  //定義數據庫連接URL  
  private final String DBURL = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF8";  
  //定義數據庫連接用戶名  
  private final String DBUSER = "root";  
  //定義數據庫連接密碼  
  private final String DBPASSWORD = "123456";  
  //定義數據庫連接對象  
  private Connection conn = null ;  
  //構造方法,加載驅動  
  public DataBaseConnection(){  
      try{  
          Class.forName(DBDRIVER) ;  
          conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;    
      }  
      catch (Exception e){  
          System.out.println("加載驅動失敗");  
      }  
  }  
  // 取得數據庫連接  
  public Connection getConnection() {
      return this.conn;
   } 
  // 關閉數據庫連接  
  public void close(){  
      try{  
          conn.close() ;  
      }catch (Exception e){  
          System.out.println("數據庫連接關閉失敗");  
      }         
  }  
} 

 

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

 

package cn.hist.test.vo;

public class User {
    // 用戶姓名
    private String username;
    // 用戶密碼
    private String password;

    // 獲得用戶名
    public String getUsername() {
        return username;
    }

    // 設置用戶名
    public void setUsername(String username) {
        this.username = username;
    }

    // 獲得用戶密碼
    public String getPassword() {
        return password;
    }

    // 設置用戶密碼
    public void setPassword(String password) {
        this.password = password;
    }
}

 

 

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

 

package cn.hist.test.dao;

import cn.hist.test.vo.User;

//定義數據庫操作方法
public interface UserDAO {
    // 用戶名,密碼登錄
    public boolean isLogin (User user) throws Exception ;
}

 

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

UserDAOImpl.java

package cn.hist.test.impl;
 
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
 
import cn.hist.test.dao.UserDAO;
import cn.hist.test.vo.User;

public class UserDAOImpl implements UserDAO {
    private Connection conn = null;
    private PreparedStatement pstmt = null;
 
    public UserDAOImpl(Connection conn) {//構造方法取得與數據庫連接
       this.conn = conn;
    }
 
    // 用戶名,密碼登錄操作
    public boolean isLogin(User user) throws Exception {
           boolean flag = false;
           String sql = "SELECT * FROM user" ;  
           this.pstmt = this.conn.prepareStatement(sql);   //預編譯
           ResultSet rs = pstmt.executeQuery() ;  
           String username = user.getUsername();
           String password = user.getPassword();
           while (rs.next()) {
               // 查詢出內容,分別與用戶輸入的用戶名和密碼進行比較
               if (username.equals(rs.getString("username")) && password.equals(rs.getString("password"))) {
                   flag = true;
               }
           }
           this.pstmt.close();  //關閉打開的操作
           return flag;
    } 
}
 

 

 5、Proxy:代理實現類。主要完成數據庫的打開和關閉,並調用Impl類對象(真實對象類)的操作,之所以增加代理類是為了以后的拓展,如果一個程序可以A-B,那么中間最好加一個過渡,使用A-C-B的形式,可以有效減少程序的耦合度,使開發結構更加清晰。 

 UserDAOProxy.java

package cn.hist.test.proxy;//代理類

import cn.hist.test.dao.UserDAO;
import cn.hist.test.dbconn.DataBaseConnection;
import cn.hist.test.impl.UserDAOImpl;
import cn.hist.test.vo.User;
 
public class UserDAOProxy implements UserDAO {
    private DataBaseConnection dbc = null; //定義數據庫連接類
    private UserDAO userDAOImpl = null;    //聲明DAO
 
    public UserDAOProxy() throws Exception {  //構造方法中實例化連接與實例化DAO對象
        this.dbc = new DataBaseConnection();  //連接數據庫
        this.userDAOImpl = new UserDAOImpl(this.dbc.getConnection());//實例化真實類
     }
    
    
    public boolean isLogin(User user) throws Exception {
        boolean flag = false;  //首先要定義要返回的變量
        try {
            flag = userDAOImpl.isLogin(user); //調用真實主題操作   
        } catch (Exception e) {
            throw e;
        } finally {
            dbc.close(); //關閉數據庫
        }
        return flag;
    }
}

 

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

package cn.hist.test.factory;//工廠類(能夠根據能夠根據不同的參數信息得到對象的實例)
 
import cn.hist.test.dao.UserDAO;
import cn.hist.test.proxy.UserDAOProxy;

public class DAOFactory {
    public static UserDAO getUserDAOInstance() throws Exception { //取得DAO接口實例
       return new UserDAOProxy(); //取得代理類的實例
    }
}

 

三、用戶登錄實例

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>2</title>
    <link rel="stylesheet" href="">
</head>
    <form id="form1" action="LoginCheck" method="post">
        username: <input type="text" name="username" id="username" />
        password: <input type="password" name="password" id="password" />
        <input type="submit" value="登錄" id="send" />
    </form>
</body>
</html>

 

LoginCheck.java

package cn.hist.test.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.hist.test.dao.UserDAO;
import cn.hist.test.factory.DAOFactory;
import cn.hist.test.vo.User;

public class LoginCheck extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        boolean flag = false;
        HttpSession session = req.getSession();
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        UserDAO userDAOProxy = null;
        try {
            userDAOProxy = DAOFactory.getUserDAOInstance();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        try {
            flag = userDAOProxy.isLogin(user);
            if (flag) {
                session.setAttribute("user", user);
                resp.sendRedirect("success.jsp");
            } else {
                resp.sendRedirect("fail.jsp");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

 

success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Test</title>
    <link rel="stylesheet" href="">
</head>
<body>
    ${sessionScope.user.username} ,歡迎登錄。
    <a href="Exit">退出</a>
</body>
</html> 

 

fail.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>fail</title>
    <link rel="stylesheet" href="">
</head>
<body>
    <p>登錄失敗!</p>
</body>
</html>

 

Exit.java

package servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Exit extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("user");
        resp.sendRedirect("login.jsp");
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <servlet>
        <servlet-name>LoginCheck</servlet-name>
        <servlet-class>cn.hist.test.servlet.LoginCheck</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>Exit</servlet-name>
        <servlet-class>cn.hist.test.servlet.Exit</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginCheck</servlet-name>
        <url-pattern>/LoginCheck</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Exit</servlet-name>
        <url-pattern>/Exit</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
</web-app>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM