书籍管理系统
项目描述
实现对数据库中的书籍进行增、删、改、查操作。其中涉及到MVC,jsp,servlet等。
项目代码
项目中是在web下开发,所使用的IDE为eclipse,Tomcat和jdk版本均为8.0
1.由于要连接数据库,所以新建工具类包即基本数据库连接类,切记导入数据库驱动连接包并放置在工程目录WebContent/WEB-INF/lib下。
温馨提示:类编写完成后可以进行本地数据库连接测试,确保数据库连接成功。
package cn.mxf.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//数据库连接类
public class BaseDao {
//声明Connection连接类
private Connection conn;
//创建PreparedStatement对象,用来执行SQL语句
private PreparedStatement ps;
//用来存放数据的结果集
private ResultSet rs;
// 连接数据库
public void getConnection() {
// 加载驱动程序
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/booksys?characterEncoding=utf-8";
//通过getConnection方法连接数据库
conn = DriverManager.getConnection(url, "root", "");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 关闭数据库 从后往前依次关闭
public void close() {
try {
if (ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
// 实现对数据的更新--增加,删除,修改操作;其中Object...为可变参数
public int executeUpdate(String sql, Object... objects) {
try {
this.getConnection();
ps = conn.prepareStatement(sql);
if (objects != null) {
for (int i = 0; i < objects.length; i++) {
ps.setObject(i + 1, objects[i]);
}
return ps.executeUpdate();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
this.close();
}
return -1;
}
// 实现对数据的查询操作
public ResultSet executeQuery(String sql, Object... objects) {
try {
this.getConnection();
ps = conn.prepareStatement(sql);
if (objects != null) {
for (int i = 0; i < objects.length; i++) {
ps.setObject(i + 1, objects[i]);
}
return rs = ps.executeQuery();
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
2.由于我们需要做的是对书籍的增删改查等操作,所以新建书籍实体类包里面包含数据实体类和书籍分类类;同时在mysql数据库中新建book(书籍信息)和category(书籍分类)表。
注意:其中book表的id设置为自动递增
书籍类
package cn.mxf.entity;
import java.util.Date;
//书籍类
public class Book {
// 对所有的属性生成get和set方法
private int id;// 书籍编号
private String name;// 书籍名称
private double price;// 价格
private String author;// 作者
private Date pubDate;// 出版日期
private int categoryId;// 书籍分类
// 无参构造方法
public Book() {
}
// 不带id的有参构造方法
public Book(String name, double price, String author, Date pubDate, int categoryId) {
super();
this.name = name;
this.price = price;
this.author = author;
this.pubDate = pubDate;
this.categoryId = categoryId;
}
// 带id的有参构造方法
public Book(int id, String name, double price, String author, Date pubDate, int categoryId) {
super();
this.id = id;
this.name = name;
this.price = price;
this.author = author;
this.pubDate = pubDate;
this.categoryId = categoryId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getPubDate() {
return pubDate;
}
public void setPubDate(Date pubDate) {
this.pubDate = pubDate;
}
public int getCategoryId() {
return categoryId;
}
public void setCategoryId(int categoryId) {
this.categoryId = categoryId;
}
}
书籍分类类
package cn.mxf.entity;
public class Category {
// 书籍分类编号
private int id;
// 书籍对应分类名
private String name;
// 生成带参构造方法
public Category(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Category(String name) {
super();
this.name = name;
}
// 生成无参构造方法
public Category() {
}
// 并对属性进行设置set和get方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.接着实现基于BaseDao的书籍数据库连接类和书籍分类数据库连接类。
书籍数据库连接类
package cn.mxf.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import cn.mxf.entity.Book;
import cn.mxf.utils.BaseDao;
//本类为继承于BaseDao
public class BookDao extends BaseDao {
// 实现查询所有书籍的功能
public List<Book> getAll() {
List<Book> list = new ArrayList<Book>();
// 查询的SQL语句
String sql = "select * from book";
// 调用查询数据的方法对书籍进行查询操作
ResultSet rs = this.executeQuery(sql);
try {
// 将查询的结果存放于List<Book>中
while (rs.next()) {
list.add(new Book(rs.getInt(1), rs.getString(2), rs.getDouble(3), rs.getString(4), rs.getDate(5),
rs.getInt(6)));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 最后别忘记关闭
this.close();
}
return list;
}
// 实现增加书籍的功能
public int addBook(Book book) {
String sql = "insert into book(name,price,author,pubDate,categoryId) values(?,?,?,?,?)";
return this.executeUpdate(sql, book.getName(), book.getPrice(), book.getAuthor(),
new SimpleDateFormat("yyyy-MM-dd").format(book.getPubDate()), book.getCategoryId());
}
// 实现通过ID找到对应书籍的功能--在此之后才能进行修改操作
public Book selectBookById(int id) {
// 通过id值查询对应书籍的SQL语句
String sql = "select * from book where id=" + id;
// 执行查询操作
ResultSet rs = this.executeQuery(sql);
try {
if (rs.next()) {
return new Book(rs.getInt(1), rs.getString(2), rs.getDouble(3), rs.getString(4), rs.getDate(5),
rs.getInt(6));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 最后别忘记关闭
this.close();
}
return null;
}
// 实现修改书籍的功能--在此之前需要找到要修改的书籍信息
public int modifyBook(Book book) {
// 更新书籍信息的SQL语句
String sql = "update book set name=?,price=?,author=?,pubDate=?,categoryId=? where id=?";
return this.executeUpdate(sql, book.getName(), book.getPrice(), book.getAuthor(),
new SimpleDateFormat("yyyy-MM-dd").format(book.getPubDate()), book.getCategoryId(), book.getId());
}
// 实现删除书籍的功能--直接通过id找到对应书籍然后删除
public int deleteBook(int id) {
// 删除书籍的SQL语句
String sql = "delete from book where id=?";
return this.executeUpdate(sql, id);
}
}
书籍分类数据库连接类
package cn.mxf.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import cn.mxf.entity.Category;
import cn.mxf.utils.BaseDao;
//本类为继承于BaseDao
public class CategoryDao extends BaseDao {
// 实现查询所有书籍分类的功能
public List<Category> getAll() {
List<Category> list = new ArrayList<Category>();
// 查询所有分类的SQL语句
String sql = "select * from category";
// 根据SQL语句执行查询操作
ResultSet rs = this.executeQuery(sql);
try {
while (rs.next()) {
// 将查询的结果存放于List<Category>中
list.add(new Category(rs.getInt(1), rs.getString(2)));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 最后别忘记关闭连接
this.close();
}
return list.size() > 0 ? list : null;
}
}
4.准备工作完成后,现在才是真正的开始:新建BookServlet类(所有的操作在这里完成),在其中完成对书籍的增删改查操作。
package cn.mxf.servlet;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
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 cn.mxf.dao.BookDao;
import cn.mxf.dao.CategoryDao;
import cn.mxf.entity.Book;
import cn.mxf.entity.Category;
// 通过注解的方式配置Servlet
@WebServlet("/book")
public class BookServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 获取BookDao对象
private BookDao bookDao = new BookDao();
// 获取CategoryDao对象
private CategoryDao categoryDao = new CategoryDao();
public BookServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 解决乱码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
/**
* 获取操作的参数,确定好下一步该做什么
* op = list :查询所有的书籍信息
* op = toAdd :跳转到添加书籍的页面
* op = add :添加书籍
* op = delete :删除书籍
* op = getById :根据id值找到需要更改的书籍信息
* op = modify :修改书籍信息
*/
// 根据传入的op判断执行那一个操作
String op = request.getParameter("op");
if (op == null || "list".equals(op)) {
// 封装为方法
list(request, response);
} else if ("toadd".equals(op)) {
toadd(request, response);
} else if ("add".equals(op)) {
add(request, response);
} else if ("getById".equals(op)) {
getById(request, response);
} else if ("modify".equals(op)) {
modify(request, response);
} else if ("delete".equals(op)) {
delete(request, response);
}
}
private void list(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取所有书籍
List<Book> list = bookDao.getAll();
// 获取所有书籍分类
List<Category> clist = categoryDao.getAll();
// 用来在同一个request周期中保存list变量使用
request.setAttribute("list", list);
// 用来在同一个request周期中保存clist变量使用
request.setAttribute("clist", clist);
// response.sendRedirect()方法是通过浏览器对象重定向的,在两个不同的页面间传值会生成两个不同的request对象。
// 由于是在不同页面间传值,所以有使用RequestDispatcher接口的forward()方法。
request.getRequestDispatcher("list.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
5.在WebContent目录下新建list.jsp用来获取书籍列表并进行显示。
<!--
显示数据库中所有书籍的JSP页面 ,其中涉及到了JSTL,EL表达式;
所以需要自己导入jstl.jar和standard.jar包到WebContent/WEB-INF/lib下;
-->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- eclipse下使用JSTL需要导入java.sun.com/jsp/jstl/core,才能使用JSTL表达式 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>书籍信息页面</title>
</head>
<body>
<h1>书籍信息列表</h1>
<hr>
<table width="80%" align="center">
<tr>
<td>编号</td>
<td>名称</td>
<td>分类</td>
<td>价格</td>
<td>作者</td>
<td>出版日期</td>
<td>操作</td>
</tr>
<!-- 通过EL表达式获取传递过来的list,并且通过JSTL中的循环获取对应的属性值 -->
<c:forEach items="${list }" var="bean" varStatus="status">
<!--
1.隔行变色
2.分别取得对应的书籍属性值并且显示出来
3.当书籍中的分类编号和分类表中的编号相同时,显示分类表中的分类名
-->
<tr <c:if test="${status.index%2==0 }">style="background:#0f0"</c:if>>
<td>${bean.id }</td>
<td>${bean.name }</td>
<td><c:forEach items="${clist }" var="category">
<c:if test="${category.id == bean.categoryId }">
${category.name }
</c:if>
</c:forEach></td>
<td>${bean.price }</td>
<td>${bean.author }</td>
<td>${bean.pubDate }</td>
<!--
1.这里以浏览器的URL方式直接将书籍的对应id传递过去,可以对书籍进行查询操作和删除操作
-->
<td><a href="book?op=getById&id=${bean.id }">修改</a> <a
href="book?op=delete&id=${bean.id }">删除</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
到这里的话你就可以执行你的代码来查询所有书籍了
6.然后就是给数据库中进行添加书籍的操作了。
private void add(HttpServletRequest request, HttpServletResponse response) throws IOException {
String bookName = request.getParameter("name");// 书名
double price = Double.parseDouble(request.getParameter("price"));// 价格
String author = request.getParameter("author");// 作者
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date pubDate = null;// 出版日期
try {
pubDate = sdf.parse(request.getParameter("pubDate"));
} catch (ParseException e) {
e.printStackTrace();
}
int categoryId = Integer.parseInt(request.getParameter("categoryId"));// 书籍分类
// 根据获取到的书籍属性新创建一个书籍对象并调用BookDao中的addBook方法进行书籍的添加
Book b = new Book(bookName, price, author, pubDate, categoryId);
if (bookDao.addBook(b) > 0) {
response.sendRedirect("book?op=list");
} else {
response.getWriter().print("添加失败!!");
}
}
private void toadd(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取所有的书籍分类名称
List<Category> clist = categoryDao.getAll();
request.setAttribute("clist", clist);
request.getRequestDispatcher("add.jsp").forward(request, response);
}
7.在WebContent目录下新建add.jsp用来获取书籍列表并进行显示。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>添加书籍</title>
</head>
<body>
<h1>添加书籍</h1>
<hr>
<!-- 这里需要注意:提交的时候需要交给当op=add时BookServlet中的add方法执行 -->
<form action="book?op=add" method="post">
<table width="60%" align="center">
<tr>
<td>书名:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>分类:</td>
<!-- 添加书籍的时候需要将书籍分类通过下拉框的形式显示出来 -->
<td><select name="categoryId">
<c:forEach items="${clist }" var="bean">
<option value="${bean.id }">${bean.name }</option>
</c:forEach>
</select></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="text" name="price"></td>
</tr>
<tr>
<td>作者:</td>
<td><input type="text" name="author"></td>
</tr>
<tr>
<td>出版日期:</td>
<td><input type="text" name="pubDate"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交">
</td>
</tr>
</table>
</form>
</body>
</html>
到这里的话你就可以执行你的代码来查询所有书籍和添加书籍了
8.接着就是修改获取到的书籍信息的操作了。
private void modify(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// 获取id
int id = 0;
if (request.getParameter("id") != null) {
id = Integer.parseInt(request.getParameter("id"));
}
String name = request.getParameter("name");// 书名
double price = Double.parseDouble(request.getParameter("price"));// 价格
String author = request.getParameter("author");// 作者
Date pubDate = null;// 出版日期
try {
pubDate = new SimpleDateFormat("yyyy-MM-dd").parse(request.getParameter("pubDate"));
} catch (ParseException e) {
e.printStackTrace();
}
int categoryId = Integer.parseInt(request.getParameter("categoryId"));// 书籍分类
// 根据获取到的书籍属性新创建一个书籍对象并调用BookDao中的modifyBook方法进行书籍的更新
Book b = new Book(id, name, price, author, pubDate, categoryId);
if (bookDao.modifyBook(b) > 0) {
response.sendRedirect("book?op=list");
} else {
response.getWriter().print("修改失败!!");
}
}
private void getById(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取id
int id = 0;
if (request.getParameter("id") != null) {
id = Integer.parseInt(request.getParameter("id"));
}
// 根据id查询对应记录
Book book = bookDao.selectBookById(id);
List<Category> clist = categoryDao.getAll();
request.setAttribute("clist", clist);
request.setAttribute("book", book);
request.getRequestDispatcher("modify.jsp").forward(request, response);
}
9.在WebContent目录下新建modify.jsp用来更新书籍并进行显示。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>修改书籍</title>
</head>
<body>
<h1>修改书籍</h1>
<hr>
<form action="book?op=modify" method="post">
<table width="60%" align="center">
<tr>
<!-- 这里需要将id传递过去 -->
<td>书名: <input type="hidden" name="id" value="${book.id }" />
</td>
<td><input type="text" name="name" value="${book.name}" /></td>
</tr>
<tr>
<td>分类:</td>
<!-- 修改书籍的时候需要将书籍分类通过下拉框的形式显示出来 -->
<td><select name="categoryId">
<c:forEach items="${clist }" var="bean">
<option value="${bean.id }"
<c:if test="${bean.id == book.categoryId }">selected</c:if>>${bean.name }</option>
</c:forEach>
</select></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="text" name="price" value="${book.price}" />
</td>
</tr>
<tr>
<td>作者:</td>
<td><input type="text" name="author" value="${book.author}" />
</td>
</tr>
<tr>
<td>出版日期:</td>
<td><input type="text" name="pubDate" value="${book.pubDate}" />
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交">
</td>
</tr>
</table>
</form>
</body>
</html>
到这里的话你就可以执行你的代码来查询所有书籍、添加书籍和修改书籍了
10.剩下的就只有删除了,其实删除是这里面最简单的了,只需要获取到id值之后就可以进行删除操作。
private void delete(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 获取id
int id = 0;
if (request.getParameter("id") != null) {
id = Integer.parseInt(request.getParameter("id"));
}
// 根据获取到的书籍id调用BookDao中的deleteBook(id)方法进行书籍的删除
if (bookDao.deleteBook(id) > 0) {
response.sendRedirect("book?op=list");
}
}
总结:
- 通过这几天的学习也对之前的JDBC进行了复习与回顾;
- 新使用的MVC(Model View Control)模式使得界面与逻辑处理分离开来,很大程度上使得我们的修改变得简单;
- 通过EL、JSTL表达式的方式大大简化了编程代码的冗余。
- 最后附上整个项目的源代码