
2.5 MVC+DAO设计模式与应用案例
一个Java Web应用程序是由很多不同的“组件”构成的,那么各组件之间是如何进行“通信”的?又是如何实现控制的?信息是如何提交和显示的?这些构成了Java Web应用程序的开发模式。
1.MVC设计模式
用JSP技术设计页面,用Servlet技术实现控制逻辑,用JavaBean技术实现业务逻辑处理。将一个系统的功能分为3种不同类型的组件,这种模式通常称为MVC模式。
2.DAO设计模式
DAO模式是进行Java数据库开发的最基本的设计模式,就是把对数据库表的操作转化为对Java类的操作。DAO模式要与JDBC、SQL等数据库应用技术结合使用。
JSP+Servlet+JavaBean+DAO实现了不同组件的分工协作,体系结构如图2-8所示。

图2-8 JSP+Servlet+JavaBean+DAO编程模式
2.5.1 基于MVC模式算术运算的Web程序设计
【例2-11】利用JSP+Servlet+JavaBean求任意两个整数之间累加和值,并显示结果。
【分析】该题目采用JSP+Servlet+JavaBean模式,由JavaBean计算累加值;由JSP实现信息的提交和运算结果的显示;由Servlet实现由提交页面获取数据,实施计算,并保存计算结果,然后实现跳转,将计算结果通过显示页面显示结果。
【设计】该程序需要由4个不同的构件组成。
1)一个封装两个数之间累加求和操作的JavaBean:Add.java。
2)一个Servlet(QiuHe.java)实现数据的获取、求值并跳转到输出页面(采用注释配置Servlet)。
3)提交两个数的JSP(input.jsp)页面,假设提交页面参数是shuju1和shuju2。
4)输出结果JSP页面(show.jsp)。
其关键是各组件之间是如何实现数据共享,以及如何实现各组件之间的跳转的。它们之间的关系如图2-9所示,图中的虚线是数据的传递。

图2-9 【例2-11】的处理流程
【实现】
1)建立一个JavaBean(Add.java),该JavaBean中包含两个属性a和b,以及实现计算累加值的操作方法sum()。其代码如下。
package con.edu.bean; public class Add{ private int a; private int b; public Add(int a, int b){this.a=a; yhis.b=b; } public Add(){} public int sum(){ int c, s=0; if(a>b){c=a; a=b; b=c; } for(int x=a; x<=b; ++x){ s += x; } return s; } //省略了各属性的setter/getter方法 }
2)设计Servlet实现数据的获取、求值并跳转到输出页面,代码如下。

3)设计提交任意两个整数的JSP页面(input.jsp),其页面代码如下。

4)设计输出结果JSP页面(show.jsp),其代码如下。
<body> <% Integer d1=(Integer)request.getAttribute("out1"); Integer d2=(Integer)request.getAttribute("out2"); Integer sum=(Integer)request.getAttribute("out_sum"); %> <p><%=d1%>加到<%= d2%>的和值是: <%= sum%> </p> </body>
【运行测试】启动页面input.jsp,按提示输入数据并提交,显示结果。
2.5.2 基于MVC模式用户注册与登录系统的开发
【例2-12】利用JSP+Servlet+JavaBean+JDBC+DAO技术,基于MVC模式开发用户注册,登录应用系统。
【分析与设计】开发该系统,其各组件如下。
1)由JavaBean定义用户实体类:User.java。
2)Servlet类的设计:两个Servlet类(注册用Servlet,登录用Servlet)。
3)利用JDBC定义DAO类,实现数据库的连接及读写数据库的操作。
4)利用JSP技术设计登录页面和注册页面。
【设计关键】该问题的处理流程如图2-10所示。

