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,针对计算机内存而言,输入的称为输入流,输出的称为输出流. 一. ...
随机推荐
- P4363 [九省联考2018]一双木棋
题面 这种搜索要把后继状态都跑出来之后取Min/Max 也就是回溯的时候进行操作 记得用hash进行记忆化(用map不开O2会TLE) #include<iostream> #includ ...
- 在vim中设置tab缩进为4个字符
编辑一个文件,进入之后一次输入 [esc] --> [ : ] --> [ set ts=4 ]vim aaa.txt
- 【目录】mysql 进阶篇系列
随笔分类 - mysql 进阶篇系列 mysql 开发进阶篇系列 55 权限与安全(安全事项 ) 摘要: 一. 操作系统层面安全 对于数据库来说,安全很重要,本章将从操作系统和数据库两个层面对mysq ...
- Hibernate4教程六(2):基本实现原理
整体流程 1:通过configuration来读cfg.xml文件 2:得到SessionFactory 工厂 3:通过SessionFactory 工厂来创建Session实例 4:通过Sessio ...
- 算法竞赛模板 动态规划之背包DP
① 01背包 有n件物品和一个容量为v的背包.第i件物品的价值是c[i],体积是w[i].求解将哪些物品装入背包可使价值总和最大. 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. ...
- 2018-2019 ACM-ICPC, Asia Seoul Regional Contest K TV Show Game 2-sat
题目传送门 题意: 有n个人,k盏灯,灯有红蓝两种颜色,每个人都猜了三种灯的颜色,问如何安排灯的颜色,使得每个人猜的灯至少有两个是对的. 思路: 很容易想到2-sat,但是显然枚举每个人猜对的情况是不 ...
- 【Luogu】【关卡2-10】分治算法(2017年10月)
任务说明:将大问题拆分为小问题,分而治之,各个击破,然后在合并回来. 取余运算||快速幂 幂次方 逆序对 南蛮图腾
- Oracle数据库中文乱码问题解决
1.查看服务器端编码select userenv('language') from dual;我实际查到的结果为:AMERICAN_AMERICA.ZHS16GBK 2.执行语句 select * f ...
- jedate(日期插件)
首先要引入JQuery,然后引入jedate.css和jedate.js(注:需要把下载好的jedate文件夹整个的放在项目中,不然图标无法显示) 没有把整个文件夹放进去的效果 ...
- Shiro学习(13)RememberMe
Shiro提供了记住我(RememberMe)的功能,比如访问如淘宝等一些网站时,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问,基本流程如下: 1.首先在登录页面选中Reme ...