【图书管理系统】深入解析基于 MyBatis 数据持久化操作:全栈实现单一删除图书、批量删除图书接口
删除图书
实现服务器代码
我们直接采用逻辑删除,调用 updateBook() 方法,把书的 status 修改为 0 即可:
实现客户端代码
点击删除时,调用delete()方法,我们来完善delete方法(前端代码已经提供了)。
接下来,我们完善删除方法:
URL 可以拼接 id ,因为 id 作为参数传入 function deleteBook(id) 中:
这里 url 又写错了,后文已经把
deteleBook
修改为deleteBook
,并且加上?bookId=
一定要注意 URL,很容易就会把 URL 写错
接口测试
ctrl+s 代码,重新运行程序,点击[删除]
点击确定后,跳转到第一页:
此时删除成功:
此时,表记录中的状态已经修改
点击[取消],观察数据依然存在
批量删除
批量删除
其实就是批量修改数据
。
约定前后端交互接口
- 点击【批量删除】按钮时,只需要把复选框选中的图书ID发送到后端即可
- 多个ID使用List的形式来传递参数
实现服务器代码
控制层 BookController
我们先打印一个日志,注意第二个参数为对象时,第一个参数要带上大括号;
接下来,我们按照 mapper 、service、controller 的顺序编写代码;
数据层 BookInfoMapper
批量删除需要用到动态SQL,所以煮啵动态 SQL 的部分使用 xml 实现;
注意:批量删除同样以软删除的方法来处理,所以批量删除就是批量修改图书的 status;
BookInfoMapper.java(接口定义)
xml 接口实现
业务层 BookService
接下来,我们完善 controller 层的代码,用于接收 service 层返回的数据:
接口测试
重新运行程序,使用 Postman 进行测试:
客户端常见错误状态码有400、404(URL 错误),我们回到后端查看错误日志
这个错误表明Spring MVC没有找到名为ids
的请求参数,而煮啵 URL 传递的参数名是id
。
修改 URL,重新构造请求:
此时,图书列表中 id 为 9,10,11 的图书已经被删除了:
实现客户端代码
点击【批量删除】按钮时,需要获取到所有选中的复选框的值
接下来,我们来完善前端批量删除的方法:
那么向数组 ids 中放什么值呢?
给 ids 数组赋值之后,就要向后端发送 ajax 请求:
也可以直接用 URL 传发送给后端的数据,也就是 ids 数组,后端使用了 @RequestParam
注解:
接下来,我们要处理后端返回的结果:
接口测试
ctrl+s 保存代码,重新启动程序;
测试步骤:
- 选择要删除的图书
- 点击【批量删除】按钮
按确定后,图书列表跳转到第一页:
此时,选中的图书已经被删除:
完整代码
BookController
@RestController
@RequestMapping("/book")
@Slf4j
public class BookController {@Autowiredprivate BookService bookService;@RequestMapping("/deleteBook")public String deleteBook(Integer bookId){log.info("删除图书, bookId {}", bookId);try {// 删除图书逻辑BookInfo bookInfo = new BookInfo();bookInfo.setId(bookId);bookInfo.setStatus(BookStatusEnum.DELETED.getCode());bookService.updateBook(bookInfo);// 修改图书成功, 返回一个空字符串return "";}catch (Exception e){log.error("删除图书发生异常, e: ", e); // 用于在后端查看异常日志, 不用返回给前端return "删除图书发生异常";}}@RequestMapping("/batchDelete")public boolean batchDelete(@RequestParam List<Integer> ids){log.info("批量删除图书, ids: {}", ids);try{bookService.batchDelete(ids);return true;}catch (Exception e){log.error("批量删除图书失败{}", e);return false;}}
}
BookService
@Service
public class BookService {@Autowiredprivate BookMapper bookMapper;public void updateBook(BookInfo bookInfo) {bookMapper.updateBook(bookInfo);}public Integer batchDelete(List<Integer> ids){return bookMapper.batchDelete(ids);}
}
BookMapper
@Mapper
public interface BookMapper {Integer updateBook(BookInfo bookInfo);Integer batchDelete(List<Integer> ids);
}
BookMapper.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bit.book.mapper.BookMapper"><!-- 现有的查询方法 --><update id="updateBook">update book_info<set><if test="bookName != null">book_name = #{bookName},</if><if test="author != null">author = #{author},</if><if test="count != null">count = #{count},</if><if test="price != null">price = #{price},</if><if test="publish != null">publish = #{publish},</if><if test="status != null">status = #{status}</if></set>where id = #{id}</update><delete id="batchDelete">update book_info set status = 0 where id in<foreach collection="ids" item="id" open="(" close=")" separator=",">#{id}</foreach></delete></mapper>
application.yml
server:port: 9090# 数据库连接配置
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/book_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Drivermybatis:configuration:map-underscore-to-camel-case: true #配置驼峰自动转换log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql语句mapper-locations: classpath:mapper/**Mapper.xml# 设置日志文件的文件名
logging:file:name: spring-book.log # 日志持久化