第一节 MVC模式简介
1.1 MVC概念
首先我们需要知道MVC模式并不是javaweb项目中独有的,MVC是一种软件工程中的一种设计模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller),即为MVC。它是一种软件设计的典范,最早为Trygve Reenskaug提出,为施乐帕罗奥多研究中心(Xerox PARC)的Smalltalk语言发明的一种软件设计模式。
1.2 MVC模式详解
虽然MVC并不是Java当中独有的,但是现在几乎所有的B/S的架构都采用了MVC框架模式。
- 控制器Controller:控制器即是控制请求的处理逻辑,对请求进行处理,负责请 求转发和重定向;
- 1.接受请求处理参数2,与model层交互,传出参数,拿到数据3.逻辑判断,选择view,并且将数据春递给view
- 视图View:视图即是用户看到并与之交互的界面,比如HTML(静态资源),JSP(动态资源)等等。
- 1.渲染数据
- 模型Model:模型代表着一种企业规范,就是业务流程/状态的处理以及业务规则的规定。业务流程的处理过程对其他层来说是不透明的,模型接受的请求,并返回最终的处理结果。业务模型的设计可以说是MVC的核心。
- 1.和数据库进行交互,处理业务逻辑和数据处理
1.3 MVC高级框架应用
MVC模式被广泛用于Java的各种框架中,比如Struts2、spring MVC等等都用到了这种思想。
Struts2是基于MVC的轻量级的web应用框架。基于MVC,说明基于Struts2开发的Web应用自然就能实现MVC,也说明Struts2着力于在MVC的各个部分为我们的开发提供相应帮助。
第二节 JSP开发模型
2.1 JavaWeb经历两个时期
2.1.1 JSP Model1
JSP Model1是JavaWeb早期的模型,它适合小型Web项目,开发成本低!Model1第一代时期,服务器端只有JSP页面,所有的操作都在JSP页面中,连访问数据库的API也在JSP页面中完成。也就是说,所有的东西都耦合在一起,对后期的维护和扩展极为不利。
JSP Model1的优化(Model1第二代)
JSP Model1优化后有所改进,把业务逻辑(service)和数据访问(dao)的内容放到了JavaBean(狭义JavaBean:实体类,广义JavaBean:实体类,dao,service,工具类)中,而JSP页面负责显示以及请求调度的工作。虽然第二代比第一代好了些,但还让JSP做了过多的工作,JSP中把视图工作和请求调度(控制器)的工作耦合在一起了。
执行逻辑:
1.浏览器发送请求给到index.jsp,index.jsp中拿到service返回的模型数据(Model)
2.通过for循环去遍历list集合,循环生成多个<tr>,完成数据的渲染工作
3.当用户点击删除按钮时,浏览器发送请求到del.jsp,并且携带参数为这一行的sid
4.del.jsp中拿到url中的参数sid时,将其传给service里面的方法去具体完成删除操作
5.删除完成之后,重定向回index.jsp==》浏览器发送请求给到index.jsp
代码分析:
del.jsp他是充当servlet的作用,去接受请求,获取参数,并且和业务层代码进行交互
高内聚,低耦合
合适的代码放在合适的地方
2.1.2 JSP Model2
JSP Model2模式已经可以清晰的看到MVC完整的结构了。
JSP:视图层,用来与用户打交道。负责接收数据,以及显示数据给用户;
Servlet:控制层,负责找到合适的模型对象来处理业务逻辑,转发到合适的视图;
JavaBean:模型层,完成具体的业务工作,例如:开启、转账等。
小结:这就是javaweb经历的两个时期,JSP Model2适合多人合作开发大型的Web项目,各司其职,互不干涉,有利于开发中的分工,有利于组件的重用。但是,Web项目的开发难度加大,同时对开发人员的技术要求也提高了。
2.2基于MVC的三层架构的实现
虽然MVC把程序分成三部分,每个部分负责不同的功能,但是这只是逻辑的分离,实际代码并没有真正分离,特别是Model(包括业务、数据访问和实体类、工具类等)部分的代码,为了增强代码的维护性和降低代码耦合性,需要把代码分层管理,于是就有了三层架构:
分别是:web层(表示|界面层)、service层(业务逻辑层)、dao层(数据访问层)
web层对应MVC中的Servlet和JSP
其他层都属于MVC中的Model
案例演示:
web层
com.qf.web.servlet
jsp页面放在 WebContent 或 WEB-INF
Service层
com.qf.service 放服务层接口
com.qf.service.impl 放服务层实现
Dao 层
com.qf.dao 方法 dao接口
com.qf.dao.impl 放dao实现
实体类
com.qf.domain | com.qf.beans | com.qf.entity | com.qf.pojo|com.qf.model
工具类
com.qf.commons | com.qf.utils
第三节 MVC结合练习
通过MVC知识,练习一个页面表格的展示及删除功能
CREATE TABLE `stu` (
`sid` char(6) NOT NULL DEFAULT '',
`sname` varchar(50) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`gender` varchar(50) DEFAULT NULL,
PRIMARY KEY (`sid`),
UNIQUE KEY `sname` (`sname`)
)
INSERT INTO `stu` VALUES ('s0010', '666', '22', 'male');
INSERT INTO `stu` VALUES ('S0011', '777', '55', 'male');
INSERT INTO `stu` VALUES ('S_1001', 'liuYi', '35', 'male');
INSERT INTO `stu` VALUES ('S_1002', 'liSi', '15', 'female');
INSERT INTO `stu` VALUES ('S_1003', 'zhangSan', '95', 'male');
INSERT INTO `stu` VALUES ('S_1004', 'liSi1', '65', 'female');
INSERT INTO `stu` VALUES ('S_1005', 'wangWu', '55', 'male');
INSERT INTO `stu` VALUES ('S_1006', 'zhaoLiu', '75', 'female');
INSERT INTO `stu` VALUES ('S_1007', 'sunQi', '25', 'male');
INSERT INTO `stu` VALUES ('S_1008', 'zhouBa', '45', 'female');
INSERT INTO `stu` VALUES ('S_1009', 'wuJiu', '85', 'male');
INSERT INTO `stu` VALUES ('S_1010', 'zhengShi', '5', 'female');
javaBean
public class Student{
private String sid;
private String sname;
private Integer age;
private String gender;
getter/setter
}
properties:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/qf_demo
username=root
password=orcl
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=5000
JdbcUtil
package com.qf.util;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class JDBCUtil {
//声明连接池对象
private static DruidDataSource ds;
static{
//实例化配置对象
Properties properties=new Properties();
try {
InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");
//加载配置文件内容
properties.load(is);
ds = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//获取连接对象
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//关闭资源的方法
public static void close(Connection con, PreparedStatement pre, ResultSet rs){
try {
if(rs!=null) {
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(pre!=null) {
pre.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(con!=null) {
con.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
第四节 JSTL
3.1 什么是JSTL
JSTL:全称Java Server Pages Standard Tag Library,JSP标准标签库,代替jsp页面的脚本,实现逻辑控制。
jstl就是用来干掉<%%>里面的java代码,来实现逻辑控制
if标签,foreach标签。。。
他是和El表达式完美配合
3.2 JSTL的作用
实现JSP页面中逻辑处理。如判断, 循环等;
下载JSTL库,http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/
把jstl.jar、standard.jar放入WEB-INF/lib目录下
3.3 使用JSTL
必须在JSP页面添加tablib指令库
<% @taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c">
3.4 常用标签介绍
3.4.1 通用标签set,out,remove
<!-- c:set就是等同于pageContext.setAttrbute("name","zhansgan") -->
<c:set var="name" value="zhansgan"></c:set>
<!-- 忘页面输出,等同于 -->
<c:out value="${name }"></c:out>
<c:remove var="name"/>
<!-- 当取不到name时,显示默认值 -->
<c:out value="${name }" default="lisi"></c:out>
3.4.2 条件标签if,choose
<c:if>
<!-- 条件标签:if choose -->
<!-- test属性中是条件,但是条件需要使用EL表达式来书写 -->
<h3>条件标签:if</h3>
<c:if test="${8>2 }">
8大于2是成立的
</c:if>
<c:if test="${8<2 }">
8小于2是成立的
</c:if>
<br>
<%-- 如果只是一个基本数据类型直接书写不需要${} --%>
<c:set var="m" value="5"></c:set>
<c:if test="${m>3}">
5大于3是成立的
</c:if>
<c:choose>
<h3>条件标签:choose(等价于java中switch)</h3>
<%-- 测试成绩等级 >90 优秀 >80 良好 >70 中等 >60及格--%>
<c:set var="score" value="80"></c:set>
<c:choose>
<c:when test="${score>=90 }">优秀</c:when>
<c:when test="${score>=80 }">良好</c:when>
<c:when test="${score>=70 }">中等</c:when>
<c:when test="${score>=60 }">及格</c:when>
<c:otherwise>不及格</c:otherwise>
</c:choose>
3.4.3 迭代标签foreach
for基础遍历
<!-- 遍历for:输出1到10 的值 -->
<!--var: 变量,把遍历的每一个值都存储在变量中进行输出
begin:开始 如果是变量使用EL表达式表示
end:结束 如果是变量使用EL表达式表示
step:间隔的长度
for( int i=0;i<10;i++){
System.out.println(i);
}
-->
示例代码:
<c:forEach var="i" begin="1" end="10" step="2">
${i}<br>
</c:forEach>
foreach遍历
<h3>测试list集合遍历获取学生列表</h3>
<table border="1" width="80%" bordercolor="red" cellspacing="0"
align="center">
<tr>
<th>学号</th>
<th>姓名</th>
<th>成绩</th>
<th>班级</th>
<th>是否是第一个</th>
<th>是否是最后一个</th>
<th>计数count</th>
<th>索引index</th>
</tr>
<!--
isFirst() first
isLast() last
getCount() count 计数 重要的
getIndex() index
-->
<!-- var :遍历出的每一项使用变量先存储
items:集合(使用El表达式)
-->
<c:forEach var="stu" items="${students}" varStatus="vs">
<tr>
<td>${stu.id}</td>
<td>${stu.name}</td>
<td>${stu.score}</td>
<td>${stu.classes}</td>
<td>${vs.first}</td>
<td>${vs.last}</td>
<td>${vs.count}</td>
<td>${vs.index}</td>
</tr>
</c:forEach>
</table>
3.4.4 url标签
<c:url var="" value="">
<c:url var="loc" value="/stu.jsp">
<c:param name="username" value="张三"></c:param>
</c:url>
/stu?username=zhangsan
<a href="${loc}">学生列表</a>
mvc设计模式
controller
view
model
五层架构
controller 处理请求,选择视图
dao 链接数据库
service 业务逻辑
model javabean
util 工具
jstl的使用
c:if
c:foreach
分页:
pageIndex:当前页
pageSize:每页大小
limit (pageIndex-1)*pageSize,pageSize
3,3
尾页即为最大页数,如何根据pageSize已知值算出最大页数?
int countNum=dao.selectCount();//8 select count(*) from stu
8 3条数据一页==》3
int pageMax=countNum%pageSize==0?countNum/pageSize:countNum/pageSize+1;
//精度丢失
int pageMax=(countNum+(pageSize-1))/pageSize;//3
//pageSize=4
//countNum=12;
一切语言到最后只剩下数据结构和算法