引言:在进行程序开发的时候,为了更加利于程序的管理我们引入了新的开发模式MVC分层模式,即按功能将程序代码分别分为M(Model模型)、V(View视图)、C(Controller控制器)三个组成部分。

一、      MVC各层的详解:

  1. 1.    M(Model)模型层:

      提供一些基础数据给控制器进行调用,完成服务器端数据的管理,其中又分成如下几个部分:

        1)    Entity实体:实体中的属性与数据库的字段对应,通过实体的属性就可以携带数据与数据表建立联系。

package com.oop.entity;

import java.io.Serializable;

/**
* 用户实体
*
*/
public class User implements Serializable {
private static final long serialVersionUID = 1L; private Integer userId; //用户编号
private String userName; //用户名
private String mobile; //电话号码
private String email; //电子邮箱
private String passWord; //密码 public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String password) {
this.passWord = password;
} public User() { } public User(Integer userId) {
this.userId = userId;
}
public User(Integer userId, String userName, String mobile, String email, String password) {
this.userId = userId;
this.userName = userName;
this.mobile = mobile;
this.email = email;
this.passWord = password;
}
public User(String userName, String mobile, String email, String password) {
this.userName = userName;
this.mobile = mobile;
this.email = email;
this.passWord = password;
} /**
* toString()方法
*/
@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName + ", mobile=" + mobile + ", email=" + email
+ ", password=" + passWord + "]";
} }

        2)    DAO(data access object)数据访问对象:提供一些CRUD的方法(将被service调用),实现操作数据的目的。

package com.oop.dao.impl;

import com.oop.dao.UserDao;
import com.oop.entity.User;
import com.oop.util.BaseDao; /**
* 管理“用户”Dao的实现类
*/
public class UserDaoImpl extends BaseDao implements UserDao {
User userr = null; public User selectUserByUP(User user) {
try {
ct = getConnection();
String sql = "SELECT * FROM tb_user WHERE username = ? AND password = ?";
pst = ct.prepareStatement(sql);
pst.setString(1, user.getUserName());
pst.setString(2, user.getPassWord());
rs = pst.executeQuery();
while (rs.next()) {
userr = new User();
userr.setUserId(rs.getInt("user_id"));
userr.setUserName(rs.getString("username"));
userr.setMobile(rs.getString("mobile"));
userr.setPassWord(rs.getString("password"));
userr.setEmail(rs.getString("email")); }
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll();
} return userr;
}
}

        3)    Service业务层:完成一些DAO、Controller不能或不方便处理的任务,他也会提供一些方法给Controller调用。

package com.oop.service.impl;

import com.oop.dao.UserDao;
import com.oop.dao.impl.UserDaoImpl;
import com.oop.entity.User;
import com.oop.service.UserService;
/**
* 管理“用户”的service实现类
* @author zhangzimu
*
*/
public class UserServiceImpl implements UserService { UserDao userDao = new UserDaoImpl();
/**
* 通过用户名、密码查询用户对象的service层方法
* 当前的登录功能对应service层只需要调用DAO层的方法,并将结果返回给Controller即可,不需要处理额外的数据
* @param user:是user类型的对象,其中携带username和password,最终传到DAO层作为查询的条件。
* @return:返回通过username和password查询到的user对象。
*/
@Override
public User findUserByUP(User user) { return userDao.selectUserByUP(user);
} }
  1. 2.    C(Controller)控制器:

      其作用主要是实现“准备数据”、“控制跳转”。准备数据通常有两种途径获取需要准备的数据(从请求中获取、从查询数据库获取);控制跳转通常有两种方式(转发、重定向)。

