java oop第10章_JDBC03(MVC分层模式)
引言:在进行程序开发的时候,为了更加利于程序的管理我们引入了新的开发模式MVC分层模式,即按功能将程序代码分别分为M(Model模型)、V(View视图)、C(Controller控制器)三个组成部分。
一、 MVC各层的详解:
- 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);
} }
- 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"
*/ } } }
- 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 = "提交"/>
<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
请求参数:参数名为username、password。
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分层模式)的更多相关文章
- servlet jsp jdbc bootstrarp mvc分层模式实现的第一个项目
登录注册界面 这是一个注册和登录的界面 用到了前端页面中自带的一点H5的标签和属性---巩固下 邮箱格式 :type="email" 不能为空: required=" ...
- java oop第14章_Swing(Java界面设计)
一. Swing相关的概念: 1. GUI:(Graphical User Interface):图形化用户界面,通过图形化的方式提供与用户交互的平台,向用户展示信息.收集用户提交的数据. 2. ...
- Java oop 第13章_多线程
第13章_多线程 一. 多线程相关的概念: 程序:由某种编程语言开发可执行某些功能的代码组合,它是静态的概念. 进程:当程序被执行时的过程可以理解为讲程序从外存调入内存的过程,会为每一个程序 ...
- java oop第09章_JDBC02(CRUD操作)
第09章_JDBC02(CRUD操作) CRUD(CREATE . RETIVE . UPDATE . DELETE)增删改查. DAO中会提供一些CRUD操作方法,调用者可以通过调用这些方法完成相应 ...
- Java OOP——第六章 框架集合
1.集合框架包含的主要内容及彼此之间的关系: 图1: 集合框架:是为了表示和操作集合而统一规定的一种统一的标准体系结构. 包含三大块的内容:对外的接口.接口的是实现和对 ...
- Java OOP——第四章 异常
1. 接口:接口就是给出一些没有内容的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来. 接口是更加抽象的抽象的类, 抽象类里的方法可以有方法体, 接口里的所有方法都没有方法体. ...
- Java OOP——第七章 多线程
1.进程:是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间): Eg:用户点击桌面的IE浏览器,就启动了一个进程,操作系统就会为该进程分配独立的地址空间.当用户再次点击左面的IE浏览器, ...
- java oop第15章_Socket网络编程
一. TCP/IP协议(Transmission Control Protocol/Internet Protocol)传输控制协议/Internet协议,是通信领域的基础.核心协议, 其他的协议 ...
- java oop第12章_IO、序列化和反序列化
引言:数据通常通过文件系统保存在外存中,有时需要将他们读取到程序中进行一些操作,Java针对文件系统的操作提供了一套规范,即IO,针对计算机内存而言,输入的称为输入流,输出的称为输出流. 一. ...
随机推荐
- Maven远程仓库地址
https://repo1.maven.org/maven2/ http://maven.jahia.org/maven2/ http://maven.aliyun.com/nexus/content ...
- FrameWork内核解析之布局加载与资源系统(三)
阿里P7Android高级架构进阶视频免费学习请点击:https://space.bilibili.com/474380680本篇文章将继续从以下两个内容来介绍布局加载与资源系统: [ LayoutM ...
- react 16.3+ 新生命周期
react 16.3版本出现了两个新的生命周期函数,并将逐渐废弃componentWillMount().componentWillReceiveProps().componentWillUpdate ...
- QPrinter
在使用到QPrinter和QprintDialog类时的附加处理 ①若是在qt creator中,需要在 (.pro)工程文件中加入 “QT+= printsupport”,否则会编译报错
- css 实现文本换行及显示不下隐藏显示省略号
CSS文本超出2行就隐藏并且显示省略号 转载:https://www.cnblogs.com/wyaocn/p/5830364.html 今天做东西,遇到了这个问题,百度后总结得到了这个结果. 首 ...
- css自适应问题
1. 图片自适应 <img src="app-logo.png" srcset="app-logo.png 175w,app-logo-double.png 365 ...
- java基础之toString的使用方法
toString方法,其返回值类型为String类型,用于返回表示对象值的字符串,返回类名和它的引用地址(散列码 hashCode)toString方法是Object类中的一个实例方法,所有的java ...
- 设置ll命令
ll 是 ls -l的别名,之所以 ll出现错误是因为没有定义别名. 如果要实现ll 命令,可以做如下操作: 1.编辑 ~./bashrc 添加 ls -l 的别名为 ll即可. vi /root/. ...
- jq随机生成数字加字母的字符串
html代码: <dl class="row"> <dt class="tit"> <label for="title& ...
- pom.xml解释
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...