一、什么是MVC
MVC(Model View Controller)是软件工程中的一种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
1. MVC也是一种开发架构设计模式,与三层架构类似。
2. MVC封了三个模块:
M:model 模型(生产数据,筛选数据)——业务逻辑层,数据访问层
V:view视图——表示层,职责:显示数据 JSP,HTML页面
C:controller控制器——控制层,职责:接收用户请求,处理用户请求,响应结果。serlvet
3. 总而言之:MVC其实就是将三层架构中的显示层"一分为二",将三层架构中的业务逻辑层与数据访问层进行合并成"model"。
MVC是一个大的概念,三层架构其实就是MVC的具体的实现的一种设计模式。
二、 MVC购物车的实现
(1)数据库分析
存在用户表、商品表、购物车表、订单表、订单详情表
--MVC购物车 --用户表 create table MVC_Users( userid number primary key,--用户ID主键 usersname varchar2(100),--用户名 upassword varchar2(50) ,--用户密码 uage number check (uage > 0 and uage<150),--用户年龄 usex varchar(50),--用户性别 umoney float,--用户余额 urole number,--用户权限0管理员1普通用户 udate date ,--用户注册日期 utel varchar2(100) ,--用户电话 uaddress varchar2(100) ) commit select * from MVC_Users --商品表 create table MVC_Good( gid number primary key, --商品编号 gname varchar2(100), --商品名称 gprice float, --商品单价 Gstock NUMBER,--商品库存 ginfo varchar2(200), --商品描述信息 gpath varchar2(100) --商品图片路径 ) select * from mvc_good --购物车表 create table MVC_Cart( cid number primary key,--购物车编号 cgid number references MVC_Good(gid),--商品编号 cuid number references MVC_Users(userid),--外键cuid对应用户表uuid ccount number ,--单个商品的数量 ctotal float --单个商品的总价格 ) select * from MVC_Cart --订单表 create table MVC_Order( oid number primary key,--订单ID oaddress varchar2(255),--收货地址 osumprice number,--订单总价 uuid number--用户ID ) --订单详细表 create table MVC_Orderitem( oiid number primary key,--订单详细ID oid number,--订单编号 gid number,--商品编号 oinum number,--数量 oprice number--价格 )
(2)servlet实现首页数据的显示:
package com.lixiangning.mvc.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.lixiangning.mvc.biz.IGoodsBiz; import com.lixiangning.mvc.biz.impl.GoodsBizImpl; import com.lixiangning.mvc.entity.Goods; /** * Servlet implementation class IndexServlet */ @WebServlet("/IndexServlet") public class IndexServlet extends HttpServlet { /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); //实例化 IGoodsBiz igb = new GoodsBizImpl(); //定义变量存储页码以及每一夜显示的数据 int pageIndex = 1; int pageSize = 4; int pageMax = 0;//存储最大页码 //当点击分页区域的下一页超链接时,获取这个参数 String pIndex = request.getParameter("pageIndex"); //判断,只有你点击了下一页 才将pIndex赋值给pageIndex if (null != pIndex) { pageIndex = Integer.valueOf(pIndex); } String strName = request.getParameter("strName"); if (strName == null) { strName = ""; } //根据dao求出总记录数 int count = igb.getGoodsCount(strName); pageMax = count % pageSize == 0 ? count / pageSize : count / pageSize + 1; List<Goods> listGoods = igb.queryGoodsAll(pageIndex, pageSize, strName); HttpSession session = request.getSession(); session.setAttribute("listGoods",listGoods); session.setAttribute("pageIndex",pageIndex); session.setAttribute("pageSize",pageSize); session.setAttribute("pageMax",pageMax); session.setAttribute("strName",strName); response.sendRedirect("index.jsp"); } }
(3)首页布局显示数据
<%@page import="java.util.List"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <!-- bootstrap.css --> <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" /> <!-- jQuery --> <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script> <!-- bootstrap.js --> <script type="text/javascript" src="js/bootstrap.min.js"></script> <style type="text/css"> table tr { text-align: center; } table tr td { vertical-align: middle !important; } .seach { width: 50%; margin: 0 auto; padding-top: 5px; padding-bottom: 5px; } </style> </head> <body> <h1 style="text-align: center">糯米团子的购物商城</h1> <c:if test="${empty listGoods }"> <jsp:forward page="index.do"></jsp:forward> </c:if> <hr> <div style="text-align: center"> <form action="index.do"> 名称:<input type="text" name="strName"> <input type="submit" value="搜索"> </form> </div> <table class="table table-bordered table-responsive" border="1" width="100%" cellpadding="0" cellspacing="0"> <tr class="list-group-item-danger"> <th>商品编号</th> <th>商品名称</th> <th>商品价格</th> <th>商品库存</th> <th>商品描述</th> <th>商品图片</th> <th>商品操作</th> </tr> <!-- 调用dao遍历即可 --> <c:forEach items="${listGoods }" var="goods"> <tr> <td>${goods.gid }</td> <td>${goods.gname }</td> <td>${goods.gprice}</td> <td>${goods.gstock}</td> <td>${goods.ginfo }</td> <td><img style="width: 130px; height: 70px;" src="${goods.gpath }" /></td> <td> <button class="btn btn-default" onclick="addCart(${goods.gid})">加入购物车</button> </td> </tr> </c:forEach> </table> <p align="right" style="font-size: 15px; font-weight: bold"> 当前页数:[${pageIndex }/${pageMax }] <a href="IndexServlet?pageIndex=1">首页</a> <a href="IndexServlet?pageIndex=${pageIndex - 1 < 0 ? 1 : pageIndex - 1 }&strName=${strName}">上一页</a> <a href="IndexServlet?pageIndex=${pageIndex + 1 > pageMax ? pageMax : pageIndex + 1 }&strName=${strName}">下一页</a> <a href="IndexServlet?pageIndex=${pageMax }">末页</a> </p> <script type="text/javascript"> function addCart(gid) { /* String username = request.getParameter("username"); if(username!=null){ location.href = "doShopping.jsp?gid="+gid; out.println("<span>欢迎你回来! " + username + "</span>"); }else{ request.setCharacterEncoding("utf-8"); location.href = "login.jsp?gid="+gid; } */ location.href = "ShoppingServlet?gid="+gid; } </script> </body> </html>
(4)首页页面显示:
(5)servlet实现加入购物车:
package com.lixiangning.mvc.servlet; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.lixiangning.mvc.biz.impl.GoodsBizImpl; import com.lixiangning.mvc.biz.impl.UsersBizImpl; import com.lixiangning.mvc.entity.Cart; import com.lixiangning.mvc.entity.Goods; import com.lixiangning.mvc.entity.Users; /** * Servlet implementation class ShoppingServlet */ @WebServlet("/ShoppingServlet") public class ShoppingServlet extends HttpServlet { /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String id = request.getParameter("gid"); int cid = 0; if (null != id) { cid = Integer.valueOf(id); } // 根据商品id查询所有信息 Goods goods = new GoodsBizImpl().getGoodsByGid(cid); // 将查询到的商品信息封装在购物车实体中 Cart cart = new Cart(); cart.setGoods(goods); cart.setCcount(1); cart.setCtotal(); // 获取购物车 HttpSession session = request.getSession(); List<Cart> listCarts = (List<Cart>) session.getAttribute("listCarts"); // 判断非空 boolean flag = true; // 为空则无商品 if (null == listCarts) { // 创建购物车 listCarts = new ArrayList<Cart>(); // 不为空有商品 } else { // 遍历购物车中的数据 for (Cart c : listCarts) { // 传递商品编号判断是否存在该商品 if (cid == c.getGoods().getGid()) { flag = false; // 加入购物车多一件商品 c.setCcount(c.getCcount() + 1); // 重新设置总价 c.setCtotal(); } } } // 判断是否存在该商品 if (flag == true) { listCarts.add(cart); } session.setAttribute("listCarts", listCarts); response.sendRedirect("cart.jsp"); } }
(6)servlet实现购物车数据的显示:
package com.lixiangning.mvc.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.lixiangning.mvc.entity.Cart; /** * Servlet implementation class CartServlet */ @WebServlet("/CartServlet") public class CartServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public CartServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); //获取购物车 List<Cart> listCarts = (List<Cart>) session.getAttribute("listCarts"); //定义变量存储页码以及显示数据 int pageIndex = 1; int pageSize = 4; //当点击分页区域的下一页超链接时获取参数 String pIndex = request.getParameter("pageIndex"); //判断 if (null != pIndex) { pageIndex = Integer.valueOf(pIndex); } //定义一个变量存储总记录数 int pageCount = listCarts.size(); int start = (pageIndex - 1) * pageSize; //sublist 参数end 没有等于 int end = pageIndex * pageSize; if (end > pageCount) { end = pageCount; } int pageMax = pageCount / pageSize; if (pageCount % pageSize != 0) { pageMax++; } //调用伪分页的方法 subList(start,end); listCarts = listCarts.subList(start, end); session.setAttribute("listCarts", listCarts); response.sendRedirect("cart.jsp"); } }
(7)购物车页面布局:
<%@page import="java.util.List"%> <%@page import="com.zking.mvc.entity.Cart"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h2>糯米团子的购物车</h2> <c:if test="${empty listCarts }"> <jsp:forward page="cart.do"></jsp:forward> </c:if> <a href="index.jsp">返回主页</a> <table border="1" width="100%" cellpadding="0" cellspacing="0"> <tr> <th>商品编号</th> <th>商品名称</th> <th>用户编号</th> <th>商品价格</th> <th>商品图片</th> <th>商品数量</th> <th>商品总价</th> <th>商品操作</th> </tr> <!-- 调用dao遍历即可 --> <c:forEach items="${listCarts }" var="cart"> <tr id="${cart.getGoods().getGid()}"> <td>${cart.getGoods().getGid()}</td> <td>${cart.getGoods().getGname()}</td> <td>${cart.getUsers().getUserid()}</td> <td>${cart.getGoods().getGprice()}</td> <td><img src="${cart.getGoods().getGpath()}" /></td> <td> <button onclick="edit('mius',${cart.getGoods().getGid()})">-</button> <input type="text" style="width: 40px" value="${cart.getCcount()}" /> <button onclick="edit('add',${cart.getGoods().getGid()})">+</button> </td> <td>${cart.getCtotal()}</td> <td> <button onclick="delCart(${cart.getGoods().getGid()})">删除</button> <button onclick="updateCart(${cart.getGoods().getGid()})">修改</button> </td> </tr> </c:forEach> </table> <hr> <p align="right" style="font-size: 15px; font-weight: bold"> [${pageIndex }/${pageMax }] <a href = "cart.jsp?pageIndex=1">首页</a> <a href = "cart.jsp?pageIndex=${pageIndex-1<0?1:pageIndex-1}">上一页</a> <a href = "cart.jsp?pageIndex=${pageIndex+1>pageMax?pageMax:pageIndex+1}">下一页</a> <a href="cart.jsp?pageIndex=${pageMax}">尾页</a> </p> <script type="text/javascript"> function delCart(id){ if(window.confirm("您确定要删除吗?")){ location.href="doDel.jsp?gid="+id; } } function edit(type,id){ //根据参数id获取tr标签 var tr = document.getElementById(id); //根据tr获取数量 var ccount = tr.cells[4].children[1].value; console.log(ccount); if(type === 'add'){ ccount++; }else if(type==='mius'){ if(ccount>=1){ ccount--; } } tr.cells[4].children[1].value = ccount; } function updateCart(id){ //根据id获取到数量 var tr = document.getElementById(id); var ccount = tr.cells[4].children[1].value; location.href="doUpdate.jsp?gid="+id+"&ccount="+ccount; } </script> </body> </html>