Bootstrap

文章相关接口

文章分类

1.新增文章分类

文章分类的表结构和实体类

实体类

接口文档

实现

新创建CategoryController,CategoryService,(CategoryServiceImpl),CategoryMapper

在CategoryController中添加方法

使用注解@PostMapping,没有映射路径,我们在CategoryController的类上添加一个映射路径@RequestMapping("/category"),然后同通过请求方式的方式进行区分,来提供服务。

在方法上声明一个实体类参数,加上@RequestBody让MVC框架自动读取请求体中的json数据,并把json数据转换成一个对象。

在mapper层添加分类时,要添加这个分类是谁创建的,创建时间,更新时间。但是接口文档中,前端给我们传递的参数里面只有分类的名称和分类的别名。所以在执行mapper层的sql之前,我们需要在service层中把category里面的一些属性值给它完善好

 CategoryController.java
package org.exampletest.controller;

import org.exampletest.pojo.Category;
import org.exampletest.pojo.Result;
import org.exampletest.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/category")
public class CategoryController {
    @Autowired
    private CategoryService categoryService;
    @PostMapping
    public Result add(@RequestBody @Validated Category category){
        categoryService.add(category);
        return Result.success();
    }

}

CategoryService.java 

package org.exampletest.service;

import org.exampletest.pojo.Category;

public interface CategoryService {
    //新增分类
    void add(Category category);

}

CategoryServiceImpl.java 

package org.exampletest.service.impl;

import org.exampletest.mapper.CategoryMapper;
import org.exampletest.pojo.Category;
import org.exampletest.service.CategoryService;
import org.exampletest.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Map;

@Service
public class CategoryServiceImpl implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Override
    public void add(Category category) {
        //补充属性值
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());

        Map<String,Object> map= ThreadLocalUtil.get();
        Integer userid = (Integer)map.get("id");
        category.setCreateUser(userid);
        categoryMapper.add(category);
    }
}

CategoryMapper.java 

package org.exampletest.mapper;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.exampletest.pojo.Category;

@Mapper
public interface CategoryMapper {
    //新增分类
    @Insert("insert into category(category_name,category_alias,create_time,update_time)"+"values(#{categoryName},#{categoryAlias},#{createTime},#{updateTime})")
    void add(Category category);
}

对参数进行校验

添加@NotEmpty,@Validated等

2.文章分类

接口文档

实现

 主体数据给浏览器响应,数据是一个数组,数组里面又有多个对象,java里数组可以声明为集合,存放多个Category对象:List<Category>

只能查询当前用户所创建的分类,在Controller里面需要参数用户id

时间字符串如何修改为接口文档的日期格式:

在实体类中,日期属性的上面添加@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;//创建时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;//更新时间

结果如图:

代码 

CategoryController

  @GetMapping
    public Result<List<Category>> list(){

        List<Category> cs = categoryService.list();
        return Result.success(cs);
    }

CategoryService

List<Category> list( );

CategoryServiceImpl

@Override
    public List<Category> list(){
        Map<String,Object> map= ThreadLocalUtil.get();
        Integer userId =(Integer)map.get("id");
        return categoryMapper.list(userId);
    }

CategoryMapper

    //查询所有
    @Select("select * from category where create_user = #{userId}")
    List<Category> list(Integer userId);

3.获取文章分类详情

接口文档

 

 

实现

通过接口文档可知,请求访问方式是Get,请求路径,请求参数等 

需要一个参数Integer id用于接收前端给我们传递的id

 CategoryController

 @GetMapping("/detail")
    public Result<Category> detail(Integer id){
        Category c=categoryService.findById(id);
        return Result.success(c);
    }

CategoryService

//根据分类查询信息
    Category findById(Integer id);

CategoryServiceImpl

    @Override
    public Category findById(Integer id){
        Category c = categoryMapper.findById(id);
        return c;
    }

CategoryMapper

   //根据id查询
    @Select("select * from category where id=#{id}")
    Category findById(Integer id);

结果:

 4.文章更新分类

接口文档 