图2-10 例2-12的工作流程
【实现】
1)创建数据库与数据表。
建立MySQL数据库user及数据库表user_b,该表中包含3个字段:用户序号id, int类型且为主键,自动增长;用户名称username, char(10);用户密码userpassword, char(10)。
2)建立对应数据库表结构的JavaBean——用户类User。
注意,该类的建立是根据数据库表user_b的数据表结构建立的。
package edu.com.model; public class Student { private int id; private String username; private String userpassword; //省略了各属性的getter/setter方法 }
3)数据库连接与关闭释放资源工具JavaBean类的设计——DbConnect类。
package com.db; import java.sql.*; public class DbConnect { private static String driverName="com.mysql.jdbc.Driver"; //驱动程序名 private static String userName="root"; //数据库用户名 private static String userPwd="123456"; //密码 private static String dbName="user"; //数据库名 public static Connection getDBconnection(){ String url1="jdbc:mysql://localhost/"+dbName; String url2="? user="+userName+"&password="+userPwd; String url3="&useUnicode=true&characterEncoding=UTF-8"; String url=url1+url2+url3; Connection con=null; try{ Class.forName(driverName); con=DriverManager.getConnection(url); }catch (Exception e) {e.printStackTrace(); } return con; } public static void closeDB(Connection con, PreparedStatement pstm, ResultSet rs){ try{ if(rs! =null) rs.close(); if(pstm! =null) pstm.close(); if(con! =null) con.close(); }catch (SQLException e) {e.printStackTrace(); } } }
4)建立访问数据库的DAO类。
package edu.com.dao; //省略了import; public class UserDAO{ //实现向数据库中添加记录的方法 public int insert(User user) throws Exception{ Connection con=null; PreparedStatement prepStmt=null; ResultSet rs=null; con=DbConnect.getDBconnection(); String sql="insert into user_b(username, userpassword) values (? , ? )"; prepStmt =con.prepareStatement(sql); prepStmt.setString(1, user.getUsername()); prepStmt.setString(2, user.getUserpassword()); int n=prepStmt.executeUpdate(); close(prepStmt); close(con); return n; } //实现查询数据库中对指定的记录是否存在的方法 public User find(User user) throws Exception { Connection con=null; PreparedStatement prepStmt=null; ResultSet rs=null; User user2 = null; con=getDBconnection(); String sql="select * from user_b where username=? and userpassword=? "; prepStmt = con.prepareStatement(sql); prepStmt.setInt(1, user.getUsername()); prepStmt.setInt(2, user.getUserpassword()); rs = prepStmt.executeQuery(); if (rs.next()){ user2 = new User(); user2.setId(rs.getInt("id")); stu2.setUsername(rs.getString("username")); stu.setUserpassword(rs.getString("userpassword")); } close(rs); close(prepStmt); close(con); return user2; } //实现列出数据库全部记录的方法 public List<Student> findAll() throws Exception {//给出实现方法} //实现删除数据库中指定的记录的方法 public void remove(Student stu)throws Exception{//给出实现方法 } //实现用指定的对象修改数据库中记录的方法 public void update(Student stu) throws Exception {//给出实现方法} }
5)用户登录的Servlet:UserChecked.java,实现登录验证处理,其代码如下。

6)编写登录表单页面(input.jsp)提交登录信息,其代码如下。
<body> <form action="userChecked"method="post"> 用 户 名:<input type="text"name="xm"><br><br> 用户密码:<input type="password" name="mm"><br><br> <input type="submit" value="登录"> </form> </body>
7)登录成功后的页面(success.jsp),其主要代码如下。
<html> <head> <title>登录验证成功页面</title> </head> <body><%=request.getParameter("xm")%>:登录成功!<br> </body> </html>
8)登录失败后的展示页面(error.jsp),其主要代码如下。
<html> <head> <title>登录验证出错页面</title> </head> <body> <%=request.getParameter("xm") %>:登录失败!<br> </body> </html>
【运行测试】启动页面input.jsp,按提示进行操作,会给出相应的结果显示。
对于“注册”过程的设计与“登录”过程设计类似,这里就不给出具体源代码了。