功能實現03 9.功能08-分頁顯示 9.1需求分析 將查詢的數據進行分頁顯示,要求功能如下: 顯示共多少條記錄 可以設置每頁顯示幾條 點擊第幾頁,顯示對應的數據 9.2思路分析 後端使用MyBatisPlus分頁插件完成查詢 修改FurnController,增加處理分頁顯示代碼 完成前臺代碼,加 ...
功能實現03
9.功能08-分頁顯示
9.1需求分析
將查詢的數據進行分頁顯示,要求功能如下:
- 顯示共多少條記錄
- 可以設置每頁顯示幾條
- 點擊第幾頁,顯示對應的數據
9.2思路分析
- 後端使用MyBatisPlus分頁插件完成查詢
- 修改FurnController,增加處理分頁顯示代碼
- 完成前臺代碼,加入分頁導航,並將分頁請求和後臺介面結合
9.3代碼實現
9.3.1分頁插件
創建MyBatisPlusConfig.java,在配置類中引入MyBatis-Plus分頁插件
package com.li.furn.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;
/**
* @author 李
* @version 1.0
*/
@Configuration
public class MybatisPlusConfig {
/**
* 思路:
* 1.註入MyBatisPlusInterceptor對象/bean
* 2.在註入MyBatisPlusInterceptor對象對象bean中,
* 加入分頁插件-PaginationInnerInterceptor
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//分頁需要指定資料庫類型,因為不同的資料庫分頁的sql語句不同
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
9.3.2Controller層
修改FurnController.java,增加分頁查詢處理
/**
* 分頁查詢的介面方法
*
* @param pageNo 顯示第幾頁,預設為1
* @param pageSize 每頁顯示條數,預設為5
* @return
*/
@GetMapping("/page")
@ResponseBody
public Result listFurnsByPage(@RequestParam(defaultValue = "1") Integer pageNo,
@RequestParam(defaultValue = "5") Integer pageSize) {
//通過page方法,返回page對象,給對象封裝分頁數據
Page<Furn> page = furnService.page(new Page<>(pageNo, pageSize));
return Result.success(page);
}
使用postman測試:
測試結果:
後端發出的sql:可以看到實際上mybatis-plus底層發出了兩次查詢,先查詢總記錄數,再根據總記錄數來分頁。
9.3.3前端代碼
修改HomeView.vue,完成分頁導航顯示,分頁請求。部分代碼:
第一部分:引入組件
<!--引入分頁組件-可以根據自己的需要進行定製-->
<div style="margin: 10px 0">
<el-pagination
@size-change="handlePageSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5,10,20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
第二部分:數據池,整個分頁導航的功能主要就是依賴於pageSize和total
...
data() {
return {
currentPage: 1,//當前頁數
pageSize: 5,//每頁顯示多少條記錄
total: 10,//數據總記錄數
...
}
},
...
第三部分:方法池
...
handlePageSizeChange(pageSize) {//處理pageSizes的修改
this.pageSize = pageSize;
//刷新家居列表
this.list();
},
handleCurrentChange(pageNum) {//修改當前要顯示的頁數
this.currentPage = pageNum;
this.list();
},
list() {//顯示所有家居信息,後面再進行分頁和考慮檢索條件
// request.get("/api/furns").then(res => {
// //將返回的數據和tableData綁定
// this.tableData = res.data;
// })
request.get("/api/furnsByPage", {
params: {//params代表請求的數據
pageNo: this.currentPage,
pageSize: this.pageSize
}
}).then(res => {
// console.log(res)
//將返回的數據和tableData綁定
this.tableData = res.data.records;
//由返回結果修改對應的total
this.total = res.data.total;
})
},
...
頁面結果顯示:
10.功能09-帶條件查詢分頁顯示列表
10.1需求分析
如果在搜索框中根據名稱查詢家居,可以返回分頁顯示的家居列表,並且點擊下一頁時,顯示的依然是符合條件的數據。
10.2思路分析
- 完成從後端代碼從mapper(dao層)-->Service層-->Controller層,並對代碼進行測試
- 完成前端代碼,使用axios發送http請求,完成帶條件查詢分頁顯示
10.3代碼實現
10.3.1Controller層
修改FurnController.java,添加按條件查詢的方法
/**
* 根據家居名查詢家居數據
*
* @param pageNo 當前頁
* @param pageSize 每頁顯示的大小
* @param condition 查詢條件:家居名,預設為空串
* @return
*/
@GetMapping("/furnsBySearchPage")
@ResponseBody
public Result listFurnsByConditionPage
(@RequestParam(defaultValue = "1") Integer pageNo,
@RequestParam(defaultValue = "5") Integer pageSize,
@RequestParam(defaultValue = "") String condition) {
//先創建QueryWrapper,可以將檢索條件封裝到QueryWrapper
QueryWrapper<Furn> queryWrapper = Wrappers.query();
//判斷條件是否為可空
if (StringUtils.hasText(condition)) {
//name為表中的欄位
queryWrapper.like("name", condition);
}
//有條件的分頁查詢
Page<Furn> page = furnService.page(new Page<>(pageNo, pageSize), queryWrapper);
return Result.success(page);
}
使用postman測試:
10.3.2前端代碼
在搜索按鈕上綁定list方法,list方法修改請求地址,當condition搜索條件為空時,就查詢的是所有的數據
list() {//考慮檢索條件
request.get("/api/furnsBySearchPage", {
params: {//params代表請求的數據
pageNo: this.currentPage,
pageSize: this.pageSize,
condition: this.search
}
}).then(res => {
// console.log(res)
//將返回的數據和tableData綁定
this.tableData = res.data.records;
//由返回結果修改對應的total
this.total = res.data.total;
})
},
頁面測試:可以看到點擊下一頁,檢索條件沒有失效
11.功能10-家居表單前後端校驗
11.1需求分析
如果在新增家居表單中,直接提交空表單,後端會報錯,因為對應的欄位不允許為空。
因此需要在表單前端進行校驗,當數據不符合條件時無法提交,並給予提示;同時在後端頁應該對接受的數據進行校驗,如果後端校驗不通過也應該給予相應的提示。
11.2思路分析
- 前端使用ElementPlus--表單rules驗證
- 後端使用JSR303數據校驗
11.3代碼實現
11.3.1前端代碼
修改HomeView.vue,增加表單驗證處理代碼
部分代碼:
<el-dialog title="提示" v-model="dialogVisible" width="35%">
<el-form :model="form" :rules="rules" ref="form" label-width="120px">
<!--prop表示和rules的哪個規則進行校驗-->
<el-form-item label="家居名" prop="name">
<el-input v-model="form.name" style="width: 80%"></el-input>
</el-form-item>
<el-form-item label="廠商" prop="maker">
<el-input v-model="form.maker" style="width: 80%"></el-input>
</el-form-item>
<el-form-item label="價格" prop="price">
<el-input v-model="form.price" style="width: 80%"></el-input>
</el-form-item>
<el-form-item label="銷量" prop="sales">
<el-input v-model="form.sales" style="width: 80%"></el-input>
</el-form-item>
<el-form-item label="庫存" prop="stock">
<el-input v-model="form.stock" style="width: 80%"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="save">確 定</el-button>
</span>
</template>
</el-dialog>
data() {//數據池
return {
...
rules: {//提交表單的校驗規則
name: [{required: true, message: '請輸入家居名', trigger: 'blur'}],
maker: [{required: true, message: '請輸入廠商', trigger: 'blur'}],
price: [
{required: true, message: '請輸入價格', trigger: 'blur'},
{pattern: /^(([1-9]\d*)|0)(\.\d+)?$/, message: '請輸入數字', trigger: 'blur'}
],
sales: [
{required: true, message: '請輸入銷量', trigger: 'blur'},
{pattern: /^(([1-9]\\d*)|0)$/, message: '請輸入數字', trigger: 'blur'}
],
stock: [
{required: true, message: '請輸入庫存', trigger: 'blur'},
{pattern: /^(([1-9]\\d*)|0)$/, message: '請輸入數字', trigger: 'blur'}
],
}
}
},
methods: {
save() {//(1)添加 (2)修改
if (this.form.id) {
...
} else {
//當添加家居時,彈出視窗的表單id是空的
//發送添加家居請求
//添加時和表單驗證關聯起來,如果沒有通過驗證,就不能提交
this.$refs['form'].validate(valid => {
if (valid) {//如果校驗通過,可以提交表單
request.post("/api/save", this.form)
.then(res => {//res為後端返回的結果
console.log("res=", res)
this.dialogVisible = false;//發送請求後隱藏表單
this.list();
})
} else {//否則不能提交
this.$message({
type: "error",
message: "數據格式不正確"
})
return false;
}
})
}
}
}
...
頁面效果:
11.3.2後端代碼
為了防止如postman之類的軟體繞過前端直接發送數據,還需要在後端進行校驗。如果
(1)使用JSR303數據校驗,在pom.xml中引入hibernate-validator.jar
<!--JSR303校驗-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
(2)修改Furn.java實體類
package com.li.furn.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* @author 李
* @version 1.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Furn {
//IdType.AUTO-主鍵類型為自增長
@TableId(type = IdType.AUTO)
private Integer id;
//對字元串進行非空校驗,應該使用@NotEmpty
@NotEmpty(message = "請輸入家居名")
private String name;
@NotEmpty(message = "請輸入廠商")
private String maker;
@NotNull(message = "請輸入數字")
@Range(min = 0, message = "價格不能小於0")
private BigDecimal price;
@NotNull(message = "請輸入數字")
@Range(min = 0, message = "銷量不能小於0")
private Integer sales;
@NotNull(message = "請輸入數字")
@Range(min = 0, message = "庫存不能小於0")
private Integer stock;
}
(3)修改FurnController.java的save()方法
@PostMapping("/save")
public Result save(@Validated @RequestBody Furn furn, Errors errors) {
//如果出現校驗錯誤,SpringBoot底層會把錯誤信息封裝到errors
HashMap<String, Object> map = new HashMap<>();
List<FieldError> fieldErrors = errors.getFieldErrors();
//遍歷errors,將錯誤信息放入map中
for (FieldError fieldError : fieldErrors) {
map.put(fieldError.getField(), fieldError.getDefaultMessage());
}
//如果沒有錯誤信息,說明後端校驗成功
if (map.isEmpty()) {
furnService.save(furn);
return Result.success();//返回成功數據
} else {//如果有錯誤信息,就不提交數據,並且將錯誤信息通過map返回客戶端顯示
return Result.error("400", "數據校驗錯誤", map);
}
}
(4)Postman測試
測試結果:
(5)接入前端
在HomeView.vue的數據池中定義一個對象validMsg,用於接收後端的校驗信息。
在save方法中,發送添加的ajax請求後,如果返回的操作碼為400,說明後端校驗出錯,取出錯誤信息
將錯誤信息顯示在添加表單中:
(6)頁面結果: