当前位置: 首页 > news >正文

使用SpringBoot + Thymeleaf + MyBatisPlus实现一个简单的书籍管理系统-demo2

一 准备环境

1 数据库环境搭建

CREATE DATABASE IF NOT EXISTS db_book;
USE db_book;CREATE TABLE book (id INT PRIMARY KEY AUTO_INCREMENT COMMENT '书籍唯一标识',name VARCHAR(255) NOT NULL COMMENT '书籍名称',author VARCHAR(100) NOT NULL COMMENT '作者',press VARCHAR(100) NOT NULL COMMENT '出版社',status VARCHAR(20) NOT NULL COMMENT '书籍状态(例如:在库、借出、已预订等)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='书籍信息表';

2 Java环境搭建

3 Maven环境搭建

二 实验过程

1 实验目的

  1. 掌握 MyBatis-Plus 的基本配置与使用方法
  2. 理解并实践基于 MyBatis-Plus 的 CRUD 操作
  3. 学会使用 MyBatis-Plus 的条件构造器进行复杂查询
  4. 掌握分页查询的实现方式
  5. 理解实体类与数据库表的映射关系
  6. 培养基于 SpringBoot+MyBatis-Plus 进行实际项目开发的能力

2 实验要求

  1. 创建一个图书管理系统,实现图书信息的增删改查功能
  2. 使用 MyBatis-Plus 简化数据访问层代码
  3. 实现按图书名称、作者、类别等条件进行查询
  4. 实现图书信息的分页展示
  5. 对图书信息进行必要的验证(如非空验证)
  6. 代码结构清晰,符合 SpringBoot 开发规范
  7. 编写必要的测试用例验证功能正确性

3 实验过程

image-20251021175822158

1. 创建 Maven 项目

使用 IDEA 创建名为E3-BookManagementSystem的Maven项目,pom.xml依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.yqd</groupId><artifactId>E3-BookManagementSystem</artifactId><version>0.0.1-SNAPSHOT</version><name>E3-BookManagementSystem</name><description>E3-BookManagementSystem</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.37</version><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
2. 配置文件(application.properties)

src/main/resources下创建配置文件:

spring:application:name: E3-BookManagementSystemdatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_book?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghaiusername: root  # 替换为你的数据库用户名password: 123456  # 替换为你的数据库密码# MyBatisPlus配置
mybatis-plus:mapper-locations: classpath:mapper/*.xml  # mapper.xml存放路径
type-aliases-package: com.yqd.entity  # 实体类包路径
configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 打印SQL日志(可选)server:port: 8081
3 启动类
package com.yqd;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.yqd.mapper") // 扫描Mapper接口所在包
public class E3BookManagementSystemApplication {public static void main(String[] args) {SpringApplication.run(E3BookManagementSystemApplication.class, args);}}
4. 实体类(Book.java)
package com.yqd.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {private Integer id;private String name;private String author;private String press;private String status;
}
5. Mapper 接口
package com.yqd.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yqd.entity.Book;
import org.apache.ibatis.annotations.Mapper;@Mapper  // 标记为MyBatis的Mapper接口
public interface BookMapper extends BaseMapper<Book> {// 无需手动编写CRUD方法,BaseMapper已提供
}
6. 服务层接口(BookService.java)
package com.yqd.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.yqd.entity.Book;import java.util.List;public interface BookService extends IService<Book> {// 继承IService,获得更多增强CRUD方法// 在BookService接口中添加List<Book> findByStatus(String status);
}
7. 服务层实现(BookServiceImpl.java)
package com.yqd.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yqd.entity.Book;
import com.yqd.mapper.BookMapper;
import com.yqd.service.BookService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import java.util.List;@Service  // 标记为服务层组件
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {@Overridepublic List<Book> findByStatus(String status) {// 使用QueryWrapper构建条件QueryWrapper<Book> queryWrapper = new QueryWrapper<>();queryWrapper.eq("status", status);  // 等价于 WHERE status = ?return baseMapper.selectList(queryWrapper);}
}
8. 控制器(BookController.java)

实现增删改查接口:

package com.yqd.controller;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yqd.entity.Book;
import com.yqd.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;import java.util.HashMap;
import java.util.List;
import java.util.Map;@Controller
@RequestMapping("/books")
public class BookController {@Autowiredprivate BookService bookService;// 1. 查询所有书籍(列表页)@GetMappingpublic String list(Model model) {// MyBatis-Plus的list()方法等价于JPA的findAll()List<Book> books = bookService.list();model.addAttribute("books", books);return "book/list";}// 2. 跳转新增/编辑页@GetMapping("/form")public String form(@RequestParam(required = false) Integer id, Model model) {if (id != null) {// MyBatis-Plus的getById()等价于JPA的findById()Book book = bookService.getById(id);model.addAttribute("book", book != null ? book : new Book());} else {model.addAttribute("book", new Book());}return "book/form";}// 3. 保存书籍(新增/更新)@PostMapping("/save")public String save(Book book) {// MyBatis-Plus的saveOrUpdate()方法自动判断新增/更新(根据ID是否为空)bookService.saveOrUpdate(book);return "redirect:/books";}// 4. 异步删除书籍@DeleteMapping("/{id}")@ResponseBodypublic Map<String, Object> delete(@PathVariable Integer id) {Map<String, Object> result = new HashMap<>();try {// MyBatis-Plus的removeById()等价于JPA的deleteById()boolean success = bookService.removeById(id);result.put("success", success);result.put("msg", success ? "删除成功" : "删除失败:书籍不存在");} catch (Exception e) {result.put("success", false);result.put("msg", "删除失败:" + e.getMessage());}return result;}// 5. 异步查询单本书籍@GetMapping("/{id}")@ResponseBodypublic Book getBookById(@PathVariable Integer id) {return bookService.getById(id);}// 6. 分页查询示例(在Controller中)@GetMapping("/page")@ResponseBodypublic IPage<Book> getPage(@RequestParam(defaultValue = "1") Integer pageNum,@RequestParam(defaultValue = "10") Integer pageSize) {Page<Book> page = new Page<>(pageNum, pageSize);return bookService.page(page); // 返回分页结果(包含总条数、当前页数据等)}
}
9. 前端页面实现(Thymeleaf + jQuery)
9.1 页面目录结构

src/main/resources/templates下创建:

templates/
├── index.html         // 首页
└── book/├── list.html      // 书籍列表页└── form.html      // 新增/编辑页
9.2 首页(index.html)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>首页</title>
</head>
<body>
<h1 style="text-align: center; margin-top: 100px;"><a href="/books">进入书籍管理系统</a>
</h1>
</body>
</html>
9.3 书籍列表页(list.html)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>书籍列表</title><script th:src="@{js/jquery.min.js}"></script><style>table { width: 80%; margin: 20px auto; border-collapse: collapse; }th, td { border: 1px solid #ccc; padding: 10px; text-align: center; }.btn { padding: 5px 10px; margin: 0 5px; cursor: pointer; }.add-btn { margin: 20px 0 0 10%; }/* 新增消息样式 */.msg {padding: 10px;margin: 10px 0;border-radius: 4px;text-align: center;}.success-msg { background: #d5f5e3; color: #27ae60; }.error-msg { background: #fadbd8; color: #e74c3c; }</style>
</head>
<body>
<h1 style="text-align: center;">书籍管理系统</h1>
<!-- 在list.html的.container内添加以下代码(h1标签下方) -->
<div th:if="${not #strings.isEmpty(successMsg)}" class="msg success-msg" th:text="${successMsg}"></div>
<div th:if="${not #strings.isEmpty(errorMsg)}" class="msg error-msg" th:text="${errorMsg}"></div>
<button class="btn add-btn" onclick="window.location.href='/books/form'">新增书籍</button><table><tr><th>ID</th><th>书名</th><th>作者</th><th>出版社</th><th>状态</th><th>操作</th></tr><tr th:each="book : ${books}"><td th:text="${book.id}"></td><td th:text="${book.name}"></td><td th:text="${book.author}"></td><td th:text="${book.press}"></td><td th:text="${book.status}"></td><td><button class="btn edit-btn" th:data-id="${book.id}">编辑</button><button class="btn delete-btn" th:data-id="${book.id}">删除</button></td></tr>
</table><script>$(function() {// 编辑按钮点击事件$('.edit-btn').click(function() {const id = $(this).data('id');window.location.href = `/books/form?id=${id}`; // 跳转到编辑页});// 删除按钮点击事件$('.delete-btn').click(function() {const id = $(this).data('id');if (confirm(`确定删除ID为${id}的书籍吗?`)) {deleteBook(id, $(this).closest('tr'));}});});// 异步删除书籍function deleteBook(id, $tr) {$.ajax({url: `/books/${id}`,type: 'DELETE',success: function(res) {if (res.success) {alert(res.msg);$tr.remove(); // 移除当前行} else {alert(res.msg);}},error: function() {alert('删除失败,请重试');}});}<!-- 消息自动消失脚本 -->$(function() {// 3秒后自动隐藏提示消息setTimeout(() => {$('.msg').fadeOut(1000);}, 3000);});
</script>
</body>
</html>
9.4 新增 / 编辑页(form.html)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title th:text="${book.id != null ? '编辑书籍' : '新增书籍'}"></title><script th:src="@{js/jquery.min.js}"></script><style>.container { width: 500px; margin: 50px auto; }h2 { text-align: center; margin-bottom: 30px; }.form-group { margin: 15px 0; }label { display: inline-block; width: 100px; text-align: right; margin-right: 10px; }input, select { width: 300px; padding: 8px; border: 1px solid #ddd; border-radius: 4px; }.msg {padding: 10px;margin: 10px 0;border-radius: 4px;text-align: center;}.success-msg { background: #d5f5e3; color: #27ae60; } /* 成功提示 */.error-msg { background: #fadbd8; color: #e74c3c; }   /* 错误提示 */.btn-group { margin-top: 20px; margin-left: 110px; }.btn { padding: 8px 20px; border: none; border-radius: 4px; cursor: pointer; }.save-btn { background: #3498db; color: white; margin-right: 10px; }.cancel-btn { background: #95a5a6; color: white; }.save-btn:disabled { background: #95a5a6; cursor: not-allowed; }</style>
</head>
<body>
<div class="container"><h2 th:text="${book.id != null ? '编辑书籍' : '新增书籍'}"></h2><form id="bookForm" th:action="@{/books/save}" method="post"><!-- 隐藏域:用于传递ID(编辑时需要) --><input type="hidden" name="id" th:value="${book.id}"><div class="form-group"><label for="name">书名:</label><input type="text" id="name" name="name" th:value="${book.name}" required></div><div class="form-group"><label for="author">作者:</label><input type="text" id="author" name="author" th:value="${book.author}" required></div><div class="form-group"><label for="press">出版社:</label><input type="text" id="press" name="press" th:value="${book.press}" required></div><div class="form-group"><label for="status">状态:</label><select id="status" name="status" required><option value="在库" th:selected="${book.status == '在库'}">在库</option><option value="借出" th:selected="${book.status == '借出'}">借出</option><option value="已预订" th:selected="${book.status == '已预订'}">已预订</option></select></div><div class="form-group"><button type="submit" class="btn save-btn" id="saveBtn">保存</button><button type="button" class="btn" onclick="window.location.href='/books'">取消</button></div></form>
</div>
<script>// 防止重复提交:点击保存后禁用按钮$(function() {$('#bookForm').submit(function() {$('#saveBtn').prop('disabled', true).text('保存中...');return true; // 允许表单提交});// 3秒后自动隐藏提示消息setTimeout(() => {$('.msg').fadeOut(1000);}, 3000);});
</script>
</body>
</html>

4 运行与测试

1. 启动项目

运行E3BookManagementSystemApplication.javamain方法,控制台显示如下信息表示启动成功:

o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8081 (http) with context path ''
2. 访问系统

打开浏览器,输入http://localhost:8081,点击 "进入书籍管理系统" 进入书籍列表页。

3. 功能测试
(1)新增书籍
  • 点击 "新增书籍" 按钮,填写表单(如书名 "Java 编程"、作者 "张三"、出版社 "编程出版社"、状态 "在库")。
  • 点击 "保存",页面跳转至列表页,显示 "新增成功",列表中出现新增的书籍。
(2)编辑书籍
  • 点击某条书籍的 "编辑" 按钮,修改表单内容(如修改状态为 "借出")。
  • 点击 "保存",页面跳转至列表页,显示 "更新成功",列表中数据已更新。
(3)删除书籍
  • 点击某条书籍的 "删除" 按钮,确认后弹出 "删除成功" 提示,列表中该书籍消失。
http://www.hskmm.com/?act=detail&tid=35965

相关文章:

  • 2025年深圳离婚律所电话推荐:家理福田诺德中心婚姻家事专线
  • 2025年超声波清洗机厂家电话推荐:广东洁泰超声设备有限公司
  • CentOS7源码安装erlang26没有默认安装JIT模块
  • 2025年超声波清洗机厂家电话推荐:广东洁泰设备技术沉淀深
  • 2025年AI优化公司电话推荐:十家可验证团队直连方式汇总
  • 2025年润滑油厂家权威推荐榜:工业润滑油,汽车润滑油,发动机润滑油,甲醇发动机润滑油,全合成润滑油,长效发动机润滑油品牌深度解析
  • 软件工程结对项目-小学四则运算题目生成与判题程序
  • 2025年上海装修公司电话推荐:极家与俞润本土双选参考
  • 2025上海装修公司电话推荐:极家与俞润实测对比。
  • 教科书上令人触动的话
  • 生日
  • 2025 年防淹门源头厂家最新推荐排行榜权威发布,含地铁 / 防洪 / 地下通道专用款,15 项专利 + 央视报道品牌领衔
  • 2025年防静电/劳保/国网/餐厅/工厂/电工/防酸碱/电力/车间/航空/员工广告衫,文化衫/t恤/polo衫/冲锋衣厂家推荐排行榜
  • 一文带你掌握Visual Studio中集成的git功能
  • 【往届已检索!稳定检索】2025年第二届人工智能、数字媒体技术与交互设计国际学术会议(ICADI 2025)
  • 苹果最折腾的功能!iPhone快捷指令分享
  • 单提交智能评审上线!用云效精准定位复杂 MR 代码问题
  • GitLab小坑:remote: GitLab: You are not allowed to create protected branches on this project.
  • ubuntu安装nvidia驱动 - Leonardo
  • 2025 年少儿英语品牌口碑排行榜最新发布:欧美外教 + 原版教材甄选,含最新推荐及靠谱选择指南
  • 2025年滑石粉厂家推荐排行榜,纳米级滑石粉,工业级滑石粉,黑色滑石粉,高白滑石粉,化妆品级滑石粉,食品级滑石粉,表面改性滑石粉,大片径比滑石粉,低收缩率滑石粉,高填充母粒滑石粉
  • 自动化智能体与测试用例生成
  • 设置某些网站不走代理
  • 2025 年试验箱厂家最新推荐排行榜:涵盖高低温 / 恒温恒湿 / 冷热冲击等设备,精选实力厂商助力企业选购
  • 2025年除尘设备厂家权威推荐榜:除尘器,脉冲除尘器,中央脉冲除尘器,工业除尘器源头企业综合测评与选购指南
  • 2025 年国内充电桩厂家最新推荐排行榜:技术、安全与服务全方位对比的优质供应商优选榜单
  • 2025年最新游戏机和游艺机的屏幕驱动方案(含音乐播放和功放芯片)
  • 2025 年最新推荐!国内加工厂家排行榜:含车铣复合 / 精密零件 / CNC 车床等领域优质企业
  • spring是怎么解决循环依赖的?
  • 2025年精密球轴承厂家权威推荐榜:半导体设备/加工中心/机床主轴/直联主轴/电主轴/定制/国产高端/不锈钢/陶瓷/耐腐蚀/超高真空/真空泵/晶圆搬运机械手臂/进口替代/国产半导体/低温泵轴承精选