• 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>
  • 相关阅读:
    (转)轻松应对IDC机房带宽突然暴涨问题
    (转)老男孩:Linux企业运维人员最常用150个命令汇总
    (转)cut命令详解
    (转)Awk使用案例总结(运维必会)
    (转)Nmap命令的29个实用范例
    BigPipe学习研究
    js正则大扫除
    ffff表单提交的那点事
    高并发订单操作处理方法
    订单号的处理
  • 原文地址:https://www.cnblogs.com/loveyunk/p/6024739.html
Copyright © 2020-2023  润新知