1. 项目概述与环境搭建图书管理系统是JavaWeb开发的经典练手项目它能帮助初学者快速掌握Web开发的核心流程。这个项目采用经典的MVC三层架构DAO、Service、Servlet结合MySQL数据库实现图书的增删改查、模糊查询和分页功能。我当年第一次做这个项目时花了整整三天才跑通第一个页面现在回想起来很多坑其实可以避免。开发环境准备JDK 1.8推荐使用OpenJDK或Oracle JDKIntelliJ IDEA社区版就够用记得安装JavaEE插件MySQL 5.78.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) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;项目结构规划标准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 ListBook 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} varbook tr td${book.bookId}/td td${fn:escapeXml(book.bookName)}/td td${book.isbn}/td td a href/book?meditid${book.bookId}编辑/a a href/book?mdeleteid${book.bookId} onclickreturn confirm(确定删除吗)删除/a /td /tr /c:forEach5. 项目优化与扩展5.1 分页功能增强原始的分页实现比较简单我们可以改进PageBean类增加总页数计算和页面导航public class PageBeanT { private int currentPage; // 当前页 private int pageSize; // 每页记录数 private int totalRecords; // 总记录数 private ListT data; // 当前页数据 public int getTotalPages() { return (totalRecords pageSize - 1) / pageSize; } // 生成页面导航HTML public String getPageNav(String url) { StringBuilder sb new StringBuilder(); for(int i1; igetTotalPages(); 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-typejava.lang.Exception/exception-type location/errorHandler/location /error-page6. 项目部署与调试6.1 Tomcat配置要点在IDEA中配置Tomcat时有几点需要特别注意Deployment选项卡要添加Artifact为war explodedApplication context建议设置为/在VM Options中添加-Dfile.encodingUTF-86.2 常见问题解决中文乱码问题确保三处编码一致JSP页面头部% page contentTypetext/html;charsetUTF-8 %过滤器设置request.setCharacterEncoding(UTF-8)MySQL连接字符串jdbc:mysql://...?useUnicodetruecharacterEncodingUTF-8数据库连接失败检查四要素URL格式是否正确端口号、数据库名用户名密码是否匹配MySQL服务是否启动防火墙是否放行3306端口7. 源码解析与学习建议项目完整源码已经打包包含详细的注释。建议学习时先运行体验完整功能从DAO层开始逐层理解尝试添加新功能如按分类查询研究分页实现的SQL原理对于想深入学习的同学可以尝试以下扩展添加用户登录功能Session管理实现图书封面图片上传引入Redis缓存热门图书改用MyBatis替代原生JDBC这个项目虽然基础但涵盖了JavaWeb开发的全部核心概念。我在带新人时发现能把这样一个项目吃透的开发者后续学习Spring等框架会轻松很多。遇到问题不要怕多调试、多查文档每个错误都是进步的机会。
基于IDEA与MySQL的JavaWeb图书管理系统实战:从零到一构建完整项目(含源码解析)
1. 项目概述与环境搭建图书管理系统是JavaWeb开发的经典练手项目它能帮助初学者快速掌握Web开发的核心流程。这个项目采用经典的MVC三层架构DAO、Service、Servlet结合MySQL数据库实现图书的增删改查、模糊查询和分页功能。我当年第一次做这个项目时花了整整三天才跑通第一个页面现在回想起来很多坑其实可以避免。开发环境准备JDK 1.8推荐使用OpenJDK或Oracle JDKIntelliJ IDEA社区版就够用记得安装JavaEE插件MySQL 5.78.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) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;项目结构规划标准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 ListBook 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} varbook tr td${book.bookId}/td td${fn:escapeXml(book.bookName)}/td td${book.isbn}/td td a href/book?meditid${book.bookId}编辑/a a href/book?mdeleteid${book.bookId} onclickreturn confirm(确定删除吗)删除/a /td /tr /c:forEach5. 项目优化与扩展5.1 分页功能增强原始的分页实现比较简单我们可以改进PageBean类增加总页数计算和页面导航public class PageBeanT { private int currentPage; // 当前页 private int pageSize; // 每页记录数 private int totalRecords; // 总记录数 private ListT data; // 当前页数据 public int getTotalPages() { return (totalRecords pageSize - 1) / pageSize; } // 生成页面导航HTML public String getPageNav(String url) { StringBuilder sb new StringBuilder(); for(int i1; igetTotalPages(); 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-typejava.lang.Exception/exception-type location/errorHandler/location /error-page6. 项目部署与调试6.1 Tomcat配置要点在IDEA中配置Tomcat时有几点需要特别注意Deployment选项卡要添加Artifact为war explodedApplication context建议设置为/在VM Options中添加-Dfile.encodingUTF-86.2 常见问题解决中文乱码问题确保三处编码一致JSP页面头部% page contentTypetext/html;charsetUTF-8 %过滤器设置request.setCharacterEncoding(UTF-8)MySQL连接字符串jdbc:mysql://...?useUnicodetruecharacterEncodingUTF-8数据库连接失败检查四要素URL格式是否正确端口号、数据库名用户名密码是否匹配MySQL服务是否启动防火墙是否放行3306端口7. 源码解析与学习建议项目完整源码已经打包包含详细的注释。建议学习时先运行体验完整功能从DAO层开始逐层理解尝试添加新功能如按分类查询研究分页实现的SQL原理对于想深入学习的同学可以尝试以下扩展添加用户登录功能Session管理实现图书封面图片上传引入Redis缓存热门图书改用MyBatis替代原生JDBC这个项目虽然基础但涵盖了JavaWeb开发的全部核心概念。我在带新人时发现能把这样一个项目吃透的开发者后续学习Spring等框架会轻松很多。遇到问题不要怕多调试、多查文档每个错误都是进步的机会。