图书馆商城 ---代码回溯1

成果图

image.png

image.png

搭建环境

intellij idea

包结构

  • 后台主要为Dao、Service、Pojo、Servlet


    image.png

    image.png
  • 前台分为后端的jsp和前端的jsp


    image.png

    image.png

导入的工具类以及方法

image.png

后台管理界面

主要分为

  • 添加删除书类

  • 显示书类

  • 添加删除书籍

  • 显示书籍

  • 显示所有订单
    共6个界面 其中头部和左侧是共用代码部分为了代码复用所以这里把头部和左侧单独写入,然后使用静态引入的方法加载到页面中

  • head

<div class="container head ">
    <h2 class="animated swing">后台管理</h2>
    <hr>
</div>

头部代码很简单 ,就使用了一个h2标签 为了好看点再引入一个 animated的摇摆特效

  • left
 <ul class="mainul">
        <div class="contents">
            <li class="maintile">分类管理</li>
            <ul>
                <li><a href = "/BackMain/AddCategory.jsp">添加分类</a></li>
                <li><a href = "/page?oper=showCategory">查看分类</a></li>
            </ul>
        </div>
        <div class="contents">
            <li class="maintile">图书管理</li>
            <ul class="contents">
                <li><a href="/page?oper=addCategoryUi">添加图书</a></li>
                <li><a href="/page?oper=showBooks">查看图书</a></li>
            </ul>
        </div>
        <div class="contents">
            <li class="maintile">订单管理</li>
            <ul>
                <li><a href = "/createorder?&oper=GetAllOrder">所有订单</a></li>
            </ul>
        </div>
    </ul>

左侧使用了两级 ul菜单,第一级为分类管理,图书管理,订单管理,第二级是对第一级的细化。其代码为在第一级的ul元素下继续使用ul元素。

完成了这两部分之后我们可以继续写主要业务功能了。

分类功能

创建分类数据表

CREATE TABLE category (

  id         int auto_increment,
  name        VARCHAR(10) NOT NULL UNIQUE ,
  description VARCHAR(255)
);

对应数据库的表

创建分类pojo

Category

    private int id;
    private String name;
    private String description;

//各种get、set、ToString

Dao层接口

CategoryDao

public interface CategoryDao {
    int AddCategory(Category category);
    Category FindCategory(int id);
    List<Category> ShowAllCategory();
    int DeleteCategory(int id);
}

Dao层细节

CategoryDaoImpl