package com.oop.controller;

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 com.oop.entity.User;
import com.oop.service.UserService;
import com.oop.service.impl.UserServiceImpl; /**
* 控制器:用于接收“登录”请求的控制器
* 当在login.jsp页面中发送/loginServlet请求时是以post方式提交时就会自动调用doPost()方法;
*/
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L; // 实例化UserServiceImpl的对象
UserService userService = new UserServiceImpl(); public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置字符编码
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8"); /*
* 1)从请求中获取“用户名”、“密码”。 request.getParameter("username"):
* 获取input的name为username这个输入框中的value值 (用户输入的“用户名称”) value = "admin"
*/ String username = request.getParameter("username");
String password = request.getParameter("password");
// 创建一个User类型的对象,将以上获取到的数据通过调用setXXX()方法为属性赋值。通过对象就可以传递属性值
User user = new User();
user.setUserName(username);
user.setPassWord(password); /* 2)调用service层的方法,service又调用Dao层的方法,查询数据库获取User类型的对象。 */
User loginUser = userService.findUserByUP(user); // 3)根据以上的查询结果判断用户是否合法,若合法跳转到成功页面(/success.jsp);
// 若不合法跳转到登录页面(/login.jsp),同时提供错误消息。 if (loginUser != null) {
// 合法跳转到成功页面(/success.jsp),同时显示成功消息 // 键值对,通过键值对就可以在目标jsp页面(success.jsp)中使用EL表达式调用( 欢迎您:${loginUser.getUserName()}),在网页中显示数据,达到不会显示Java代码的目的
request.setAttribute("loginUser", loginUser);
//将请求转发到目标页面,
request.getRequestDispatcher("/success.jsp").forward(request, response); } else {
// 不合法跳转到登录页面(/login.jsp),同时提供错误消息。 /**
* 第一种跳转:request.getRequestDispatcher().forward(request, response);
* 1、属于服务器跳转,相当于方法调用,在执行当前文件的过程中转向执行的目标文件,两个文件(当前文件和目标文件)属于同一次请求,前后页共用一个request,
* 可以通过此来传递一些数据或者会话(session)信息。request.setAttribute()和request.getAttribute()。
* 2、在前后两次执行后,地址栏不变,仍是当前文件地址。
* 3、不能转向本web应用之外的页面和网站,所以转向的速度要快。
* 4、URL中所包含的“/”表示应用程序(项目webroot)的路径
*/
request.setAttribute("errorInfo", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response); /**
* 第二种跳转:response.sendRedirect()。
* 1、属于重定向,也是客户端跳转,相当于客户端向服务端发送请求之后,服务器返回一个响应,客户端接收到响应之后又向服务端发送一次请求,一共是2次请求,
* 前后页不共用一个request,不能读取转向前通过request.setAttribute()设置的属性值。
* 2、在前后两次执行后,地址栏发生改变,是目标文件的地址。
* 3、可以转向到本web应用之外的页面和网站,所以转向的速度相对要慢。
* 4、URL种所包含的"/"表示根目录的路径
*
*/ /**
* 特殊的应用:对数据进行修改、删除、添加操作的时候,应该用response.sendRedirect()。
* 如果是采用了request.getRequestDispatcher().forward(request,response),
* 那么操作前后的地址栏都不会发生改变,仍然是修改的控制器,如果此时再对当前页面刷新的话,
* 就会重新发送一次请求对数据进行修改,这也就是有的人在刷新一次页面就增加一条数据的原因。
* 如何采用第二种方式传递数据:
1、可以选择session,但要在第二个文件中删除;
2、可以在请求的url中带上参数,如"add.htm?id=122"
*/ } } }
  1. 3.    V(view)视图:

      给用户展示数据的平台,通常是由JSP(Java sever page)作为视图。

      JSP可以完全兼容HTML的内容,又增加了一些动态处理数据的功能。

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
<!--action="/loginServlet":指定请求提交的路径。
method = "post":指定提交的方式
-->
<p>${pageContext.request.contextPath}表示JSP取得绝对路径的方法,也就是取出部署的应用程序名或者是当前的项目名称<p/>
<p>会在web xml文件中去找<p/> <form action="${pageContext.request.contextPath}/loginServlet" method = "post">
用户名称:<input type = "text" name = "username" /><br/><br/>
用户密码:<input type = "password" name = "password"/><br/><br/>
${errorInfo}<br/>
<input type = "submit" value = "提交"/>&nbsp;&nbsp;&nbsp;
<input type = "reset" value = "重置"/><br/><br/>
</form>
</body>
</html>

success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'success.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
--> </head> <body>
欢迎您:${loginUser.getUserName()}
</body>
</html>

二、      MVC各层之间调用的注意事项:

  1、      上一层调用下一层:如Controller调用Service,Service调用Dao,不允许反向调用。

  2、      同一层之间:尽量避免同层之间调用。

三、      MVC分层模式下的案例:

案例描述:实现登录功能------------------------------------------------------------案例代码在上面

  1、      创建一个web project:MVC

  2、      加入MySQL的jar包:

  3、      创建项目需要的包:按照MVC分层模式来创建包。

  4、      编写登录页面:/login.jsp

      表单中提供“用户名输入框”、“密码输入框”、“登录按钮”

      当点击“登录按钮”时就会向服务器发送登录请求

      请求路径: /loginServlet

      请求参数:参数名为usernamepassword

  5、      编写Controller:

    Com.oop.controller.LoginServlet

   1)      从请求中获取“用户名”、“密码”。

   2)      调用service层的方法,service又调用Dao层的方法,查询数据库获取User类型的对象。

      3)      根据以上的查询结果判断用户是否合法,若合法跳转到成功页面(/success.jsp);若不合法跳转到登录页面(/login.jsp),同时提供错误消息。

