基于IDEA与MySQL的JavaWeb图书管理系统实战:从零到一构建完整项目(含源码解析)

基于IDEA与MySQL的JavaWeb图书管理系统实战:从零到一构建完整项目(含源码解析)

1. 项目概述与环境搭建

图书管理系统是JavaWeb开发的经典练手项目,它能帮助初学者快速掌握Web开发的核心流程。这个项目采用经典的MVC三层架构(DAO、Service、Servlet),结合MySQL数据库实现图书的增删改查、模糊查询和分页功能。我当年第一次做这个项目时,花了整整三天才跑通第一个页面,现在回想起来,很多坑其实可以避免。

开发环境准备

  • JDK 1.8+:推荐使用OpenJDK或Oracle JDK
  • IntelliJ IDEA:社区版就够用,记得安装JavaEE插件
  • MySQL 5.7+:8.0版本需要注意驱动兼容性
  • Tomcat 9.0:建议下载免安装版

安装MySQL时有个小技巧:初始化完成后,建议先用命令行创建数据库和用户,避免后续权限问题。我遇到过好几次因为权限配置不当导致连接失败的情况:

CREATE DATABASE book DEFAULT CHARACTER SET utf8mb4; CREATE USER 'bookadmin'@'%' IDENTIFIED BY 'yourpassword'; GRANT ALL PRIVILEGES ON book.* TO 'bookadmin'@'%';

2. 数据库设计与项目结构

数据库设计是项目的基石,我们采用简单的单表结构,包含图书ID、名称、ISBN和分类四个字段。实际项目中可能需要更多字段,但作为入门练习,这样已经足够:

CREATE TABLE `book` ( `BOOK_ID` int(50) NOT NULL AUTO_INCREMENT, `BOOK_NAME` varchar(100) NOT NULL, `ISBN` varchar(100), `CATEGORY` varchar(100), PRIMARY KEY (`BOOK_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

项目结构规划(标准Maven目录):

src ├── main │ ├── java │ │ ├── com.yourname.dao # 数据访问层 │ │ ├── com.yourname.pojo # 实体类 │ │ ├── com.yourname.service # 业务逻辑 │ │ ├── com.yourname.servlet # 控制器 │ │ └── com.yourname.util # 工具类 │ ├── resources # 配置文件 │ └── webapp │ ├── WEB-INF │ └── views # JSP页面

3. 核心代码实现详解

3.1 数据库连接工具类

DBUtil是项目的关键基础设施,我推荐使用Druid连接池替代原生JDBC,性能更好且自带监控功能。这是我在生产环境中验证过的配置方案:

public class DBUtil { private static DataSource dataSource; static { DruidDataSource druid = new DruidDataSource(); druid.setUrl("jdbc:mysql://localhost:3306/book"); druid.setUsername("bookadmin"); druid.setPassword("yourpassword"); druid.setInitialSize(5); druid.setMaxActive(20); dataSource = druid; } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }

3.2 DAO层实现

采用DAO模式可以很好地将数据库操作与业务逻辑分离。这里使用模板方法减少重复代码:

public class BookDaoImpl implements BookDao { private QueryRunner qr = new QueryRunner(DBUtil.getDataSource()); @Override public List<Book> selectAll() throws SQLException { String sql = "SELECT * FROM book"; return qr.query(sql, new BeanListHandler<>(Book.class)); } // 其他方法实现类似... }

3.3 Service层设计

Service层处理业务规则,比如添加图书前的数据校验:

public class BookServiceImpl implements BookService { private BookDao bookDao = new BookDaoImpl(); @Override public void add(Book book) throws SQLException { if(book.getBookName() == null || book.getBookName().trim().isEmpty()){ throw new IllegalArgumentException("图书名称不能为空"); } bookDao.add(book); } }

4. Web层与前端交互

4.1 Servlet控制器

使用一个集中式Servlet处理所有图书相关请求,通过参数m区分操作类型:

@WebServlet("/book") public class BookServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) { String action = request.getParameter("m"); switch(action) { case "add": addBook(request, response); break; // 其他case... } } private void addBook(HttpServletRequest request, HttpServletResponse response) { // 获取参数、调用Service、重定向... } }

4.2 JSP页面技巧

在booklist.jsp中使用JSTL简化代码,注意EL表达式和JSTL标签的配合:

<c:forEach items="${bookList}" var="book"> <tr> <td>${book.bookId}</td> <td>${fn:escapeXml(book.bookName)}</td> <td>${book.isbn}</td> <td> <a href="/book?m=edit&id=${book.bookId}">编辑</a> <a href="/book?m=delete&id=${book.bookId}" onclick="return confirm('确定删除吗?')">删除</a> </td> </tr> </c:forEach>

5. 项目优化与扩展

5.1 分页功能增强

原始的分页实现比较简单,我们可以改进PageBean类,增加总页数计算和页面导航:

public class PageBean<T> { private int currentPage; // 当前页 private int pageSize; // 每页记录数 private int totalRecords; // 总记录数 private List<T> data; // 当前页数据 public int getTotalPages() { return (totalRecords + pageSize - 1) / pageSize; } // 生成页面导航HTML public String getPageNav(String url) { StringBuilder sb = new StringBuilder(); for(int i=1; i<=getTotalPages(); i++) { sb.append("<a href='").append(url) .append("&page=").append(i).append("'>") .append(i).append("</a> "); } return sb.toString(); } }

5.2 异常处理机制

添加全局异常处理器,避免直接向用户暴露堆栈信息:

@WebServlet("/errorHandler") public class ErrorHandler extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) { Throwable throwable = (Throwable) req.getAttribute("javax.servlet.error.exception"); String errorMsg = "系统繁忙,请稍后再试"; if(throwable instanceof SQLException) { errorMsg = "数据库操作失败"; } req.setAttribute("errorMsg", errorMsg); req.getRequestDispatcher("/error.jsp").forward(req, resp); } }

在web.xml中配置:

<error-page> <exception-type>java.lang.Exception</exception-type> <location>/errorHandler</location> </error-page>

6. 项目部署与调试

6.1 Tomcat配置要点

在IDEA中配置Tomcat时,有几点需要特别注意:

  1. Deployment选项卡要添加Artifact为war exploded
  2. Application context建议设置为"/"
  3. 在VM Options中添加:-Dfile.encoding=UTF-8

6.2 常见问题解决

中文乱码问题:确保三处编码一致

  1. JSP页面头部:<%@ page contentType="text/html;charset=UTF-8" %>
  2. 过滤器设置:request.setCharacterEncoding("UTF-8")
  3. MySQL连接字符串:jdbc:mysql://...?useUnicode=true&characterEncoding=UTF-8

数据库连接失败:检查四要素

  1. URL格式是否正确(端口号、数据库名)
  2. 用户名密码是否匹配
  3. MySQL服务是否启动
  4. 防火墙是否放行3306端口

7. 源码解析与学习建议

项目完整源码已经打包,包含详细的注释。建议学习时:

  1. 先运行体验完整功能
  2. 从DAO层开始逐层理解
  3. 尝试添加新功能如按分类查询
  4. 研究分页实现的SQL原理

对于想深入学习的同学,可以尝试以下扩展:

  • 添加用户登录功能(Session管理)
  • 实现图书封面图片上传
  • 引入Redis缓存热门图书
  • 改用MyBatis替代原生JDBC

这个项目虽然基础,但涵盖了JavaWeb开发的全部核心概念。我在带新人时发现,能把这样一个项目吃透的开发者,后续学习Spring等框架会轻松很多。遇到问题不要怕,多调试、多查文档,每个错误都是进步的机会。