
做了幾個項目,發(fā)現(xiàn)在這幾個項目里面,都實現(xiàn)了分頁查詢
效果,所以就總結(jié)一下,方便學(xué)習(xí)
我們
基于黑馬程序員的蒼穹外賣
來講解分頁查詢的要點
??什么是分頁查詢
分頁查詢是指將大量數(shù)據(jù)按照固定大小的頁進(jìn)行切分,每次查詢只返回一頁數(shù)據(jù),通過不斷翻頁來獲取全部數(shù)據(jù)。
??代碼實現(xiàn)
Result.java
這是一個common類,好多方法都可以使用
package com.sky.result;
import lombok.Data;
import java.io.Serializable;
/**
* 后端統(tǒng)一返回結(jié)果
* @param <T>
*/
@Data
public class Result<T> implements Serializable {
private Integer code; //編碼:1成功,0和其它數(shù)字為失敗
private String msg; //錯誤信息
private T data; //數(shù)據(jù)
public static <T> Result<T> success() {
Result<T> result = new Result<T>();
result.code = 1;
return result;
}
public static <T> Result<T> success(T object) {
Result<T> result = new Result<T>();
result.data = object;
result.code = 1;
return result;
}
public static <T> Result<T> error(String msg) {
Result result = new Result();
result.msg = msg;
result.code = 0;
return result;
}
}
所有的分頁查詢,我們都統(tǒng)一封裝為PageResult對象,來表示分頁查詢結(jié)果
PageResult.java
package com.sky.result;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* 封裝分頁查詢結(jié)果
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {
private long total; //總記錄數(shù)
private List records; //當(dāng)前頁數(shù)據(jù)集合
}
EmployeeController.java
我們查看接口文檔,發(fā)現(xiàn)接口路徑是GET方式,并且請求參數(shù)是query,不是json,那么就不需要使用注解@ResponseBody了
package com.sky.controller.admin;
import com.sky.constant.JwtClaimsConstant;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.EmployeePageQueryDTO;
import com.sky.entity.Employee;
import com.sky.properties.JwtProperties;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.EmployeeService;
import com.sky.utils.JwtUtil;
import com.sky.vo.EmployeeLoginVO;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* 員工管理
*/
@RestController
@RequestMapping("/admin/employee")
@Slf4j
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
// @Autowired
// private JwtProperties jwtProperties;
//
// /**
// * 登錄
// *
// * @param employeeLoginDTO
// * @return
// */
// @PostMapping("/login")
// public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
// log.info("員工登錄:{}", employeeLoginDTO);
//
// Employee employee = employeeService.login(employeeLoginDTO);
//
// //登錄成功后,生成jwt令牌
// Map<String, Object> claims = new HashMap<>();
// claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
// String token = JwtUtil.createJWT(
// jwtProperties.getAdminSecretKey(),
// jwtProperties.getAdminTtl(),
// claims);
//
// EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
// .id(employee.getId())
// .userName(employee.getUsername())
// .name(employee.getName())
// .token(token)
// .build();
//
// return Result.success(employeeLoginVO);
// }
//
// /**
// * 退出
// *
// * @return
// */
// @PostMapping("/logout")
// public Result<String> logout() {
// return Result.success();
// }
//
// @PostMapping
// @ApiOperation("新增員工")
// public Result save(@RequestBody EmployeeDTO employeeDTO){
// log.info("新增員工:{}",employeeDTO);
// return Result.success();
// }
@GetMapping("/page")
@ApiOperation("員工分頁查詢")
public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
log.info("員工分頁查詢,參數(shù)為{}",employeePageQueryDTO);
PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO);
//返回給Result
//返回的對象是pageResult
return Result.success(pageResult);
}
}
注意,結(jié)果return的是Result.success(pageResult);
結(jié)果返回的是pageResult對象
在service層擴(kuò)展一下分頁查詢方法
這里pageQuery會報錯,我們再一個分頁查詢接口EmployeeService中完善這個方法
EmployeeService.java
package com.sky.service;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.EmployeePageQueryDTO;
import com.sky.entity.Employee;
import com.sky.result.PageResult;
public interface EmployeeService {
//Employee login(EmployeeLoginDTO employeeLoginDTO);
//void save(EmployeeDTO employeeDTO);
//分頁查詢
PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
}
實現(xiàn)這個接口
EmployeeServiceImpl.java
package com.sky.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.PasswordConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.EmployeePageQueryDTO;
import com.sky.entity.Employee;
import com.sky.exception.AccountLockedException;
import com.sky.exception.AccountNotFoundException;
import com.sky.exception.PasswordErrorException;
import com.sky.mapper.EmployeeMapper;
import com.sky.result.PageResult;
import com.sky.service.EmployeeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
/**
* 員工登錄
*
* @param employeeLoginDTO
* @return
*/
// public Employee login(EmployeeLoginDTO employeeLoginDTO) {
// String username = employeeLoginDTO.getUsername();
// String password = employeeLoginDTO.getPassword();
//
// //1、根據(jù)用戶名查詢數(shù)據(jù)庫中的數(shù)據(jù)
// Employee employee = employeeMapper.getByUsername(username);
//
// //2、處理各種異常情況(用戶名不存在、密碼不對、賬號被鎖定)
// if (employee == null) {
// //賬號不存在
// throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
// }
//
// //密碼比對
// // TODO 后期需要進(jìn)行md5加密,然后再進(jìn)行比對
// if (!password.equals(employee.getPassword())) {
// //密碼錯誤
// throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
// }
//
// if (employee.getStatus() == StatusConstant.DISABLE) {
// //賬號被鎖定
// throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
// }
//
// //3、返回實體對象
// return employee;
// }
//
// @Override
// public void save(EmployeeDTO employeeDTO) {
// Employee employee=new Employee();
//
// //對象屬性拷貝
// BeanUtils.copyProperties(employeeDTO,employee);
//
// //設(shè)置賬號狀態(tài),默認(rèn)正常狀態(tài)
// employee.setStatus(StatusConstant.ENABLE);
//
// //設(shè)置密碼
// //默認(rèn)密碼為123456
// employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
//
// //設(shè)置當(dāng)前記錄的創(chuàng)建時間和修改時間
// employee.setCreateTime(LocalDateTime.now());
// employee.setUpdateTime(LocalDateTime.now());
//
// //設(shè)置當(dāng)前記錄創(chuàng)建人的id和修改人id
// employee.setCreateUser(BaseContext.getCurrentId());
// employee.setUpdateUser(BaseContext.getCurrentId());
//
// employeeMapper.insert(employee);
// }
//分頁查詢
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO){
PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
Page<Employee> page=employeeMapper.pageQuery(employeePageQueryDTO);
long total=page.getTotal();
List<Employee> records=page.getResult();
return new PageResult(total,records);
}
}
這里我們使用了Mybatis的pagehelper插件
要使用這個插件,實現(xiàn)我們在pox.xml文件中導(dǎo)入下面的依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
使用這個插件,會把我們后面的sql語句進(jìn)行動態(tài)拼接。類似于MySQL的動態(tài)sql,會動態(tài)的把limit關(guān)鍵字拼接進(jìn)去,并且進(jìn)行動態(tài)計算
同理,這里pageQuery會報錯,我們在接口DishMapper中完善這個方法,Mapper層一般與數(shù)據(jù)庫有關(guān)
package com.sky.mapper;
import com.github.pagehelper.Page;
import com.sky.annotation.AutoFill;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.enumeration.OperationType;
import com.sky.vo.DishVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
@Mapper
public interface DishMapper {
/**
* 根據(jù)分類id查詢菜品數(shù)量
* @param
* @return
*/
// @Select("select count(id) from dish where category_id = #{categoryId}")
// Integer countByCategoryId(Long categoryId);
//
//
// //插入菜品數(shù)據(jù)
// @AutoFill(value = OperationType.INSERT)
// void insert(Dish dish);
//菜品分頁查詢
Page<DishVO> pageQuery(DishPageQueryDTO dishPageQueryDTO);
}
注意
這里我們傳入的是DishPageQueryDTO,我們看一下下圖
下面我們來編寫動態(tài)sql
對于動態(tài)sql,使用注解進(jìn)行開發(fā)是比較麻煩的(因為我們要使用到動態(tài)標(biāo)簽),所以我們把這段sql寫到xml映射文件中
EmployeeMapper.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.sky.mapper.EmployeeMapper">
<select id="pageQuery" resultType="com.sky.entity.Employee">
select * from employee
<where>
<if test="name!=null and name!=''">
-- 動態(tài)拼接
and name like concat('%',#{name},'%')
</if>
</where>
order by create_time desc
</select>
</mapper>
?問題
我們發(fā)現(xiàn),界面展示的時間不是我們想要的 年–月–日,而是一大串?dāng)?shù)字,我們應(yīng)該怎么解決呢
使用下面的方法進(jìn)行解決
??解決方法
在WebMvcConfiguration中擴(kuò)展SpringMvc的消息轉(zhuǎn)換器,統(tǒng)一對日期類型進(jìn)行格式化處理
WebMvcConfiguration.java
package com.sky.config;
import com.sky.interceptor.JwtTokenAdminInterceptor;
import com.sky.json.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.List;
/**
* 配置類,注冊web層相關(guān)組件
*/
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Autowired
private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
//
// /**
// * 注冊自定義攔截器
// *
// * @param registry
// */
// protected void addInterceptors(InterceptorRegistry registry) {
// log.info("開始注冊自定義攔截器...");
// registry.addInterceptor(jwtTokenAdminInterceptor)
// .addPathPatterns("/admin/**")
// .excludePathPatterns("/admin/employee/login");
// }
//
// /**
// * 通過knife4j生成接口文檔
// * @return
// */
// @Bean
// public Docket docket() {
// ApiInfo apiInfo = new ApiInfoBuilder()
// .title("蒼穹外賣項目接口文檔")
// .version("2.0")
// .description("蒼穹外賣項目接口文檔")
// .build();
// Docket docket = new Docket(DocumentationType.SWAGGER_2)
// .apiInfo(apiInfo)
// .select()
// .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
// .paths(PathSelectors.any())
// .build();
// return docket;
// }
//
// /**
// * 設(shè)置靜態(tài)資源映射
// * @param registry
// */
// protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
// registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
// }
//
//擴(kuò)展springmvc的消息轉(zhuǎn)換器
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters){
log.info("擴(kuò)展消息轉(zhuǎn)換器");
//創(chuàng)建一個消息轉(zhuǎn)換器對象
MappingJackson2HttpMessageConverter converter=new MappingJackson2HttpMessageConverter();
//需要為消息轉(zhuǎn)換器設(shè)置一個對象轉(zhuǎn)換器,對象轉(zhuǎn)換器可以將Java對象轉(zhuǎn)換為json數(shù)據(jù)
converter.setObjectMapper(new JacksonObjectMapper());
//將自己的消息轉(zhuǎn)換器加入到容器里面
converters.add(0,converter);
}
}
序列化
:從Java對象生成json的過程反序列化
:把json解析為Java對象的過程
在上一段代碼中,我們使用了對象轉(zhuǎn)換器,但是我們應(yīng)該怎么創(chuàng)建一個對象轉(zhuǎn)換器呢
創(chuàng)建對象轉(zhuǎn)換器
JacksonObjectMapper.java
下面的代碼都是比較固定的
package com.sky.json;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
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.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對象轉(zhuǎn)為json,或者將json轉(zhuǎn)為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_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
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(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);
}
}
這樣子就實現(xiàn)了分頁查詢效果文章來源:http://www.zghlxwxcb.cn/news/detail-771374.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-771374.html
到了這里,關(guān)于【SpringBoot篇】分頁查詢 | 擴(kuò)展SpringMvc的消息轉(zhuǎn)換器的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!