6、      处理视图:/login.jsp、/success.jsp

  /login.jsp:显示错误消息

  /success.jsp:显示成功消息

java oop第10章_JDBC03(MVC分层模式)的更多相关文章

  1. servlet jsp jdbc bootstrarp mvc分层模式实现的第一个项目

    登录注册界面 这是一个注册和登录的界面 用到了前端页面中自带的一点H5的标签和属性---巩固下 邮箱格式 :type="email"  不能为空:  required=" ...

  2. java oop第14章_Swing(Java界面设计)

    一.   Swing相关的概念: 1.  GUI:(Graphical User Interface):图形化用户界面,通过图形化的方式提供与用户交互的平台,向用户展示信息.收集用户提交的数据. 2. ...

  3. Java oop 第13章_多线程

    第13章_多线程 一.   多线程相关的概念:  程序:由某种编程语言开发可执行某些功能的代码组合,它是静态的概念.   进程:当程序被执行时的过程可以理解为讲程序从外存调入内存的过程,会为每一个程序 ...

  4. java oop第09章_JDBC02(CRUD操作)

    第09章_JDBC02(CRUD操作) CRUD(CREATE . RETIVE . UPDATE . DELETE)增删改查. DAO中会提供一些CRUD操作方法,调用者可以通过调用这些方法完成相应 ...

  5. Java OOP——第六章 框架集合

    1.集合框架包含的主要内容及彼此之间的关系: 图1:   集合框架:是为了表示和操作集合而统一规定的一种统一的标准体系结构.               包含三大块的内容:对外的接口.接口的是实现和对 ...

  6. Java OOP——第四章 异常

    1. 接口:接口就是给出一些没有内容的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来. 接口是更加抽象的抽象的类, 抽象类里的方法可以有方法体, 接口里的所有方法都没有方法体. ...

  7. Java OOP——第七章 多线程

    1.进程:是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间): Eg:用户点击桌面的IE浏览器,就启动了一个进程,操作系统就会为该进程分配独立的地址空间.当用户再次点击左面的IE浏览器, ...

  8. java oop第15章_Socket网络编程

    一.   TCP/IP协议(Transmission Control Protocol/Internet Protocol)传输控制协议/Internet协议,是通信领域的基础.核心协议, 其他的协议 ...

  9. java oop第12章_IO、序列化和反序列化

    引言:数据通常通过文件系统保存在外存中,有时需要将他们读取到程序中进行一些操作,Java针对文件系统的操作提供了一套规范,即IO,针对计算机内存而言,输入的称为输入流,输出的称为输出流. 一.     ...

随机推荐

  1. (转)Unity Cinemachine插件,实现单目标和多目标之间切换

    Unity Cinemachine插件学习笔记,实现单目标和多目标之间切换*版本要求Unity2017.1及以上. 参考资料: [官方] Unity 2017.1正式版发布 Cinemachine插件 ...

  2. teb教程1

    http://wiki.ros.org/teb_local_planner/Tutorials/Setup%20and%20test%20Optimization 简介:本部分关于teb怎样优化轨迹以 ...

  3. Linux 100个常用指令

    1.ls 列出目录内容. 文件属性: -:普通文件 d:目录文件 b:块设备 c:字符设备文件 l:符号连接文件 p:命令管道 s:套接字文件 文件权限: 9位数字,每3位一组 文件硬链接次数 文件所 ...

  4. STL_set

    #include <iostream> #include <set> #include <string> #include <cstdio> using ...

  5. div::before一个能插入元素的选择器

    div::before一个能插入元素的选择器

  6. Angularjs书写规范

    文件命名原则: 遵循以描述组件功能,然后是类型(可选)的方式来给所有的组件提供统一的命名 命名:feature.type.js. 测试文件名(feature.type.spec.js) 大多数文件都有 ...

  7. Oracle多表更新及MERGE命令和闪回机制还原数据表

    一.多表更新 比如线上有个系统由于某一个模块出现异常,导致系统整体的数据出现了错误,需要你手动改写数据库错误,Oracle update语句更新的值来自另一张表 update语法最基本的格式为 UPD ...

  8. PHP多参数方法的重构

    假设我们要完成一个保存文章的功能,如果采用函数编程的方式,大概会是下面这个样子: <?php function saveArticle($title, $content, $categoryId ...

  9. PHP ftp_delete() 函数

    定义和用法 ftp_delete() 函数删除 FTP 服务器上的一个文件. 如果成功,该函数返回 TRUE.如果失败,则返回 FALSE 和一个警告. 语法 ftp_delete(ftp_conne ...

  10. luoguP2709 小B的询问 [莫队]

    题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...