前面已经完成了用户的基本功能,也完成了引入Swagger文档、代码接口调试等工作,接下来要完成的,是博客的文章分类功能,这个需要进行单独的管理,减少多表的关联
一、 分页插件Pagehelper
由于数据比较多,我们的页面不可能全部展示出来,所以需要使用数据分页,目的就是使数据不全部展示出来,影响页面的美观和布局,分页最重要的就是当前第几页和一页展示多少数据的内容,因为我们使用的是Mybatis,它也有分页插件,借助它的分页插件来完成分页操作,首先将分页插件引到我们项目中,
官网地址:Mybatis-PageHelper/README_zh.md at master · pagehelper/Mybatis-PageHelper · GitHub
1.1 引入依赖
把下面的依赖放到pom.xml中,
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
1.2 配置分页插件
然后到application.yml中添加分页插件的配置
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
application.yml完整代码
spring:
application:
name: blog
datasource:
url: jdbc:mysql://localhost:3306/person_blog?useUnicode=true&useSSL=false&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT%2b8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
server:
port: 8081
servlet:
context-path: /blog
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*xml
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
基本的配置完成了
1.3 分页请求类封装
我们将这个分页请求的类进行封装,因为这个是公共的分页请求,在以后的功能中还会用到,所以将请求类进行封装,前端传过来的两个参数,一共就两个:页数,当前页显示的数量
我们在工具包Util包中再建一个page包,然后新建一个PageRequest.java,放置分页的类
package com.blog.personblog.config;
import lombok.Data;
@Data
public class PageRequest {
/**
*
* 页码
*/
private int pageNum;
/**
*
* 每页的数据条数
*/
private int pageSize;
}
1.4 分页返回类包装
我们在page包下再建一个返回类,主要放我们分页查询返回的数据,
新建一个分页返回类:PageResult.java
package com.blog.personblog.config.page;
import lombok.Data;
import java.util.List;
@Data
public class PageResult {
/**
* 当前页码
*/
private int pageNum;
/**
* 当前页的数量
*/
private int pageSize;
/**
* 记录总数
*/
private int totalSize;
/**
* 页码总数
*/
private int totalPages;
/**
* 存放返回数据
*/
private List<?> result;
}
二、 分页功能代码实现
2.1 添加实体类
首先新建一个分类的实体类,在entity包下新建一个Category.java类,代码和数据库字段对应即可
数据库中的表person_category及字段:
Category.java类:
package com.blog.personblog.entity;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class Category {
/**
* 主键ID
*/
private int categoryId;
/**
* 分类名称
*/
private String categoryName;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
2.2 添加业务接口
写完了实体类,就要在Service层调用业务接口
在service包中新建一个CategoryService.java的接口,将业务暴露出来
新建完成后, CategoryService.java的完整代码
package com.blog.personblog.service;
import com.blog.personblog.config.page.PageRequest;
import com.blog.personblog.entity.Category;
import java.util.List;
public interface CategoryService {
/**
* 获取所有的分类
* 需要的参数是前端传来的两个参数
* @return
*/
List<Category> getCategoryPage(PageRequest pageRequest);
/**
* 新建分类
* @param category
* @return
*/
int saveCategory(Category category);
/**
* 修改分类
* @param category
* @return
*/
int updateCategory(Category category);
/**
* 删除分类
* @param categoryId
* @return
* 删除分类不用返回值
*/
void deleteCategory(Integer categoryId);
/**
* 根据分类id查找
* @param categoryId
* @return
*/
Category findById(Integer categoryId);
}
2.3 添加业务接口实现类
Service层写完之后,在Impl包下新建一个CategoryServiceImpl.java实现类
CategoryServiceImpl.java实现类实现的是分类功能的增删改查,但查询调用的是分页查询
重点是分页接口的实现,通过前端传过来的两个值,使用PageHelper插件进行分页
package com.blog.personblog.service.Impl;
import com.blog.personblog.config.page.PageRequest;
import com.blog.personblog.entity.Category;
import com.blog.personblog.service.CategoryService;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryServiceImpl implements CategoryService {
@Override
public List<Category> getCategoryPage(PageRequest pageRequest) {
int pageNum = pageRequest.getPageNum();
int pageSize = pageRequest.getPageSize();
PageHelper.startPage(pageNum,pageSize);
return null;
}
@Override
public int saveCategory(Category category) {
return 0;
}
@Override
public int updateCategory(Category category) {
return 0;
}
@Override
public void deleteCategory(Integer categoryId) {
}
@Override
public Category findById(Integer categoryId) {
return null;
}
}
2.4 数据库查询接口实现
接着在mapper包下新建一个CategoryMapper.java接口
CategoryMapper.java类
package com.blog.personblog.mapper;
import com.blog.personblog.entity.Category;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CategoryMapper {
/**
* 分类列表
* @return
*/
List<Category> getCategoryPage();
/**
* 创建
* @param category
* @return
*/
int create(Category category);
/**
* 修改
* @param category
* @return
*/
int update(Category category);
/**
* 删除
* @param id
*/
void delete(Integer id);
/**
* 根据id查找分类
* @param id
* @return
*/
Category getById(Integer id);
}
2.5 编写数据库xml
我们在resources文件下的mapper文件夹,新建一个CategoryMapper.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.blog.personblog.mapper.CategoryMapper">
<resultMap id="BaseResultMap" type="com.blog.personblog.entity.Category">
<result column="category_id" jdbcType="INTEGER" property="categoryId"/>
<result column="category_name" jdbcType="VARCHAR" property="categoryName"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
</resultMap>
<select id="getCategoryPage" resultMap="BaseResultMap">
select * from person_category;
</select>
<insert id="create" parameterType="com.blog.personblog.entity.Category" useGeneratedKeys="true" keyProperty="CategoryId">
INSERT INTO person_category (category_name)
VALUES(#{categoryName})
</insert>
<update id="update" parameterType="com.blog.personblog.entity.Category">
update person_category
<set>
category_name = #{categoryName},
</set>
WHERE category_id = #{categoryId}
</update>
<delete id="delete" parameterType="java.lang.Integer">
delete from person_category where category_id = #{categoryId,jdbcType=INTEGER}
</delete>
<select id="getById" resultType="com.blog.personblog.entity.Category">
select category_id from person_category where category_id = #{categoryId}
</select>
</mapper>
数据库的接口已经写好了
接下来回到CategoryService接口的实现类 CategoryServiceImpl.java中
使用@Autowired引入Mapper层
@Autowired
CategoryMapper categoryMapper;
使用@Autowired引入CategoryMapper,然后用categoryMapper去调用CategoryMapper中的接口
CategoryServiceImpl.java完整代码
package com.blog.personblog.service.Impl;
import com.blog.personblog.config.page.PageRequest;
import com.blog.personblog.entity.Category;
import com.blog.personblog.mapper.CategoryMapper;
import com.blog.personblog.service.CategoryService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
@Override
public List<Category> getCategoryPage(PageRequest pageRequest) {
int pageNum = pageRequest.getPageNum();
int pageSize = pageRequest.getPageSize();
PageHelper.startPage(pageNum,pageSize);
List<Category> categoryList = categoryMapper.getCategoryPage();
return categoryList;
}
@Override
public int saveCategory(Category category) {
return categoryMapper.create(category);
}
@Override
public int updateCategory(Category category) {
return categoryMapper.update(category);
}
@Override
public void deleteCategory(Integer categoryId) {
categoryMapper.delete(categoryId);
}
@Override
public Category findById(Integer categoryId) {
Category category = categoryMapper.getById(categoryId);
if ( category == null) {
return null;
}
return category;
}
}
打开Swagger接口文档地址:
2.6 编写Controller层
在编写Controller层之前,我们先对分页返回的数据处理一下,我们在Util包下新建一个分页工具:PageUtil.java
这是为了把返回的数据都封装到PageResult中,里面有分页的信息和封装列表
PageUtil.java完整代码
package com.blog.personblog.util;
import com.blog.personblog.config.page.PageRequest;
import com.blog.personblog.config.page.PageResult;
import com.github.pagehelper.PageInfo;
/**
* 分页工具类
*/
public class PageUtil {
/**
*
* 分页信息封装
* @param pageRequest
* @param pageInfo
* @return
*
* 利用PageInfo
*/
public static PageResult getPageResult(PageRequest pageRequest, PageInfo<?> pageInfo) {
PageResult pageResult = new PageResult();
pageResult.setPageNum(pageInfo.getPageNum());
pageResult.setPageSize(pageInfo.getPageSize());
pageResult.setTotalSize(pageInfo.getTotal());
pageResult.setTotalPages(pageInfo.getPages());
pageResult.setResult(pageResult.getResult());
return pageResult;
}
}
接下来要编写Controller层, 记得加上Swagger接口
package com.blog.personblog.controller;
import com.blog.personblog.config.page.PageRequest;
import com.blog.personblog.config.page.PageResult;
import com.blog.personblog.entity.Category;
import com.blog.personblog.service.CategoryService;
import com.blog.personblog.util.JsonResult;
import com.blog.personblog.util.PageUtil;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
*
* 分类管理接口
*/
@Api(tags = "分类管理")
@RestController
@RequestMapping("/category")
public class CategoryController {
/**
*
* 调用Service层
*/
@Autowired
CategoryService categoryService;
/**
* 分页查询列表
* @param pageRequest
* @return
*/
@PostMapping("/list")
public JsonResult<Object> listPage(@RequestBody @Valid PageRequest pageRequest) {
List<Category> categoryList = categoryService.getCategoryPage(pageRequest);
PageInfo pageInfo = new PageInfo(categoryList);
PageResult pageResult = PageUtil.getPageResult(pageRequest, pageInfo);
return JsonResult.success(pageResult);
};
/**
* 添加分类
* @param category
* @return
*/
@ApiOperation(value = "添加分类")
@PostMapping("/create")
public JsonResult<Object> categoryCreate(@RequestBody @Valid Category category) {
int isStatus = categoryService.saveCategory(category);
if (isStatus == 0) {
return JsonResult.error("添加分类失败");
}
return JsonResult.success();
}
/**
* 修改分类
* @param category
* @return
*/
@ApiOperation(value = "修改分类")
@PostMapping("/update")
public JsonResult<Object> categoryUpdate(@RequestBody @Valid Category category) {
int isStatus = categoryService.updateCategory(category);
if (isStatus == 0) {
return JsonResult.error("修改分类失败");
}
return JsonResult.success();
}
@ApiOperation(value = "删除分类")
@PostMapping("/delete/{id}")
public JsonResult<Object> categoryDelete(@PathVariable(value = "id") int id) {
categoryService.deleteCategory(id);
return JsonResult.success();
}
}
打开Swagger接口文档地址:http://localhost:8081/blog/swagger-ui/index.html#
成功
2.7 出现的问题及解决方案
问题:
以上的配置和各层都写好之后,启动项目
用everything查找blogLog打开打印日志,日志信息如下:
springboot2.6好像禁止循环依赖还是啥的,翻来翻去没看到解决办法,后面去pageHelper github看,才看到最新版本已经解决了这个问题。
解决方案:
更新到最新版本pageHelper,版本1.4.1
添加成功之后,重新启动项目,控制台正常
三、测试
打开Postman,创建一个测试接口,命名为分类列表,测试分类功能,
需要传入的是两个参数,pageNum和pageSize
分类功能测试成功,、
测试添加分类功能,创建一个添加用户类,点击发送
发现报错500,后台肯定报错了,去查看,
再回到Postman,填入相应的JSON数据,点击Send发送 ,报200代表成功
打开数据库,打开person_category表格,可以看到新增的数据
再测一个删除
回到Postman,填入相应数据,
打开数据库,打开person_category表格刷新,发现id=1的数据被删除了