public class CategoryDaoImpl implements CategoryDao {
    private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
    private static QueryRunner queryRunner = new QueryRunner(dataSource);
    @Override
    public int AddCategory(Category category) {
        int result = 0;
        String sql = "INSERT INTO category (id, name, description) VALUES(?,?,?)";
            try {
         result = queryRunner.update(sql, new Object[]{category.getId(), category.getName(), category.getDescription()});
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return result;
    }

    @Override
    public Category FindCategory(int id) {
        Category category;
        String sql = "Select * from category where id = ?";
        try{
           category = (Category) queryRunner.query(sql, id, new BeanHandler(Category.class));
        }catch (SQLException e){
            throw  new RuntimeException(e);
        }
        return category;
    }

    @Override
    public List<Category> ShowAllCategory() {
        List<Category> cl = new ArrayList<>();
        String sql = "Select * from category";
        try{
            cl = ( List<Category>) queryRunner.query(sql, new BeanListHandler(Category.class));
        }catch (SQLException e){
            throw  new RuntimeException(e);
        }
        return cl;

    }

    @Override
    public int DeleteCategory(int id) {
        int result = 0;
        String sql = "delete from category where id = ?";
        try {
            result = queryRunner.update(sql, id);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return result;
    }
}

为了方便操作数据库 ,这里我们使用了queryRunner 的jar包
使用前我们需要先配置好xml文件 然后设置数据源

  • xml文件
  <named-config name="mysql">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/booksystem?characterEncoding=utf8</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>

导入jar包后设置数据源

    private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
    private static QueryRunner queryRunner = new QueryRunner(dataSource);

这样我们就能 从本地mysql拿到数据了

这里主要用到的是queryRunner 的update方法和query方法
update方法

//用于添加删除修改
  result = queryRunner.update(sql语句, 参数);

query方法

//获得查询结果集
  queryRunner.query(sql语句, 查询结果集合的类型);

Demo层测试

再往下写之前可以写一个Demo层来测试下前面的Dao层是否能拿到数据,以便后面的bug调试

CategoryService 层

将从Dao层拿到的数据流转到Service层
先写接口

public interface CategoryService {
    int AddCategory(Category category);
    Category FindCategory(int id);
    List<Category> ShowAllCategory();
    int DeleteCategory(int id);
}

再在impl中细写逻辑判断 并输出相关内容到后台

public class CategoryServiceImpl implements CategoryService {
    CategoryDao cd = new CategoryDaoImpl();
    @Override
    public int AddCategory(Category category) {

        int result = cd.AddCategory(category);
        if(result>0){
            System.out.println("添加成功");
        }else {
            System.out.println("添加失败");
        }
        return result;
    }

    @Override
    public Category FindCategory(int id) {
        return cd.FindCategory(id);
    }

    @Override
    public List<Category> ShowAllCategory() {
        return cd.ShowAllCategory();
    }

    @Override
    public int DeleteCategory(int id) {
        int result = cd.DeleteCategory(id);
        if(result>0){
            System.out.println("删除成功");
        }else {
            System.out.println("删除失败");
        }
        return result;
    }
}

添加分类jsp

我们通过

<%@include file="Head.jsp"%>

jsp静态引入的方式引入我们上面写的head文件
然后用 bootstrap的分栏方式来进行布局
采用简单的 3/9分

<div class="container">
    <div class="col-md-3">
     //左侧大致分栏
    </div>
    <div class="col-md-9">
    //右侧主要内容
    </div>
 <form action="/page">
                <input type="hidden" name="oper" value="addList">
                <div class="form-group">
                    <label>分类名称:</label>
                    <input class="form-control" type="text" name="categoryName" value="">
                </div>

                <div class="form-group">
                    <label>分类描述:</label>
                    <textarea class="form-control" name="CategoryDescription" value=""></textarea>
                </div>

                <input type="submit" value="提交">
            </form>

在右侧放入的一个form表单 将其提交到一个叫/page的servelet

/pageservlet

第一步肯定是覆写service方法啦

 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置输入和输出编码格式
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
//拿到名为oper的操作符,以便写后续其他功能
        String oper = req.getParameter("oper");
        if(oper.equals("addList")){
//封装成函数调用
            AddList(req,resp);
        }else if(oper.equals("showCategory")){
         //其他功能函数
        }
}

可以看到在上面的jsp中我们隐藏了一个input

    <input type="hidden" name="oper" value="addList">

就是为了区分不同的操作

addlist 函数

 private void AddList(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String categoryName = req.getParameter("categoryName");
        String categoryDescrption = req.getParameter("CategoryDescription");
        Category category = new Category();
        category.setName(categoryName);
        category.setDescription(categoryDescrption);
        System.out.println(category);
        int result = cs.AddCategory(category);
        if(result>0){
            req.setAttribute("flag",1);
            req.getRequestDispatcher("/BackMain/AddCategory.jsp").forward(req,resp);
        }
    }

如果添加成功的话,我们在request的中添加了一个flag对象,并且转发请求回到AddCategory.jsp上。
在AddCategory.jsp中判断是否有flag,如果有则输出添加成功,如果没有 ,则添加失败

//jstl+ei表达式写法
  <c:if test="${!empty(requestScope.flag)}">
                <p>添加分类成功</p>
            </c:if>
//原生jsp写法
            <%if(request.getAttribute("flag")!=null){%>
            <p>添加分类成功</p>
            <% }%>

效果图

aaaddn.gif

查看分类

  • 编写查看分类的servlet
private void ShowCategory(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<Category> lc = cs.ShowAllCategory();
        HttpSession hs = req.getSession();
        hs.setAttribute("Catelist",lc);
//        req.setAttribute("Catelist",lc);
        resp.sendRedirect("/BackMain/ShowCategory.jsp");
    }
  • 显示界面 jsp
<table class="showCategory table table-striped table-hover">
            <thead>
            <tr>
                <td>分类编号</td>
                <td>分类名字</td>
                <td>分类介绍</td>
                <td>操作</td>
            </tr>
            </thead>
            <tbody>
            <c:forEach items="${sessionScope.Catelist}" var = "category">
                <tr>
                    <td>${category.id}</td>
                    <td>${category.name}</td>
                    <td>${category.description}</td>
                    <td><a href = "#"onclick="Topage(this)">删除</a></td>
                </tr>
            </c:forEach>
            </tbody>
        </table>

放在table中 通过jstl 的foreach表达式拿出来

