瑞吉外賣實戰項目全攻略——第二天
瑞吉外賣實戰項目全攻略——第二天
該系列將記錄一份完整的實戰項目的完成過程,該篇屬於第二天
案例來自B站黑馬程序員Java項目實戰《瑞吉外賣》,請結合課程資料閱讀以下內容
該篇我們將完成以下內容:
- 完善登陸系統
- 新增員工
- 員工信息分頁查詢
- 啟用/禁止員工賬號
- 編輯員工信息
完善登陸系統
我們的功能完善一般分為三步
需求分析
我們在前面的文章中已經實現了login的系統登錄
但是我們頁面的訪問並沒有設置限制,如果我們直接跳過登陸頁面直接輸入系統內部頁面的url同樣可以進入
所以我們在進入內部頁面時需要先進行檢測用戶是否登錄
我們在之前的login功能中如果登陸成功就會給Session加入一個employee的ID值,我們憑藉ID來判斷是否登錄
此外,我們需要在進入頁面之前進行判斷,那麼我們就需要構造一個過濾器或者攔截器,下面我們採用過濾器Filter實現
代碼實現
我們創建一個filter文件夾專門存放filter過濾器
下面我們根據邏輯進行代碼實現過程:
package com.qiuluo.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.qiuluo.reggie.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 檢查用戶是否已經完成登錄
*/
// 注意:需要在啟動類上添加@ServletComponentScan註解來幫助識別過濾器
// 過濾器需要添加@WebFilter,設置filterName過濾器名,urlPatterns選擇過濾路徑
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
// 注意:需要繼承Filter過濾器
public class LoginCheckFilter implements Filter{
//路徑匹配器,支持通配符(類似於工具類,帶有方法)
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
// 實現doFilter方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 類型轉換,便於使用對應方法
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1、獲取本次請求的URI:/backend/index.html
String requestURI = request.getRequestURI();
log.info("攔截到請求:{}",requestURI);
// 中間步驟:定義不需要處理的請求路徑
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
//2、判斷本次請求是否需要處理
boolean check = check(urls, requestURI);
//3、如果不需要處理,則直接放行
if(check){
log.info("本次請求{}不需要處理",requestURI);
filterChain.doFilter(request,response);
return;
}
//4、判斷登錄狀態,如果已登錄,則直接放行
if(request.getSession().getAttribute("employee") != null){
log.info("用戶已登錄,用戶id為:{}",request.getSession().getAttribute("employee"));
filterChain.doFilter(request,response);
return;
}
log.info("用戶未登錄");
//5、如果未登錄則返回未登錄結果,通過輸出流方式向客戶端頁面響應數據
//(前端代碼需要我們返回一個"NOTLOGIN"來告訴前端沒有登錄)
response.getWriter().write(JSON.toJSONString(Result.error("NOTLOGIN")));
return;
}
/**
* 路徑匹配,檢查本次請求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match){
return true;
}
}
return false;
}
}
實際測試
我們首先需要採用clean,清除之前存有的數據操作
直接在瀏覽器輸入系統內部網頁的登錄URL,如果代碼正確,我們會閃回到登陸界面進行登錄
新增員工
我們的功能完善一般分為三步
需求分析
我們在系統內部頁面中點擊新增員工,會跳轉到另一個頁面,這屬於前端工作
接下來我們在頁面中填寫信息,前端會將這些信息封裝起來,以Employee的形式發送給後端端口
我們打開F12,輸入數據點擊保存後查看數據的請求方式(點擊負載,可以查看到填寫信息的Employee內容,這裡不再展示):
這個請求方式的路徑就是我們需要完善的代碼URL的路徑
代碼開發
現在我們來到IDEA中進行簡單的開發:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 新增員工
* @param employee
* @return
*/
@PostMapping
public Result<String> save(HttpServletRequest request,@RequestBody Employee employee){
// 日誌輸出
log.info("添加員工");
// 1.根據數據庫的設置,補全相關信息(密碼,註冊事件,修改時間,註冊人ID,修改人ID)
employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
Long empId = (Long) request.getSession().getAttribute("employee");
employee.setCreateUser(empId);
employee.setUpdateUser(empId);
// 2.調用業務層方法直接新增數據進入數據庫中
employeeService.save(employee);
// 3.返回Result返回體
return Result.success("新增員工成功");
}
}
實際測試
在主頁面輸入相關資料後,查看數據庫是否發生改變即可(因為主頁面的分頁操作還未完成,我們無法在前台看到信息)
異常處理
在介紹下一節之前,我們需要注意:
- 數據庫中的ID設為主鍵,意味着我們的賬號只能設置單獨的ID
因此,如果我們連續兩次輸入ID相同的員工創建,就會報錯導致程序出現異常
因此我們需要對異常進行處理,異常處理通常分為兩種方法:
- 在Controller方法中使用try,catch進行異常捕獲
- 使用異常處理器進行全局異常捕獲
第一種方法只能作用在當前情況下,但這種情況並不僅僅在當前情況出現,例如我們修改id如果修改為相同id也會報錯
第二種方法可以作用在全局狀態下,只要遇見這種問題,我們都會進行處理
因此我們採用第二種方法處理:
package com.qiuluo.reggie.common;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.sql.SQLIntegrityConstraintViolationException;
/**
* 全局異常處理
* @ControllerAdvice 來書寫需要修改異常的註解類(該類中包含以下注解)
* @ResponseBody 因為返回數據為JSON數據,需要進行格式轉換
*/
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {
/**
* 處理異常
* @ExceptionHandler 來書寫需要修改的異常
* SQLIntegrityConstraintViolationException.class是我們錯誤時系統彈出的,直接複製即可
* @return
*/
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public Result<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
// 我們可以通過log.error輸出錯誤提醒
// (我們可以得到以下提示信息:Duplicate entry '123' for key 'employee.idx_username')
log.error(ex.getMessage());
// 我們希望將id:123提取出來做一個簡單的反饋信息
if (ex.getMessage().contains("Duplicate entry")){
String[] split = ex.getMessage().split(" ");
String msg = split[2] + "已存在";
return Result.error(msg);
}
return Result.error("未知錯誤");
}
}
員工信息分頁查詢
我們的功能完善一般分為三步
需求分析
我們要將數據庫信息通過分頁查詢的方法查詢出來並反饋到頁面中
我們打開頁面後,直接查找報錯的部分,查看其請求信息以及相關URL:
打開負載,查看傳遞的信息:
還需要注意的是,當我們輸入查詢信息後,我們會多一個參數name,這個參數也需要進行後台操作:
我們需要注意的是我們採用的是數據庫的分頁查詢,因此我們需要設置一個分頁插件來將數據插入
此外我們的代碼書寫只需要採用page,pageSize查詢數據,將name進行近似匹配併當作查詢條件即可
代碼實現
首先我們先來實現分頁插件:
package com.qiuluo.reggie.config;
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;
/**
* 配置MP的分頁插件
* 注意:設置為配置類,使Spring可以搜索到
*/
@Configuration
public class MyBatisPlusConfig {
// 設置為Bean,受管理權限
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
// 1.創建一個大型Interceptor
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// 2.添加PaginationInnerInterceptor進Interceptor里即可
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
// 3.返回Interceptor
return mybatisPlusInterceptor;
}
}
接下來再來實現主頁面的代碼:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 員工信息分頁查詢
*/
@GetMapping("/page")
public Result<Page> page(int page, int pageSize, String name){
// 構造分頁構造器
Page pageInfo = new Page(page,pageSize);
// 構造條件構造器
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
// 添加排序條件
queryWrapper.orderByDesc(Employee::getUpdateTime);
// 執行查詢
employeeService.page(pageInfo,queryWrapper);
return Result.success(pageInfo);
}
}
實際測試
打開主頁面,數據出現即為成功
啟動/禁用員工賬號
我們的功能完善一般分為三步
需求分析
當點擊我們的員工行列後的啟動/禁止,數據庫的Status進行轉換
我們同樣點擊後打開F12查看請求URL以及參數:
我們可以看到它將id作為判斷員工的標準,將status的值傳入便於我們修改
其中前端將修改狀態的操作和修改員工信息的操作列為同一個請求,所以我們直接完成修改員工全部信息的操作即可
代碼實現
我們直接書寫後端代碼:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 根據id修改員工信息
* @param employee
* @return
*/
@PutMapping
public Result<String> update(HttpServletRequest request,@RequestBody Employee employee){
// 1.得到當前修改人的id
long empId = (long)request.getSession().getAttribute("employee");
// 2.對被修改員工的修改時間和修改人進行修改
employee.setUpdateTime(LocalDateTime.now());
employee.setUpdateUser(empId);
// 3.直接將數據修改即可(被修改的數據已經被封裝到了employee中,所以我們直接傳遞即可)
employeeService.updateById(employee);
return Result.success("更新成功");
}
}
實際測試
我們點擊啟動或者禁用,數據庫或前端頁面的狀態碼發生變化,即為成功
異常處理
如果按照上述操作進行,是無法成功修改狀態的,但是程序也不會發生報錯
這是因為我們的數據庫ID中設置長度為19位,但是我們的JS處理器的Long類型只能精確到前16位
這就會導致我們的ID數據的最後三位在傳遞時變化為000,導致前端傳遞ID與數據庫實際ID無法匹配,無法成功修改
我們採用的處理方法是將服務端傳遞的JSON數據進行處理,我們希望將Long類型的數據全部轉變為String類型,這樣就不會省略為0
具體步驟如下:
- 提供對象轉換器JacksonObjectMapper,基於Jackson進行Java對象到json數據的轉換(資料提供)
package com.qiuluo.reggie.common;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
/**
* 對象映射器:基於jackson將Java對象轉為json,或者將json轉為Java對象
* 將JSON解析為Java對象的過程稱為 [從JSON反序列化Java對象]
* 從Java對象生成JSON的過程稱為 [序列化Java對象到JSON]
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知屬性時不報異常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化時,屬性不存在的兼容處理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(BigInteger.class, ToStringSerializer.instance)
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//註冊功能模塊 例如,可以添加自定義序列化器和反序列化器
this.registerModule(simpleModule);
}
}
- 在WebMvcConfig配置類中擴展springMvc的消息轉換器,在此消息轉換器中使用提供的對象轉換器進行Java到Json數據的轉換
package com.qiuluo.reggie.config;
import com.qiuluo.reggie.common.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("開始靜態映射");
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
}
/**
* 擴展mvc框架的消息轉換器
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("擴展消息轉換器...");
//創建消息轉換器對象
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
//設置對象轉換器,底層使用Jackson將Java對象轉為json
messageConverter.setObjectMapper(new JacksonObjectMapper());
//將上面的消息轉換器對象追加到mvc框架的轉換器集合中
converters.add(0,messageConverter);
}
}
編輯員工信息
我們的功能完善一般分為三步
需求分析
當我們點擊頁面員工的編輯後,跳轉頁面:
這裡我們需要注意,我們的數據會直接出現在頁面中,這說明我們在點擊編輯時,後台會將我們的數據傳遞給前端,前端才能將數據展現出來
所以我們回到上一步,F12查看操作:
我們會發現,它調用了GET類型的請求,並將我們的id傳入,這說明我們需要創建一個路徑來根據id獲得數據
然後我們點擊編輯里的保存,查看F12:
我們會發現,這個路徑和我們上一步實現的啟動禁用賬號的路徑相同,所以當我們點擊修改後自動調用根據id修改參數的方法
代碼實現
我們只需要實現第一個方法根據ID獲得數據即可:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 根據id查詢員工
* @param id
* @return
*/
@GetMapping("/{id}")
public Result<Employee> getById(@PathVariable Long id){
// 根據路徑獲得id,直接調用業務層方法獲得employee
Employee emp = employeeService.getById(id);
if (emp != null){
return Result.success(emp);
}else {
return Result.error("未查詢成功");
}
}
}
實際測試
返回主頁面,點擊員工後面的編輯後,跳轉頁面時帶有數據即可
易錯點
在這裡我們會點出該項目目前容易出錯的位置
過濾器的使用
Filter也稱之為過濾器,它是Servlet技術中的技術,Web開發人員通過Filter技術,對web服務器管理的所有web資源
實現步驟主要分為兩步:
- 創建Java類,添加註解,繼承Filter
package com.qiuluo.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.qiuluo.reggie.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 檢查用戶是否已經完成登錄
*/
// @WebFilter註解配置相關信息
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter{
}
- 繼承並書寫doFilter方法
package com.qiuluo.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.qiuluo.reggie.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 檢查用戶是否已經完成登錄
*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter{
//路徑匹配器,支持通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
/*
doFilter用來實現過濾功能
在最開始我們設置了需要過濾的路徑
doFilter里在來設置在該路徑下哪些路徑可以直接跳過
doFilter里也可以設置需要經過哪些判斷或哪些處理才能經過
filterChain攜帶req和resp來表示通過過濾器
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1、獲取本次請求的URI
String requestURI = request.getRequestURI();// /backend/index.html
log.info("攔截到請求:{}",requestURI);
//定義不需要處理的請求路徑
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
//2、判斷本次請求是否需要處理
boolean check = check(urls, requestURI);
//3、如果不需要處理,則直接放行
if(check){
log.info("本次請求{}不需要處理",requestURI);
filterChain.doFilter(request,response);
return;
}
//4、判斷登錄狀態,如果已登錄,則直接放行
if(request.getSession().getAttribute("employee") != null){
log.info("用戶已登錄,用戶id為:{}",request.getSession().getAttribute("employee"));
filterChain.doFilter(request,response);
return;
}
log.info("用戶未登錄");
//5、如果未登錄則返回未登錄結果,通過輸出流方式向客戶端頁面響應數據
response.getWriter().write(JSON.toJSONString(Result.error("NOTLOGIN")));
return;
}
/**
* 路徑匹配,檢查本次請求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match){
return true;
}
}
return false;
}
}
數據庫的分頁操作
數據庫的分頁操作需要在數據庫內部的特定位置(limit)處修改值
所以需要設置一個MyBatisPlus攔截器來完成操作,MyBatisPlus已經為我們簡化了步驟,我們只需要將相對應的攔截器添加即可:
package com.qiuluo.reggie.config;
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;
/**
* 配置MP的分頁插件
*/
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
然後我們就需要注意業務層繼承的實現類中所給的方法的參數即可:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 員工信息分頁查詢
*/
@GetMapping("/page")
public Result<Page> page(int page, int pageSize, String name){
// 構造分頁構造器
Page pageInfo = new Page(page,pageSize);
// 構造條件構造器
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
// 這裡是一個like自帶的判斷,如果StringUtils.isNotEmpty(name)為true,才會執行該操作,否則無效
queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
// 添加排序條件
queryWrapper.orderByDesc(Employee::getUpdateTime);
// 執行查詢(參數為Page和qw類型,所以我們前面創建相應類型填充數據)
employeeService.page(pageInfo,queryWrapper);
return Result.success(pageInfo);
}
}
消息轉換器
首先我們來簡單解釋一下消息轉換器是什麼:
- 消息轉換器用於將請求/響應體內部的數據提取出來
- 例如在請求體中是URL的一部分,但是我們的後台代碼中卻是參數
- 消息轉換器就是用於這一部分參數的轉換,系統中配置了許多默認的消息轉換器
但默認的消息轉換器有時不能滿足我們的需求,例如上述異常處理中,我們希望直接將JSON數據轉化為String類型的數據
這時我們就需要手動設置消息轉換器:
package com.qiuluo.reggie.config;
import com.qiuluo.reggie.common.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 擴展mvc框架的消息轉換器
* 其中JacksonObjectMapper是我們自己創建的/下載的消息轉換器,裏面設置了我們所需要的轉換方式
* 下述操作只是將該轉換器添加到系統的轉換器隊列中,以便於能夠執行該轉換器的操作
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//創建消息轉換器對象
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
//設置對象轉換器,底層使用Jackson將Java對象轉為json
messageConverter.setObjectMapper(new JacksonObjectMapper());
//將上面的消息轉換器對象追加到mvc框架的轉換器集合中
converters.add(0,messageConverter);
}
}
結束語
該篇內容到這裡就結束了,希望能為你帶來幫助~
附錄
該文章屬於學習內容,具體參考B站黑馬程序員的Java項目實戰《瑞吉外賣》
這裡附上視頻鏈接:業務開發Day2-01-本章內容介紹_嗶哩嗶哩_bilibili