• 【后端】黑马MVC案例详解


    最近刚入门后端,对不起,我背叛了游戏【哭】

    跟着写了一个这样的案例

    网页界面是这样的

     没写删除,里面带有增加行和修改表单数据的功能

     

     web方面就三个页面,里面涉及到了Mybatis,Tomcat,JSP,Servlet,Maven,前端三剑客等知识,东西比较杂,我也是速通选手,掌握不太稳固,所以写个文章巩固一下知识点,以便自己能够更好地理解代码以及运行逻辑。

    项目结构是这样的,需要配置mybatis-config.xml文件,pom.xml需要引入tomcat、Servlet,mybatis,JSP,Maven写个标识就能自动下载了,Maven好方便

    以及Mapper配置文件和web配置文件,不是很复杂。

    我们的代码方面

    一、前端页面

    三个前端页面分别是这样的

    brand:主页面

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    3. html>
    4. <html lang="en">
    5. <head>
    6. <meta charset="UTF-8">
    7. <title>Titletitle>
    8. head>
    9. <body>
    10. <input type="button" value="新增" id="add"><br>
    11. <hr>
    12. <table border="1" cellspacing="0" width="80%">
    13. <tr>
    14. <th>序号th>
    15. <th>品牌名称th>
    16. <th>企业名称th>
    17. <th>排序th>
    18. <th>品牌介绍th>
    19. <th>状态th>
    20. <th>操作th>
    21. tr>
    22. <c:forEach items="${brands}" var="brand" varStatus="status">
    23. //items:被遍历的容器
    24. //var:遍历产生的临时变量
    25. //varStatus:遍历状态对象
    26. //我们这里是从SelectAllServlet跳转过来的,所以接收了request域,我们只管调brand对象输出数据就行
    27. <tr align="center">
    28. <%--<td>${brand.id}td>--%>
    29. <td>${status.count}td>
    30. <td>${brand.brandName}td>
    31. <td>${brand.companyName}td>
    32. <td>${brand.ordered}td>
    33. <td>${brand.description}td>
    34. <c:if test="${brand.status == 1}">//这里是JSP,就是if判断
    35. <td>启用td>
    36. c:if>
    37. <c:if test="${brand.status != 1}">
    38. <td>禁用td>
    39. c:if>
    40. <td><a href="/brandDemo/selectByIdServlet?id=${brand.id}">修改a> <a href="#">删除a>td>
    41. tr>
    42. c:forEach>
    43. table>
    44. <script>
    45. document.getElementById("add").onclick = function (){
    46. location.href = "/brandDemo/addBrand.jsp";
    47. }//这里使用getElementById设置了按钮的点击事件。
    48. script>
    49. body>
    50. html>

     addBrand:新增数据

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. html>
    3. <html lang="en">
    4. <head>
    5. <meta charset="UTF-8">
    6. <title>添加品牌title>
    7. head>
    8. <body>
    9. <h3>添加品牌h3>
    10. <form action="/brandDemo/addServlet" method="post">//这里我们提交到addServlet服务,还是以POST形式,然后addServlet再转发到brand.jsp页面
    11. 品牌名称:<input name="brandName"><br>
    12. 企业名称:<input name="companyName"><br>
    13. 排序:<input name="ordered"><br>
    14. 描述信息:<textarea rows="5" cols="20" name="description">textarea><br>
    15. 状态:
    16. <input type="radio" name="status" value="0">禁用
    17. <input type="radio" name="status" value="1">启用<br>
    18. <input type="submit" value="提交">
    19. form>
    20. body>
    21. html>

    update:修改数据

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    3. html>
    4. <html lang="en">
    5. <head>
    6. <meta charset="UTF-8">
    7. <title>修改品牌title>
    8. head>
    9. <body>
    10. <h3>修改品牌h3>
    11. <form action="/brandDemo/updateServlet" method="post">//这里还是一样的,提交到updateServlet服务当中
    12. //这里跟新增表单页面没什么大的不同,但是Servlet方面就要先查询再修改,还是比新增麻烦的
    13. <%--隐藏域,提交id--%>
    14. <input type="hidden" name="id" value="${brand.id}">
    15. 品牌名称:<input name="brandName" value="${brand.brandName}"><br>
    16. 企业名称:<input name="companyName" value="${brand.companyName}"><br>
    17. 排序:<input name="ordered" value="${brand.ordered}"><br>
    18. 描述信息:<textarea rows="5" cols="20" name="description">${brand.description} textarea><br>
    19. 状态:
    20. <c:if test="${brand.status == 0}">
    21. <input type="radio" name="status" value="0" checked>禁用
    22. <input type="radio" name="status" value="1">启用<br>
    23. c:if>
    24. <c:if test="${brand.status == 1}">
    25. <input type="radio" name="status" value="0" >禁用
    26. <input type="radio" name="status" value="1" checked>启用<br>
    27. c:if>
    28. <input type="submit" value="提交">
    29. form>
    30. body>
    31. html>

    二、mybatis操作方面

    既然处理数据肯定是要学习mybatis的

    操作不难,写几个接口就行

    这里则是使用到mapper的知识,不得不说,javaweb学的东西是真的杂,学的时候天天导包配文件,累。

    BrandMapper:

    1. package com.itheima.mapper;
    2. import com.itheima.pojo.Brand;
    3. import org.apache.ibatis.annotations.Insert;
    4. import org.apache.ibatis.annotations.ResultMap;
    5. import org.apache.ibatis.annotations.Select;
    6. import org.apache.ibatis.annotations.Update;
    7. import java.util.List;
    8. public interface BrandMapper {//这里也没啥好说的,以注解形式操纵数据库,都是一些基础操作语句
    9. //唯一值得注意的是当我们两种模式命名有冲突的时候我们要配置ResultMap
    10. //使得我们Brand查询的时候能找到对应的变量
    11. /*
    12. 查询所有
    13. @return
    14. */
    15. @Select("select * from tb_brand")
    16. @ResultMap("brandResultMap")
    17. List selectAll();
    18. @Insert("insert into tb_brand values(null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
    19. void add(Brand brand);
    20. /**
    21. * 根据id查询
    22. * @param id
    23. * @return
    24. */
    25. @Select("select * from tb_brand where id = #{id}")
    26. @ResultMap("brandResultMap")
    27. Brand selectById(int id);
    28. /**
    29. * 修改
    30. * @param brand
    31. */
    32. @Update("update tb_brand set brand_name = #{brandName},company_name = #{companyName},ordered = #{ordered},description = #{description},status = #{status} where id = #{id}")
    33. void update(Brand brand);
    34. }

    brand数据类:

    1. package com.itheima.pojo;
    2. public class Brand {
    3. // id 主键
    4. private Integer id;
    5. // 品牌名称
    6. private String brandName;
    7. // 企业名称
    8. private String companyName;
    9. // 排序字段
    10. private Integer ordered;
    11. // 描述信息
    12. private String description;
    13. // 状态:0:禁用 1:启用
    14. private Integer status;
    15. //提供了三种构造方法以备不同情况,是一些面向对象的特性,Java学过的都能懂
    16. public Brand() {
    17. }
    18. public Brand(Integer id, String brandName, String companyName, String description) {
    19. this.id = id;
    20. this.brandName = brandName;
    21. this.companyName = companyName;
    22. this.description = description;
    23. }
    24. public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
    25. this.id = id;
    26. this.brandName = brandName;
    27. this.companyName = companyName;
    28. this.ordered = ordered;
    29. this.description = description;
    30. this.status = status;
    31. }
    32. public Integer getId() {
    33. return id;
    34. }
    35. public void setId(Integer id) {
    36. this.id = id;
    37. }
    38. public String getBrandName() {
    39. return brandName;
    40. }
    41. public void setBrandName(String brandName) {
    42. this.brandName = brandName;
    43. }
    44. public String getCompanyName() {
    45. return companyName;
    46. }
    47. public void setCompanyName(String companyName) {
    48. this.companyName = companyName;
    49. }
    50. public Integer getOrdered() {
    51. return ordered;
    52. }
    53. public void setOrdered(Integer ordered) {
    54. this.ordered = ordered;
    55. }
    56. public String getDescription() {
    57. return description;
    58. }
    59. public void setDescription(String description) {
    60. this.description = description;
    61. }
    62. public Integer getStatus() {
    63. return status;
    64. }
    65. public void setStatus(Integer status) {
    66. this.status = status;
    67. }
    68. @Override
    69. public String toString() {
    70. return "Brand{" +
    71. "id=" + id +
    72. ", brandName='" + brandName + '\'' +
    73. ", companyName='" + companyName + '\'' +
    74. ", ordered=" + ordered +
    75. ", description='" + description + '\'' +
    76. ", status=" + status +
    77. '}';
    78. }
    79. }

    三、Servlet服务

    这里就是处理数据的大头了

    因为创建工厂类只用一次就能最节省资源,所以我们用一个SqlSessionFactoryUtils静态类来封装好,下次直接调函数就行了,这里还是操作mybatis的东西

    1. package com.itheima.util;
    2. import org.apache.ibatis.io.Resources;
    3. import org.apache.ibatis.session.SqlSessionFactory;
    4. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    5. import java.io.IOException;
    6. import java.io.InputStream;
    7. public class SqlSessionFactoryUtils {
    8. private static SqlSessionFactory sqlSessionFactory;//静态对象
    9. static {
    10. try{//这里是数据库连接必写的三句
    11. String resource = "mybatis-config.xml";
    12. InputStream inputStream = Resources.getResourceAsStream(resource);
    13. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    14. }catch (IOException e){
    15. e.printStackTrace();
    16. }
    17. }
    18. public static SqlSessionFactory getSqlSessionFactory(){
    19. return sqlSessionFactory;//用的时候直接调这个方法
    20. }
    21. }

    随后写BrandService,这里是将对数据的操作全都封装好,免得到时候麻烦

    代码是这样的

    1. package com.itheima.service;
    2. import com.itheima.mapper.BrandMapper;
    3. import com.itheima.pojo.Brand;
    4. import com.itheima.util.SqlSessionFactoryUtils;
    5. import org.apache.ibatis.session.SqlSession;
    6. import org.apache.ibatis.session.SqlSessionFactory;
    7. import java.util.List;
    8. public class BrandService {
    9. SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();//这里获取工厂类
    10. /*
    11. 查询所有
    12. @return
    13. */
    14. public List selectAll(){//查询所有
    15. //调用BrandMapper.selectAll()
    16. //2.获取SqlSession
    17. SqlSession sqlSession = factory.openSession();
    18. //3.获取BrandMapper
    19. BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    20. //4.调用方法
    21. List brands = mapper.selectAll();//这里就是操作数据库,然后封装到一个brands列表里
    22. sqlSession.close();
    23. return brands;//返回查询到的值
    24. }
    25. /**
    26. * 添加
    27. * @param brand
    28. */
    29. public void add(Brand brand){//这里是添加
    30. //2. 获取SqlSession
    31. SqlSession sqlSession = factory.openSession();
    32. //3. 获取BrandMapper
    33. BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    34. //4. 调用方法
    35. mapper.add(brand);//往数据库里添加一个brand对象
    36. //提交事务
    37. sqlSession.commit();
    38. //释放资源
    39. sqlSession.close();
    40. }
    41. /**
    42. * 根据id查询
    43. * @return
    44. */
    45. public Brand selectById(int id){//依靠id查询对象
    46. //调用BrandMapper.selectAll()
    47. //2. 获取SqlSession
    48. SqlSession sqlSession = factory.openSession();
    49. //3. 获取BrandMapper
    50. BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    51. //4. 调用方法
    52. Brand brand = mapper.selectById(id);
    53. sqlSession.close();
    54. return brand;
    55. }
    56. /**
    57. * 修改
    58. * @param brand
    59. */
    60. public void update(Brand brand){//修改值
    61. //2. 获取SqlSession
    62. SqlSession sqlSession = factory.openSession();
    63. //3. 获取BrandMapper
    64. BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
    65. //4. 调用方法
    66. mapper.update(brand);
    67. //提交事务
    68. sqlSession.commit();
    69. //释放资源
    70. sqlSession.close();
    71. }
    72. }

    然后是Servlet服务类

    通过这些服务我们来操作网页里的数据

    SelectAllServlet:

    1. package com.itheima.web;
    2. import com.itheima.pojo.Brand;
    3. import com.itheima.service.BrandService;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.annotation.WebServlet;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. import java.io.IOException;
    10. import java.util.List;
    11. @WebServlet("/selectAllServlet")//这里我们通过标签访问Servlet
    12. public class SelectAllServlet extends HttpServlet {
    13. private BrandService service = new BrandService();//先创建一个Brand服务对象
    14. @Override
    15. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    16. //1、调用BrandService完成查询
    17. List brands = service.selectAll();//这里我们直接调用查询
    18. //2、存入request域中
    19. req.setAttribute("brands",brands);//存入request域,到时候发出去的就是这个,要查询的话只要调用键查值就行了,request域都是键值对。
    20. //3、转发到brand.jsp
    21. req.getRequestDispatcher("/brand.jsp").forward(req,resp);//这里我们调用getrequestDispatcher方法转发到brand.jsp页面中,再通过JSP代码把数据显示出来。
    22. }
    23. @Override
    24. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    25. this.doGet(req,resp);//这样写能同时响应POST请求和GET请求
    26. }
    27. }

    AddServlet:

    1. package com.itheima.web;
    2. import com.itheima.pojo.Brand;
    3. import com.itheima.service.BrandService;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.annotation.WebServlet;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. import java.io.IOException;
    10. @WebServlet("/addServlet")
    11. public class AddServlet extends HttpServlet {
    12. private BrandService service = new BrandService();
    13. @Override
    14. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    15. //处理POST请求的乱码问题
    16. request.setCharacterEncoding("utf-8");
    17. //1. 接收表单提交的数据,封装为一个Brand对象
    18. String brandName = request.getParameter("brandName");
    19. String companyName = request.getParameter("companyName");
    20. String ordered = request.getParameter("ordered");
    21. String description = request.getParameter("description");
    22. String status = request.getParameter("status");
    23. //封装为一个Brand对象
    24. Brand brand = new Brand();
    25. brand.setBrandName(brandName);
    26. brand.setCompanyName(companyName);
    27. brand.setOrdered(Integer.parseInt(ordered));
    28. brand.setDescription(description);
    29. brand.setStatus(Integer.parseInt(status));
    30. //2. 调用service 完成添加
    31. service.add(brand);
    32. //3. 转发到查询所有Servlet
    33. request.getRequestDispatcher("/selectAllServlet").forward(request,response);
    34. }
    35. @Override
    36. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    37. this.doGet(request, response);
    38. }
    39. }

    SelectById:

    1. package com.itheima.web;
    2. import com.itheima.pojo.Brand;
    3. import com.itheima.service.BrandService;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.annotation.WebServlet;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. import java.io.IOException;
    10. @WebServlet("/selectByIdServlet")
    11. public class SelectByIdServlet extends HttpServlet {
    12. private BrandService service = new BrandService();
    13. @Override
    14. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    15. //1、接受id
    16. String id = req.getParameter("id");
    17. //2、调用service查询
    18. Brand brand = service.selectById(Integer.parseInt(id));
    19. //3、存储到request中
    20. req.setAttribute("brand",brand);
    21. //4、转发到update.jsp
    22. req.getRequestDispatcher("/update.jsp").forward(req,resp);
    23. }
    24. @Override
    25. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    26. this.doGet(req, resp);
    27. }
    28. }

    Updateservlet:

    1. package com.itheima.web;
    2. import com.itheima.pojo.Brand;
    3. import com.itheima.service.BrandService;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.annotation.WebServlet;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. import java.io.IOException;
    10. @WebServlet("/updateServlet")
    11. public class UpdateServlet extends HttpServlet {
    12. private BrandService service = new BrandService();
    13. @Override
    14. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    15. //处理POST请求的乱码问题
    16. req.setCharacterEncoding("utf-8");
    17. //1、接受表单提交的数据
    18. String id = req.getParameter("id");
    19. String brandName = req.getParameter("brandName");
    20. String companyName = req.getParameter("companyName");
    21. String ordered = req.getParameter("ordered");
    22. String description = req.getParameter("description");
    23. String status = req.getParameter("status");
    24. //封装为一个Brand对象
    25. Brand brand = new Brand();
    26. brand.setId(Integer.parseInt(id));
    27. brand.setBrandName(brandName);
    28. brand.setCompanyName(companyName);
    29. brand.setOrdered(Integer.parseInt(ordered));
    30. brand.setDescription(description);
    31. brand.setStatus(Integer.parseInt(status));
    32. //2、调用serice完成修改
    33. service.update(brand);
    34. //3、转发到查询所有Servlet
    35. req.getRequestDispatcher("/selectAllServlet").forward(req,resp);
    36. }
    37. @Override
    38. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    39. this.doGet(req, resp);
    40. }
    41. }

    代码差不多就这样了,做完发现东西还挺多的,面向对象要写的东西还是挺多的。

     

    下面是逻辑的梳理,说实话梳理逻辑确实是要花上一些时间

    展现brand页面:通过查询tb_brand和JSP以及HTML、CSS来展现出数据库里的数据

    访问顺序:SelectAll.class->brand.jsp

    新增数据:填写表单数据->在数据库中实现添加->addServlet->selectAllServlet->发送到brand.jsp->展现数据

    访问顺序:brand.jsp->AddServlet.class->update.jsp->SelectAllServlet.class->brand.jsp

    修改数据:通过查询当前id所对应的表将其发送到update.jsp0界面->填写修改后的数据->提交表单数据->在数据库中实现修改->查询所有->brand.jsp展现数据

    访问顺序:brand.jsp->SelectByIdServlet->update.jsp->updateServlet->SelectAllServlet->brand.jsp

  • 相关阅读:
    Spring 源码(3)Spring BeanFactory 是怎么创建的?
    python加载图片无法显示原因探究/python内存回收机制作祟
    MySQl数据库————DQL数据查询语言
    vulnhub之tomato(西红柿)
    【C++模拟实现】map、set容器的模拟实现
    IDEA插件开发(8)---Listeners
    【软考中级】网络工程师:7.下一代互联网
    中国口罩及其他防护用品行业市场深度调研与发展趋势报告
    Python---练习:while循环嵌套(用两次while三步走--里外各一次)
    【Java】引用类型数组的理解与操作
  • 原文地址:https://blog.csdn.net/qq_63499305/article/details/130901480