  • 删除类
    ps:这里打算用ajax删除,并且用的ajax都是原生js写的 并没有用jquery

先给每一个删除一个js函数 topage()
参数this是为了获取类id

 var myTable =document.getElementsByClassName("showCategory")[0];
    function Topage (obj) {
        console.log();
        var flag  = window.confirm("你确定要删除吗");

        if(flag) {
            var ajax;
            var index = obj.parentElement.parentElement.firstElementChild.innerHTML;
            if (window.XMLHttpRequest) {
                ajax = new XMLHttpRequest();
            } else if (window.ActiveXObject) {
                ajax = new ActiveXObject("Msxml2.XMLHTTP");
            }
            //复写onreadystatechange函数
            ajax.onreadystatechange = function () {
                if (ajax.readyState == 4) {
                    // window.location.href = "/page?oper=showCategory";
                    var item = obj.parentElement.parentElement;
                    item.parentElement.removeChild(item);
                }
                if (ajax.status == 404) {
                }
            }
            ajax.open("get", "/page?oper=deleteCategory&CategoryId=" + index);
            ajax.send(null);
        }
    }

因为categoryid 是父类的父类的第一个子类的内容
拿到index 后通过添加在get的后面传过去。
完成操作后再用前端删除掉这一列即可。
删除用remove方法

//js删除自身元素节点
 item.parentElement.removeChild(item);

跳转到的删除servlet

    private void DeleteCategory(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int CategoryId = Integer.parseInt(req.getParameter("CategoryId"));
        int result = cs.DeleteCategory(CategoryId);
    }

拿到get传来得index数据同时用parserInt方法转成int类型
传入写好的cs类完成删除操作

图书操作

关于添加、删除 、显示图书的操作同理,不过有一点是 添加图书分类的时候应出现一个下拉框,从已有的分类选取。
这里大部分只贴代码 不再赘述

建立图书表

create table Book(
    id  int auto_increment primary key,
    category_id int,
    name varchar(20) not null,
    description varchar(255),
    author varchar(20),
    price float,
    image_id varchar(100),
    constraint category_id_fk FOREIGN key(category_id) REFERENCES category(id)
)
  • pojo层建立图书类
    int id;
    int category_id;
    String name;
    String description;
    String author;
    float price;
    String image_id;

各种set get tostring
  • 建立BookDao层接口
public interface BookDao {
    int AddBook(Book book);
    int DeleteBook(int id);
    List<Book> ShowAllBooks();
    Book FindBook(int id);
    List<Book> ShowCategoryBook(int id);
}
  • servlet
private void AddBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        String author = req.getParameter("author");
        float price = Float.parseFloat(req.getParameter("price"));
        int categoryId = Integer.parseInt(req.getParameter("categoryId"));
        String imageId = req.getParameter("imageId");
        String descirption = req.getParameter("description");
        System.out.println(name+author+price+categoryId+imageId+descirption);
        Book book = new Book(0,categoryId,name,descirption,author,price,imageId);
        int result = bs.AddBook(book);
        if(result>0){
            req.setAttribute("message",1);
            req.getRequestDispatcher("/BackMain/AddBook.jsp").forward(req,resp);
        }
    }
    private void ShowBooks(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<Book> lb = bs.ShowAllBooks();
        req.setAttribute("BookList",lb);
        req.getRequestDispatcher("/BackMain/ShowBook.jsp").forward(req,resp);

    }
    private void DeleteBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int bookId = Integer.parseInt(req.getParameter("BookId"));
        int result = bs.DeleteBook(bookId);
    }
  • 添加jsp
       <div class="addBook">
            <form action="/page" method="post" >
                <input type="hidden" name="oper" value="addbook">
                <div class="form-group">
                    <label>图书名称</label>
                    <input  class="form-control" type="text" name="name">
                </div>
                <div class="form-group">
                    <label>作者:</label>
                    <input   class="form-control"type="text" name="author">
                </div>
                <div class="form-group">
                    <label>图书价钱</label>
                    <input   class="form-control" type="text" name="price">
                </div>
                <div class="form-group">
                    <label>类型</label>
                    <select   class="form-control" name="categoryId">
                        <c:forEach items="${requestScope.category}" var="category">
                            <option value="${category.id}">${category.name}</option>
                        </c:forEach>
                    </select>
                </div>
                <div class="form-group">
                    <label>上传图片</label>
                    <input  type="file" name="imageId">
                </div>
                <div class="form-group">
                    <label>详细描述</label>
                    <textarea  class="form-control"name="description"></textarea>
                </div>
                <button type="submit" class="btn btn-default">提交</button>
            </form>
            <c:if test="${!empty(requestScope.message)}">
                <p>添加书本成功</p>
            </c:if>
        </div>