实现 

 在Controller里添加方法,方法里添加实体类参数接收前端传来的数据,在实体类参数前添加@RequestBody自动获取数据,并将其json格式的数据转换成一个Category对象,添加@Validated对前端提交的参数进行校验,实体类对应的属性上需要添加响应的注解,完成参数的校验。

 

 CategoryController

   @PutMapping
    public Result update(@RequestBody @Validated Category category){
        categoryService.update(category);
        return Result.success();
    }

CategoryService

//更新分类
    void update(Category category);

CategoryServiceImpl

@Override
    public void update(Category category) {
        category.setUpdateTime(LocalDateTime.now());
        categoryMapper.update(category);
    }

CategoryMapper

 //更新
    @Update("update category set category_name = #{categoryName},category_alias=#{categoryAlias},update_time=#{updateTime} where id=#{id}")
    void update(Category category);

结果:

 5.分组校验

 测试新增文章分类

发现居然报错了?!因为新增文章分类和文章更新分类参数都是Category都使用@Validated进行校验,所以 属性上的注解都生效了。新增文章时不需要传递id,更新需要传递id,这时应该对校验规则进行分组。

分组校验

把校验项进行归类分组,在完成不同的功能的时候,校验指定组中的校验项

步骤:

  1. 定义分组(Validation里面表示分组需要通过接口表示,定义一个接口就代表的是一个分组,在实体类中定义接口)
    1.                 例如:public interface Add{}
  2. 定义校验项时指定归属分组(Validation给我们提供的这种校验的注解里边都有一个属性groups,通过groups指定当前校验项属于哪个分组;groups类型是一个数组,可以给同一个校验项指定多个分组)
    1. @NotNull(groups=Update.class)
      private Integer id;//主键ID
      @NotEmpty(groups={Add.class,Update.class})
      private String categoryName;//分类名称
  3. 校验时指定要校验的分组(在controller里方法参数前添加@Validated时传入哪个class)
    • @PutMapping
      public Result update(@RequestBody @Validated(Category.Update.class) Category category){

步骤1、2:        (Category.java)

package org.exampletest.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;

import java.time.LocalDateTime;
@Data
public class Category {
    @NotNull(groups=Update.class)
    private Integer id;//主键ID
    @NotEmpty(groups={Add.class,Update.class})
    private String categoryName;//分类名称
    @NotEmpty(groups={Add.class,Update.class})
    private String categoryAlias;//分类别名
    private Integer createUser;//创建人ID
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;//创建时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;//更新时间


    public interface Add{}

    public interface Update{}
}

步骤3:(CategoryController) 

  @PutMapping
    public Result update(@RequestBody @Validated(Category.Update.class) Category category){
        categoryService.update(category);
        return Result.success();

结果:

当同一个校验项有多个分组的时候,要写多个分组,尤其时校验项特别多的时候就特别麻烦,可以借助Validation的默认分组进行优化。

如果说某个校验项没有指定分组,默认属于Default分组

分组之间可以继承,A extends B 那么A中拥有B中所有的校验项

@Data
public class Category {
    @NotNull(groups=Update.class)
    private Integer id;//主键ID

//校验项没有指定分组,默认属于Default分组
    @NotEmpty
    private String categoryName;//分类名称
    @NotEmpty
    private String categoryAlias;//分类别名
    private Integer createUser;//创建人ID
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;//创建时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;//更新时间


//分组之间可以继承,A extends Default 那么A中拥有Default中所有的校验项

    public interface Add extends Default {}
    public interface Update extends  Default{}
}

6.删除文章分类

接口文档

实现

 CategoryController

    @DeleteMapping
    public Result delete(@RequestParam Integer id){
        categoryService.delete(id);
        return Result.success();
    }

CategoryService

//删除文章分类
    void delete(Integer id);

CategoryServiceImpl

   @Override
    public void delete(Integer id) {
        categoryMapper.delete(id);
    }

CategoryMapper

  //删除
    @Delete("delete from category where id=#{id}")
    void delete(Integer id);

结果:

 

;