对https://blog.csdn.net/Archer__13/article/details/127144489 和 https://blog.csdn.net/Archer__13/article/details/127155529 的内容合并总结后的完整版
一. 创建数据库
在数据库springboot下创建一个book表
CREATE TABLE `book` (
`id` int NOT NULL AUTO_INCREMENT,
`book_name` varchar(45) DEFAULT NULL,
`price` int DEFAULT NULL,
PRIMARY KEY (`id`)
)
二. 编写实体类对象
package com.stu.springboot.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
@Data
public class Book {
@TableId(type = IdType.AUTO)
private Integer id;
private String bookName;
private Integer price;
}
三. Mapper层
package com.stu.springboot.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.stu.springboot.pojo.Book;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BookMapper extends BaseMapper<Book> {
}
四. Service层
package com.stu.springboot.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.stu.springboot.pojo.User;
public interface UserService extends IService<User> {
}
package com.stu.springboot.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.stu.springboot.mapper.BookMapper;
import com.stu.springboot.pojo.Book;
import com.stu.springboot.service.BookService;
import org.springframework.stereotype.Service;
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {
}
五. 添加分页插件
package com.stu.springboot.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
六. Controller层
package com.stu.springboot.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stu.springboot.common.R;
import com.stu.springboot.pojo.Book;
import com.stu.springboot.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Arrays;
@Controller
public class BookController {
@Autowired
private BookService bookService;
@GetMapping("/manage/bookPage")
public String bookPage(){
return "manage/book";
}
@PostMapping("/manage/book")
@ResponseBody
public R<Page> book(int pageNo, int pageSize, String name, String lowPrice, String highPrice){
Page<Book> pageInfo = new Page<>(pageNo, pageSize); //第X页,每页显示X条
LambdaQueryWrapper<Book> queryWrapper = new LambdaQueryWrapper<>();
//添加过滤条件:如果name不为空时,根据书名模糊查询
queryWrapper.like(StringUtils.isNotEmpty(name), Book::getBookName, name);
//添加过滤条件:根据价格区间查找,>=lowPrice, <=highPrice
queryWrapper.ge(StringUtils.isNotEmpty(lowPrice) && StringUtils.isEmpty(highPrice), Book::getPrice, lowPrice);
queryWrapper.le(StringUtils.isEmpty(lowPrice) && StringUtils.isNotEmpty(highPrice), Book::getPrice, highPrice);
queryWrapper.between(StringUtils.isNotEmpty(lowPrice) && StringUtils.isNotEmpty(highPrice),Book::getPrice, lowPrice, highPrice);
//添加排序条件:根据价格降序
queryWrapper.orderByDesc(Book::getPrice);
//执行查询
bookService.page(pageInfo, queryWrapper);
return R.success(pageInfo);
}
@PostMapping("/manage/addBook")
@ResponseBody
public R addBook(Book book){
try {
boolean addResult = bookService.save(book);
if(addResult){
return R.success("添加成功");
}
} catch (Exception e) {
e.printStackTrace();
}
return R.error("添加失败");
}
@RequestMapping("/manage/deleteBook")
@ResponseBody
public R deleteBook(String[] id){
try {
boolean deleteResult = bookService.removeByIds(Arrays.asList(id));
if(deleteResult){
return R.success("删除成功");
}
} catch (Exception e) {
e.printStackTrace();
}
return R.error("删除失败");
}
@PostMapping("/manage/queryBookById")
@ResponseBody
public R queryBookById(String id){
Book book = bookService.getById(id);
if(book != null){
return R.success(book);
}
return R.error("未查询到该书");
}
@RequestMapping("/manage/updateBook")
@ResponseBody
public R updateBook(Book book){
try {
boolean updateResult = bookService.updateById(book);
if(updateResult){
return R.success("修改成功");
}
} catch (Exception e) {
e.printStackTrace();
}
return R.error("更新失败");
}
}
上面需要用到自定义common包下的R类(响应对象类)
package com.stu.springboot.common;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class R<T> { //服务端响应的数据都会封装成此对象
private Integer code; //编码:1成功,0和其它数字为失败
private String message; //错误信息
private T objectData; //数据
private Map map = new HashMap(); //动态数据
public static <T> R<T> success(T object) {
R<T> r = new R<T>();
r.objectData = object;
r.code = 1;
return r;
}
public static <T> R<T> error(String message) {
R r = new R();
r.message = message;
r.code = 0;
return r;
}
public R<T> add(String key, Object value) {
this.map.put(key, value);
return this;
}
}
七. 页面
<!DOCTYPE html>
<!--suppress ThymeleafVariablesResolveInspection -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>图书管理</title>
<!--引入jQuery-->
<script type="text/javascript" src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <!--引入jquery -->
<!--引入BootStrap框架-->
<link rel="stylesheet" type="text/css" href="../../static/jquery/bootstrap_3.3.0/css/bootstrap.min.css">
<script type="text/javascript" src="../../static/jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
<!--引入BootStrap框架的分页插件-->
<link rel="stylesheet" type="text/css" href="../../static/jquery/bs_pagination-master/css/jquery.bs_pagination.min.css">
<script type="text/javascript" src="../../static/jquery/bs_pagination-master/js/jquery.bs_pagination.min.js"></script>
<script type="text/javascript" src="../../static/jquery/bs_pagination-master/localization/en.js"></script>
<script type="text/javascript">
$(function(){
//当图书管理页面加载完成后,默认显示第1页,每页显示5条(即查询所有数据的第1页的数据,每页显示5条)
queryBookForPage(1, 5);
//给查询按钮添加单击事件
$("#queryBookBtn").click(function (){
//查询符合条件的所有数据,默认显示第1页,每页显示5条数据:queryBookForPage(1, 5);
queryBookForPage(1, $("#page").bs_pagination('getOption', 'rowsPerPage'));
//$("#page").bs_pagination('getOption', 'rowsPerPage')获取上次显示的每页显示的条数
//当修改每页显示的条数时,可以通过该方式显示当前页面需要展示的条数
});
//给添加按钮添加单击事件
$("#addBookBtn").click(function (){
//重置表单(表单内容清空)
$("#addBookForm").get(0).reset();
//弹出添加的模态窗口
$("#addBookModal").modal("show");
});
//给保存按钮添加单击事件
$("#saveBookBtn").click(function (){
//收集参数
var name = $.trim($("#addBookName").val());
var price = $.trim($("#addBookPrice").val());
//表单验证
if(name==""){
alert("书名不能为空");
return;
}
var priceRequest = /^(([1-9]\d*)|0)$/;
if(!priceRequest.test(price)){
alert("价格只能是非负整数");
return;
}
$.ajax({
url:'[[@{/manage/addBook}]]',
data:{
bookName:name,
price:price
},
type:'post',
dataType:'json',
success:function (data){
if(data.code=="1"){
//关闭模态窗口
$("#addBookModal").modal("hide");
//刷新市场活动列,显示第一页数据,保持每页数显示条数不变
queryBookForPage(1, $("#page").bs_pagination('getOption', 'rowsPerPage'));
}else{
//模态窗口不关
alert(data.message);
$("#addBookModal").modal("show");
}
}
});
});
//给全选按钮添加单击事件
$("#checkAll").click(function (){
//如果全选按钮是选中状态,则列表中所有checkbox都选中(即列表中每条数据的checkbox和全选按钮的值保持一致)
$("#bookTableRow input[type='checkbox']").prop("checked", this.checked);
});
//如果列表中的所有checkbox都选中,则全选按钮也选中,否则如果至少一个每有选中,则全选按钮也不选中
//由于列表中的数据是查询之后才加载出来的,晚于其他元素,所以用on的方式
$("#bookTableRow").on("click", "input[type='checkbox']", function (){
if($("#bookTableRow input[type='checkbox']").size() == $("#bookTableRow input[type='checkbox']:checked").size()){
$("#checkAll").prop("checked", true);
}else{
$("#checkAll").prop("checked", false);
}
});
//给删除按钮添加单击事件,删除选中的数据
$("#deleteBookBtn").click(function (){
//获取列表中所有被选中的checkbox
var checkedIds = $("#bookTableRow input[type='checkbox']:checked");
if(checkedIds.size() == 0){
alert("清选择要删除的书");
return;
}
if(window.confirm("确定删除吗?")){
var ids = "";
$.each(checkedIds, function (){
ids += "id="+this.value+"&";
});
ids = ids.substr(0, ids.length-1);
$.ajax({
url:'[[@{/manage/deleteBook}]]',
data:ids,
type: 'post',
dataType: 'json',
success:function (data){
if(data.code == "1"){
//刷新列表,显示第一页数据,保持每页数显示条数不变
queryBookForPage(1, $("#page").bs_pagination('getOption', 'rowsPerPage'));
}else{
alert(data.message);
}
}
});
}
});
//给修改按钮添加单击事件
$("#updateBookBtn").click(function (){
var checkId = $("#bookTableRow input[type='checkbox']:checked");
if(checkId.size() == 0){
alert("请选择要修改的数据");
return;
}
if(checkId.size() > 1){
alert("每次只能修改一条数据");
return;
}
var id = checkId[0].value;
$.ajax({
url:'[[@{/manage/queryBookById}]]',
data:{
id:id
},
type:'post',
dataType:'json',
success:function (data){
if(data.code=="1"){
//把信息显示到修改模态窗口的对应位置
$("#bookId").val(data.objectData.id);
$("#updateBookName").val(data.objectData.bookName);
$("#updateBookPrice").val(data.objectData.price);
//弹出修改的模态窗口
$("#updateBookModal").modal("show");
}else{
alert(data.message);
}
}
});
});
//给更新按钮添加单击事件
$("#updateBtn").click(function (){
//收集参数
var id = $("#bookId").val();
var name = $.trim($("#updateBookName").val());
var price = $.trim($("#updateBookPrice").val());
//表单验证
if(name==""){
alert("书名不能为空");
return;
}
var priceRequest = /^(([1-9]\d*)|0)$/;
if(!priceRequest.test(price)){
alert("价格只能是非负整数");
return;
}
$.ajax({
url:'[[@{/manage/updateBook}]]',
data:{
id:id,
bookName:name,
price:price
},
type:'post',
dataType:'json',
success:function (data){
if(data.code=="1"){
//关闭模态窗口
$("#updateBookModal").modal("hide");
//刷新列表,保持页号和每页数显示条数不变
queryBookForPage($("#page").bs_pagination('getOption', 'currentPage'), $("#page").bs_pagination('getOption', 'rowsPerPage'));
}else{
//模态窗口不关
alert(data.message);
$("#updateBookModal").modal("show");
}
}
});
});
});
function queryBookForPage(pageNo, pageSize){
var name = $("#bookName").val();
var lowPrice = $("#lowPrice").val();
var highPrice = $("#highPrice").val();
//发送请求
$.ajax({
url:'[[@{/manage/book}]]',
data: {
name:name,
lowPrice:lowPrice,
highPrice:highPrice,
pageNo:pageNo,
pageSize:pageSize
},
type: 'post',
dataType: 'json',
success:function (data){ //data是后端的R对象,R.objectData是后端的Page对象
//显示书的列表,将后端传回来的数据变成html写在相应的表格里
var htmlStr = "";
$.each(data.objectData.records, function (index, obj){
htmlStr += "<tr>";
htmlStr += "<td><input type=\"checkbox\" value=\""+obj.id+"\"/></td>";
htmlStr += "<td>"+obj.bookName+"</td>";
htmlStr += "<td>"+obj.price+"</td>";
htmlStr += "</tr>";
});
$("#bookTableRow").html(htmlStr);
//切换页面后,要取消全选按钮
$("#checkAll").prop("checked", false);
//【 切换页面时,刷新页面显示的内容 】
//计算总页数
var totalPages = 1;
if(data.objectData.total % pageSize == 0){
totalPages = data.objectData.total / pageSize;
}else{
totalPages = parseInt(data.objectData.total / pageSize) + 1;
}
//调用BootStrap框架的分页插件,显示翻页信息
$("#page").bs_pagination({
currentPage: pageNo, //当前页号
rowsPerPage: pageSize, //每页显示的数据个数
totalRows: data.objectData.total, //数据的总条数
totalPages: totalPages, //总页数,必须赋值
visiblePageLinks: 5, //分页条中显示的页面卡片个数
showGoToPage: true, //是否显示 跳转 到某个页面, 默认是true
showRowsPerPage: true, //是否显示 每页显示条数, 默认是true
showRowsInfo: false, //是否显示 记录的信息, 默认是true
//用户每次切换页号,都会自动出发本函数, 返回切换页号之后的pageNo和pageSize
onChangePage:function (event, pageObj){
queryBookForPage(pageObj.currentPage, pageObj.rowsPerPage);
}
});
}
});
}
</script>
</head>
<body>
<div>
<span th:text="|欢迎${session.loginUser.username}|"></span>
<a th:href="@{/user/logout}"><input type="button" value="退出"/></a>
</div>
<br>
<!-- 查询条 -->
<div>
书名: <input type="text" id="bookName">
价格: <input type="text" id="lowPrice"> — <input type="text" id="highPrice">
<input type="button" value="查询" id="queryBookBtn">
</div>
<br>
<!-- 添加、删除、修改 -->
<div>
<button type="button" class="btn btn-primary" id="addBookBtn"><span class="glyphicon glyphicon-plus"></span> 添加</button>
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#updateBookModal" id="updateBookBtn"><span class="glyphicon glyphicon-pencil"></span> 修改</button>
<button type="button" class="btn btn-danger" id="deleteBookBtn"><span class="glyphicon glyphicon-minus"></span> 删除</button>
</div>
<br>
<!-- 添加的模态窗口,使用的是bootstrap中已经定义好的样式 -->
<div class="modal fade" role="dialog" id="addBookModal" > <!-- modal用来标识模态窗口,fade是弹出时的动画效果(淡入淡出效果), role="dialog"标识对话框 -->
<div class="modal-dialog" role="document" style="width: 85%;"> <!-- class="modal-dialog":模态窗口的第二层容器 -->
<div class="modal-content"> <!-- class="modal-content":模态窗口的第三层容器 -->
<div class="modal-header"> <!-- class="modal-header":模态窗口的头部 -->
<button type="button" class="close" data-dismiss="modal"> <!-- data-dismiss:通过点击该元素关闭指定目标,即点击叉号关闭class=modal的模态窗口 -->
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">添加书籍</h4>
</div>
<div class="modal-body"> <!-- class="modal-body":模态窗口的主体内容 -->
<form class="form-horizontal" role="form" id="addBookForm">
<div class="form-group">
<label class="col-sm-2 control-label">书名<span style="font-size: 15px; color: red;">*</span></label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="addBookName">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">价格<span style="font-size: 15px; color: red;">*</span></label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="addBookPrice">
</div>
</div>
</form>
</div>
<div class="modal-footer"> <!-- class="modal-footer":模态窗口的页脚内容 -->
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" id="saveBookBtn">保存</button>
</div>
</div>
</div>
</div>
<!-- 修改的模态窗口 -->
<div class="modal fade" role="dialog" id="updateBookModal" >
<div class="modal-dialog" role="document" style="width: 85%;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">修改书籍</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" role="form">
<input type="hidden" id="bookId"> <!-- 使用隐藏域来存储获取到的id -->
<div class="form-group">
<label class="col-sm-2 control-label">书名<span style="font-size: 15px; color: red;">*</span></label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="updateBookName">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">价格<span style="font-size: 15px; color: red;">*</span></label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="updateBookPrice">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" id="updateBtn">更新</button>
</div>
</div>
</div>
</div>
<!-- 显示具体内容 -->
<div>
<table>
<thead>
<tr>
<td><input type="checkbox" id="checkAll"/></td>
<td>书名</td>
<td>价格</td>
</tr>
</thead>
<tbody id="bookTableRow">
<tr>
<td><input type="checkbox"/></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<br>
<!-- 分页条 -->
<div id="page"></div>
</body>
</html>