成果图
搭建环境
intellij idea
包结构
-
后台主要为Dao、Service、Pojo、Servlet
-
前台分为后端的jsp和前端的jsp
导入的工具类以及方法
后台管理界面
主要分为
添加删除书类
显示书类
添加删除书籍
显示书籍
显示所有订单
共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>
<% }%>
效果图
查看分类
- 编写查看分类的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>
至此 我们后端除了一个订单模块就基本完成了