因为需要显示所有已经有的分类,
因而这里我进入添加分类jsp的jsp前应进入其servlet 然后跳转到相应的jsp
所以链接我们因该这么写

 <ul class="mainul">
        <div class="contents">
            <li class="maintile">分类管理</li>
            <ul>
                <li><a href = "/BackMain/AddCategory.jsp">添加分类</a></li>
                <li><a href = "/page?oper=showCategory">查看分类</a></li>
            </ul>
        </div>
        <div class="contents">
            <li class="maintile">图书管理</li>
            <ul class="contents">
                <li><a href="/page?oper=addCategoryUi">添加图书</a></li>
                <li><a href="/page?oper=showBooks">查看图书</a></li>
            </ul>
        </div>
        <div class="contents">
            <li class="maintile">订单管理</li>
            <ul>
                <li><a href = "/createorder?&oper=GetAllOrder">所有订单</a></li>
            </ul>
        </div>
    </ul>

前面的查看分类也是同理 必须要先到page servlet中拿到数据后请求转发到相应的servlet。否则直接进入的话数数据时空的。

  • 显示和删除jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: sz101
  Date: 2019/10/31
  Time: 21:121区
  To change this template use File | Settings | File Templates.
--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> 
<%--这里记得导入本地tomcat lib包 不然会报错--%>
<html>
<head>
    <title>后端管理界面</title>
    <link href="../bootstrap/bootstrap.min.css" rel="stylesheet" type="text/css"/>
    <link href="../css/mycss.css" rel="stylesheet" type="text/css"/>

</head>
<body>
<%@include file="Head.jsp"%>
<div class="container">
    <div class="col-md-3">
        <%@include file="Left.jsp"%>
    </div>
    <div class="col-md-9">
        <table class="showCategory table table-striped table-hover">
            <thead>
            <tr>
                <td>编号</td>
                <td>书名</td>
                <td>作者</td>
                <td>分类</td>
                <td>简介</td>
                <td>图片id</td>
                <td>价格</td>
                <td>操作</td>
            </tr>
            </thead>
            <tbody>
            <c:forEach items="${requestScope.BookList}" var = "book">
                <tr>
                    <td>${book.id}</td>
                    <td>${book.name}</td>
                    <td>${book.author}</td>
                    <td>${book.category_id}</td>
                    <td>${book.description}</td>
                    <td>${book.image_id}</td>
                    <td>${book.price}</td>
                    <td><a href = "#"onclick="Topage(this)">删除</a></td>
                </tr>
            </c:forEach>
            </tbody>
        </table>
    </div>
</div>
<script>
    //不用ajax
    // var myTable =document.getElementsByClassName("showCategory")[0];
    // for(var i = 0 ; i<myTable.rows.length;i++){
    //     var x = myTable.rows[i].cells[3];
    //     var index = x.parentElement.firstElementChild.innerHTML;
    //     x.firstChild.href = "/page?oper=deleteCategory&CategoryId="+index;
    //     console.log( x.firstChild);
    // }

    var myTable =document.getElementsByClassName("showCategory")[0];
    function Topage (obj) {
        console.log(obj.parentElement.parentElement)
        var flag  = window.confirm("你确定要删除吗");
        if(flag) {
            var ajax;
            var index = obj.parentElement.parentElement.firstElementChild.innerHTML;
            if (window.XMLHttpRequest) {
                ajax = new XMLHttpRequest();
            } else if (window.ActiveXObject) {
                ajax = new ActiveXObject("Msxml2.XMLHTTP");
            }
            //复写onreadystatechange函数
            ajax.onreadystatechange = function () {
                if (ajax.readyState == 4) {
                    // window.location.href = "/page?oper=showBooks";
                    var item = obj.parentElement.parentElement;
                    item.parentElement.removeChild(item);
                }
                if (ajax.status == 404) {
                }
            }
            ajax.open("get", "/page?oper=deleteBook&BookId=" + index);
            ajax.send(null);
        }
    }

</script>
</body>
</html>

至此 我们后端除了一个订单模块就基本完成了

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容