zoukankan      html  css  js  c++  java
  • 【JavaWeb 实际项目 04】

    第五部分:图书模块

    主要包含:首页的图书管理,后台管理-图书管理

    一、MVC概念

    MVC全称:Model模型,View视图,Controller控制器

    MVC最早出现在JavaEE三层中的web层,它可以知道代码有效的分隔,单独工作

    view视图:只负责数据和界面的显示,不接受任何与数据无关的代码,便于程序员和美工到的分工合作--JSP/HTML

    controller控制器:只负责接收请求,调用业务层的代码处理请求,然后派发页面,是一个调度者的角色--Servlet转到某个页面。或者是重定向到某个页面

    Model模型:将与业务逻辑相关的数据封装为具体的JavaBean类,其中不掺杂任何与数据处理相关的代码--javaBean/domain/entity/pojo

    MVC是一种思想

    MVC的理念是将软件代码拆分为组件,单独开发,组合使用(目的还是为了降低耦合度

     mvc的作用还是为了降低耦合。让代码合理分层。方便后期升级和维护

    二、图书模块

    1、编写图书模块的数据库表

    ##创建图书表
    create table t_book(
        `id` int(11) primary key auto_increment,     ## 主键
        `name` varchar(50) not null,                ## 书名 
        `author` varchar(50) not null,                ## 作者
        `price` decimal(11,2) not null,                ## 价格
        `sales` int(11) not null,                    ## 销量
        `stock` int(11) not null,                    ## 库存
        `img_path` varchar(200) not null            ## 书的图片路径
    );

     插入初始数据

    ## 插入初始化测试数据
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , 'java从入门到放弃' , '国哥' , 80 , 9999 , 9 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '数据结构与算法' , '严敏君' , 78.5 , 6 , 13 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '怎样拐跑别人的媳妇' , '龙伍' , 68, 99999 , 52 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '木虚肉盖饭' , '小胖' , 16, 1000 , 50 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , 'C++编程思想' , '刚哥' , 45.5 , 14 , 95 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '蛋炒饭' , '周星星' , 9.9, 12 , 53 , 'static/img/default.jpg');
     
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '赌神' , '龙伍' , 66.5, 125 , 535 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , 'Java编程思想' , '阳哥' , 99.5 , 47 , 36 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , 'JavaScript从入门到精通' , '婷姐' , 9.9 , 85 , 95 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , 'cocos2d-x游戏编程入门' , '国哥' , 49, 52 , 62 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , 'C语言程序设计' , '谭浩强' , 28 , 52 , 74 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , 'Lua语言程序设计' , '雷丰阳' , 51.5 , 48 , 82 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '西游记' , '罗贯中' , 12, 19 , 9999 , 'static/img/default.jpg');
    
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '水浒传' , '华仔' , 33.05 , 22 , 88 , 'static/img/default.jpg');
     
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '操作系统原理' , '刘优' , 133.05 , 122 , 188 , 'static/img/default.jpg');
     
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '数据结构 java版' , '封大神' , 173.15 , 21 , 81 , 'static/img/default.jpg');
     
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , 'UNIX高级环境编程' , '乐天' , 99.15 , 210 , 810 , 'static/img/default.jpg');
     
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , 'javaScript高级编程' , '国哥' , 69.15 , 210 , 810 , 'static/img/default.jpg');
     
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '大话设计模式' , '国哥' , 89.15 , 20 , 10 , 'static/img/default.jpg');
     
    insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) 
    values(null , '人月神话' , '刚哥' , 88.15 , 20 , 80 , 'static/img/default.jpg');
    
    ## 查看表内容
    select id,name,author,price,sales,stock,img_path from t_book;

    2、编写图书模块的JavaBean

    public class Book {
        private  Integer id;
        private String name;
        private String author;
        private BigDecimal price;
        private Integer sales;
        private Integer stock;
        private String imgPath= "static/img/default.jpg";
    
    //图片路径这个需要有个判断 -->在构造方法内编写下面的代码
    
    //要求给定图书封面图书路径不能为空
    if(imgPath != null||"".equals(imgPath)){
        this.imgPath = imgPath;
    }

    3、编写图书模块的dao和测试dao

     BookDao接口 -->查看页面发现,图书模块也是包含了增删改查的操作,所以写增删改查的方法

    public interface BookDao {
    
        //查看页面发现,图书模块也是包含了增删改查的操作
    
        public int addBook(Book book);
    
        public int deleteBook(Integer id);
    
        public int updateBook(Book book);
    
        public Book queryBookById(Integer id);
    
        public List<Book> queryBooks();
    }

    BookDaoImpl类

    package com.wufq.dao.impl;
    
    import com.wufq.dao.BookDao;
    import com.wufq.pojo.Book;
    
    import java.util.List;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/7/19 11:30
     */
    public class BookDaoImpl extends BaseDao implements BookDao{
        @Override
        public int addBook(Book book) {
            String sql = "insert into t_book(`name`,`author`,`price`,`sales`,`stock`,`img_path`)values(?,?,?,?,?,?)";
            return update(sql,book.getName(),book.getAuthor(),book.getPrice(),book.getSales(),book.getStock(),book.getImgPath());
        }
    
        @Override
        public int deleteBookById(Integer id) {
            String sql = "delete from t_book where id = ?";
            return update(sql,id);
        }
    
        @Override
        public int updateBook(Book book) {
            String sql = "update t_book set `name`=?,`author`=?,`price`=?,`sales`=?,`stock`=?,`img_path`=? where id=?";
            return update(sql,book.getName(), book.getAuthor(),book.getPrice(), book.getSales(),book.getStock(),book.getImgPath(),book.getId());
        }
    
        @Override
        public Book queryBookById(Integer id) {
            String sql = "select `id`,`name`,`author`,`price`,`sales`,`stock`,`img_path` imgPath from t_book  where id=?";
            return queryForOne(sql,Book.class,id);
        }
    
        @Override
        public List<Book> queryBooks() {
            String sql="select `id`,`name`,`author`,`price`,`sales`,`stock`,`img_path` imgPath from t_book";
            return queryForList(sql,Book.class);
        }
    }

     BookDaoTest测试类

    package com.wufq.test;
    
    import com.wufq.dao.BookDao;
    import com.wufq.dao.impl.BookDaoImpl;
    import com.wufq.pojo.Book;
    import org.junit.Test;
    
    import java.math.BigDecimal;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/7/23 15:18
     */
    public class BookDaoTest {
    
        private BookDao bookDao = new BookDaoImpl();
    
        @Test
        public void addBook() throws Exception {
            bookDao.addBook(new Book(null,"尘封好厉害","wufq",new BigDecimal(9999),110000,0,null));
        }
    
        @Test
        public void deleteBook() throws Exception {
            bookDao.deleteBook(20);
        }
    
        @Test
        public void updateBook() throws Exception {
            bookDao.updateBook(new Book(19,"大家都好厉害","wufq",new BigDecimal(9999),1100000,0,null));
        }
    
        @Test
        public void queryBookById() throws Exception {
            System.out.println(bookDao.queryBookById(10));
        }
    
        @Test
        public void queryBooks() throws Exception {
            for(Book querybook : bookDao.queryBooks()) {
                System.out.println(querybook);
            }
        }
    
    }

    4、编写图书模块的Service和测试Service

    BookService接口

    package com.wufq.service;
    import com.wufq.pojo.Book;
    import java.util.List;
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/7/23 17:14
     */
    public interface BookService {
    
        public void addBook(Book book);
    
        public void deleteBookById(Integer id);
    
        public void updateBook(Book book);
    
        public Book queryBookById(Integer id);
    
        public List<Book> queryBooks();
    }

    BookServiceImpl类

    package com.wufq.service.impl;
    import com.wufq.dao.BookDao;
    import com.wufq.dao.impl.BookDaoImpl;
    import com.wufq.pojo.Book;
    import com.wufq.service.BookService;
    import java.util.List;
    
    /**
     * @Description
     * @Author wufq
     * @Version
     * @Date 2021/7/23 17:20
     */
    public class BookServiceImpl  implements BookService{
        private BookDao bookDao= new BookDaoImpl();
        @Override
        public void addBook(Book book) {
             bookDao.addBook(book);
        }
    
        @Override
        public void deleteBookById(Integer id) {
             bookDao.deleteBookById(id);
        }
    
        @Override
        public void updateBook(Book book) {
             bookDao.updateBook(book);
        }
    
        @Override
        public Book queryBookById(Integer id) {
             return bookDao.queryBookById(id);
        }
    
        @Override
        public List<Book> queryBooks() {
            return bookDao.queryBooks();
        }
    }

    5、编写图书模块的Web层,和页面联调测试

     5.1、图书列表功能的实现

    |-- 列表功能的流程

     1、修改图书管理的请求地址(manager.jsp) -->依据上面的流程,manager.jsp通过BookServlet程序请求到图书信息的页面数据

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <div><a href="manager/bookServlet?action=list">图书管理</a>
        <a href="pages/manager/order_manager.jsp">订单管理</a>
        <a href="index.jsp">返回商城</a>
    </div>
    manager/bookServlet?请求资源地址,action=list服务器请求的那个方法

    2、编写BookServlet的list请求

     protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1、通过bookService查询全部图书
            List<Book> books = bookService.queryBooks();
            //2、把全部图书保存到Request域中
            req.setAttribute("books",books);
            //3、请求转发到/pages/manager/book_manager.jsp -->这里面的第一个/指的是web目录
            req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req, resp);
        }

    3、修改/pages/manager/book_manager.jsp页面的数据遍历输出

    |-- 首先我们要导入JSTL的包

    <%--循环遍历域中的数据,${requestScope.books}中的books是BookServlet里面的全部图书存储的域名--%>
                <c:forEach items="${requestScope.books}" var="book">
                    <tr>
                        <td>${book.name}</td>
                        <td>${book.price}</td>
                        <td>${book.author}</td>
                        <td>${book.sales}</td>
                        <td>${book.stock}</td>
                        <td><a href="book_edit.jsp">修改</a></td>
                        <td><a href="#">删除</a></td>
                    </tr>
                </c:forEach>

    web.xml文件内配置BookServlet

    <servlet-mapping>
            <servlet-name>BookServlet</servlet-name>
            <!--加manager不是manager这个目录,只是为了后面权限的管理方便-->
            <url-pattern>/manager/bookServlet</url-pattern>
        </servlet-mapping>

    为什么要前面加manager呢?

    通过前后台简单介绍来理解为什么需要加?

    其实就是为了区分前后台访问时的权限问题。

     5.2、添加图书功能实现

    添加图书的流程:

     1、修改book_edit.jsp请求BookServlet的地址

    <body>
            <div id="header">
                <img class="logo_img" alt="" src="static/img/client-7.png" >
                <span class="wel_word">编辑图书</span>
                <%--manager静态模块--%>
                <%@include file="/pages/common/manager.jsp"%>
            </div>
            
            <div id="main">
                <form action="manager/bookServlet" method="get">
                    <%--通过隐藏域告诉服务器调用的是哪个方法--%>
                    <input type="hidden" name="action" value="add">
                    <table>
                        <tr>
                            <td>名称</td>
                            <td>价格</td>
                            <td>作者</td>
                            <td>销量</td>
                            <td>库存</td>
                            <td colspan="2">操作</td>
                        </tr>        
                        <tr>
                            <%--这里要把前面的book去掉,因为要和book的bean里面的属性保持一致--%>
                            <%--<td><input name="book_name" type="text" value="时间简史"/></td>--%>
                            <td><input name="name" type="text" value="时间简史"/></td>
                            <td><input name="price" type="text" value="30.00"/></td>
                            <td><input name="author" type="text" value="霍金"/></td>
                            <td><input name="sales" type="text" value="200"/></td>
                            <td><input name="stock" type="text" value="300"/></td>
                            <td><input type="submit" value="提交"/></td>
                        </tr>    
                    </table>
                </form>
                
        
            </div>
    
            <%--每个页面的页脚--%>
            <%@include file="/pages/common/fooler.jsp"%>
    </body>

    2、编写BookServlet的add方法

    protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            //1、获取请求的参数,封装成book对象
            Book book = WebUtils.copyParamToBean(req.getParameterMap(), new Book());
            //2、调用bookService.addBook()方法保存图书
            bookService.addBook(book);
            //3、跳到图书列表页面(要使用重定向)/manager/bookServlet?action=list
            /*
            * 这么写有一个bug:重复提交表单,当用户在页面刷新(F5)时,会发送两次请求并且请求的地址是最后一次请求的地址
            * (http://localhost:8080/book/manager/bookServlet?action=add&name=xxx&price=30.00&author=xxx&sales=200&stock=300)
            *
            * 解决这种问题,需要加上一个重定向:重新把去请求的地址跳转到提交之前的地址上
            * (http://localhost:8080/book/manager/bookServlet?action=list)
            */
            //req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req, resp);
            resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=list");
        }

     5.3、删除图书功能的实现

    1、删除流程

    点击删除按钮(删除按钮对应发送到服务器的地址:manager/bookServlet?action=delete&id=图书编号),请求到BookServlet处理后返回地址到浏览器

    2、修改book_manager.jsp文件

     <%--循环遍历域中的数据,${requestScope.books}中的books是BookServlet里面的全部图书存储的域名--%>
                <c:forEach items="${requestScope.books}" var="book">
                    <tr>
                        <td>${book.name}</td>
                        <td>${book.price}</td>
                        <td>${book.author}</td>
                        <td>${book.sales}</td>
                        <td>${book.stock}</td>
                        <td><a href="book_edit.jsp">修改</a></td>
                        <td><a href="/manager/bookServlet?action=delete&${book.id}">删除</a></td>
                    </tr>
                </c:forEach>

    注意:book.id是页面传过来的id,而id,name...等又是通过BookDaoImpl对应的sql语句中查询出来的

    3、bookServlet编写delete方法

     protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            //1、获取请求的参数id,图书编号
            int id = WebUtils.parseInter(req.getParameter("id"),0);
            //2、调用BookService.deleteBookById(),删除图书
            bookService.deleteBookById(id);
            //3、重定向回图书列表管理页面
            resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=list");
    
        }

    4、WebUtils内添加int类型转换的工具方法

    //    String类型转换成Integer类型
        public static int parseInter(String str,int defautInt){
            try {
                return Integer.parseInt(str);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            return defautInt;
        }

    5、在book_manager.jsp中给删除添加确认提示操作

    <head>
    <meta charset="UTF-8">
    <title>图书管理</title>
        <%--静态包含base标签、css样式、jQuery--%>
        <%@include file="/pages/common/head.jsp"%>
    
        <%--给删除添加删除确认操作--%>
        <script type="text/javascript">
            $(function(){
                //给删除的a标签绑定单击事件,用于删除的确认操作
                $("a.deleteClass").click(function(){
    
                    /*在时间的function函数中,有一个this对象,这个this对象,是当前正在响应的dom对象
    
                    confirm 是确认提示框函数
                    参数是他的提示内容
                    他有两个按钮,一个确认按钮,一个取消按钮
                    返回true表示点击,返回false表示取消了
                    $(this)-->表示删除的a标签对象,parent是获取他的父层td,tr.find("td:first").text()-->表示去找td下面的第一个内容文本
                    * */
                    return confirm("你确定要删除【"+$(this).parent().parent().find("td:first").text()+"】")
                });
            });
    
        </script>
    </head>

    5.4、修改图书功能的实现

    1、修改流程

    2、修改book_manager.jsp内【修改】的请求地址

    <c:forEach items="${requestScope.books}" var="book">
                    <tr>
                        <td>${book.name}</td>
                        <td>${book.price}</td>
                        <td>${book.author}</td>
                        <td>${book.sales}</td>
                        <td>${book.stock}</td>
                        <td><a href="manager/bookServlet?action=getBook&id=${book.id}">修改</a></td>
                        <td><a class="deleteClass" href="manager/bookServlet?action=delete&id=${book.id}">删除</a></td>
                    </tr>
                </c:forEach>

    3、增加BookServlet内getBook方法

    protected void getBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            //1、获取图书编号
            int id = WebUtils.parseInter(req.getParameter("id"),0);
            //2、调用bookService.queryBookById(id)得到图书信息
            Book book = bookService.queryBookById(id);
            //3、把图书信息保存到图书域中
            req.setAttribute("book",book);
            //4、请求转发到book_edit.jsp页面
            req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp);
        }

    4、修改book_edit.jsp页面

    <tr><td><input name="name" type="text" value="${requestScope.book.name}"/></td>
      <td><input name="price" type="text" value="${requestScope.book.price}"/></td>
      <td><input name="author" type="text" value="${requestScope.book.author}"/></td>
      <td><input name="sales" type="text" value="${requestScope.book.sales}"/></td>
      <td><input name="stock" type="text" value="${requestScope.book.stock}"/></td>
      <td><input type="submit" value="提交"/></td>
    </tr>    

    5、编写BookServlet的update方法

    protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1、获取请求的参数封装成book对象
            Book book = WebUtils.copyParamToBean(req.getParameterMap(), new Book());
            //2、调用bookService.updateBook(book);修改图书
            bookService.updateBook(book);
            //3、重定向到/manager/bookServlet?action=list页面
            resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=list");
        }

    6、解决book_edit.jsp页面,既要实现添加操作,又要实现修改操作

    <div id="main">
                <form action="manager/bookServlet" method="get">
                    <%--通过隐藏域告诉服务器调用的是哪个方法--%>
                    <input type="hidden" name="action" value="${empty param.id?"add":"update"}"/>
                     <input type="hidden" name="id" value="${requestScope.book.id}"/>
                    <table>
                        <tr>
                            <td>名称</td>
                            <td>价格</td>
                            <td>作者</td>
                            <td>销量</td>
                            <td>库存</td>
                            <td colspan="2">操作</td>
                        </tr>        
  • 相关阅读:
    MyEclipse 2015 Stable 2.0破解方法
    GeoGlobe Server运维
    GeoGlobe Server运维
    Silverlight用户无法注册之MySql.Data.dll不一致
    Photoshop影像匀色技术
    GeoGlobe Server使用问题收集
    Windows Server 2008 R2中无法使用360免费Wifi的解决方案
    吉奥平台软件安装经验分享
    U盘中毒后变为快捷方式的解决方法
    主机访问虚拟机中新建的网站
  • 原文地址:https://www.cnblogs.com/frankruby/p/15012425.html
Copyright © 2011-2022 走看看