springboot --大事件--文章管理接口开发
新增文章接口
业务需求:
当用户在点击左侧菜单列表里边,在右侧这个页面里边去展示当前文章相关的内容,在右侧页面的右上角会有一个发布文章按钮,当用户点击按钮时,会弹出一个抽屉的界面,在这个抽屉的界面里有一个表单,用户需要在表单里输入文章的标题,文章分类,选择文章的封面图像,再去填写一下文章的内容,如果都填写了没有问题,那么此时就可以点击发布按钮,访问后台的接口。
实现思路:
需要在Controller中编译方法,在service层完成业务代码。
代码展示:
controller层:
@PostMappingpublic Result<String> add(@RequestBody Article article) {articleService.add(article);return Result.success();}
Service层:
public void add(Article article) {//将创建时间,修改时间设置为当前时间article.setCreateTime(LocalDateTime.now());article.setUpdateTime(LocalDateTime.now());//获取当前用户idMap<String,Object> map = ThreadUtil.get();Integer id = (Integer) map.get("id");//设置创建用户idarticle.setCreateUser(id);//保存articleMapper.save(article);
mapper层:
@Update("insert into article(title,content,cover_img,state,category_id,create_user,create_time,update_time) values(#{title},#{content},#{coverImg},#{state},#{categoryId},#{createUser},#{createTime},#{updateTime})")void save(Article article);
测试:
测试成功,在进行对参数的校验。
参数校验
需要在实体类上进行参数校验。
@Data@AllArgsConstructor@NoArgsConstructor@Validatedpublic class Article {private Integer id;//主键ID@NotEmpty@Pattern(regexp = "^\\S{1,10}$")private String title;//文章标题private String content;// 文章内容@NotEmpty@URLprivate String coverImg;// 封面图片private String state;//发布状态(已发布/草稿)@NotNullprivate Integer categoryId;//分类IDprivate Integer createUser;//创建者IDprivate LocalDateTime createTime;//创建时间private LocalDateTime updateTime;//修改时间}
注意要在controller层上添加注解:
public Result<String> add(@RequestBody @Validated Article article) {articleService.add(article);return Result.success();}
测试:
但是我们状态的校验用注解已经无法是实现了,因此需要自定义校验。
自定义校验
已有的注解不能满足所有的校验需求,特殊的情况需要自定义校验,(自定义校验注解)
实现步骤
自定义注解state
自定义校验数据的State Validation实现ConstraintValidator接口
在需要校验的地方使用自定义注解
代码展示:
@State
package com.lyc.annotation;import jakarta.validation.Constraint;import jakarta.validation.Payload;import java.lang.annotation.*;@Documented//在属性上生效@Target(ElementType.FIELD)//在运行时阶段保留@Retention(RetentionPolicy.RUNTIME)// 自定义注解 提供校验规则@Constraint(validatedBy = StateValidation.class)public @interface State {//提供校验失败后的提示信息String message() default "文章状态只能是:已发布或者草稿";//指定分组Class[] groups() default {};//负载,获取到该自定义注解的附加信息Class<? extends Payload>[] payload() default{};}
StateValidation
package com.lyc.annotation;import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
//泛型中提供的第一个参数是给那个注解提供给校验规则,第二个参数是校验的数据类型
public class StateValidation implements ConstraintValidator<State, String> {@Overridepublic boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {/*** @Param s 将来要校验的数据* @return*///提供校验规则if (s == null){return false;}if (s.equals("已发布") || s.equals("草稿")){return true;}return false;}
}
进行测试:
证明注解成功。
总结:
自定义校验
自定义校验State,message,groups,payload
自定义校验数据的类state Validation
在需要校验的地方使用自定义注解
文章列表(条件分页)
业务需求:
当用户在点击左侧菜单列里面的文章管理后,在页面的主区域展示当前用户创建的文章信息,并且这些文章是以列表的形式去展示,在列表的上方,可以选择文章分类,发布状态去搜索文章,在列表的底部,他去展示了一个分页条,里面展示了总记录数,还有一些用户的可选择项,用户可以选择每一页显示的条数,以及查询页码,上一页,下一页等等,都需要去访问后端接口,拿到数据,达到明确的要求,最终在列表中进行展示
查看接口文档:
实现思路:
在Controller中添加方法,完成列表查询。根据返回数据的返回结果去自定义pageBean类,需要去拿到封装分页查询的结果,需要去自定义。
然后在方法内部调用service层的方法查询。
在service层需要使用mybatis提供的pageHelper完成分页查询,我们只需要在调用mapper的方法执行SQL语句之前开启分页查询。
然后在mapper层编译动态SQL。
代码展示:
controller层:
public Result<PageBean<Article>> list(Integer pageNum,Integer pageSize,@RequestParam(required = false) Integer categoryId,@RequestParam(required = false) String state){PageBean<Article> list = articleService.list(pageNum, pageSize, categoryId, state);return Result.success(list);
}
Service层:
public PageBean<Article> list(Integer pageNum, Integer pageSize, Integer categoryId, String state) {//1. 构建Page Bean对象Map<String,Object> map= ThreadUtil.get();Integer userid = (Integer) map.get("id");PageBean<Article> pageBean = new PageBean<>();//开启分页查询 pageHelperPageHelper.startPage(pageNum,pageSize);//调用mapper完成查询List<Article> as = articleMapper.list(userid,categoryId,state);//Page中提供了方法,可以获取PageHelper分页查询后,得到的总记录条数和当前页数据Page<Article> p = (Page<Article>) as;//把数据填充到pageBean对象中pageBean.setTotal(p.getTotal());pageBean.setItems(p.getResult());return pageBean;
}
mapper层:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lyc.mapper.ArticleMapper">
<!-- 动态SQL--><select id="list" resultType="com.lyc.pojo.Article">select * from article<where><if test="categoryId != null">category_id = #{categoryId}</if><if test="state != null">and state = #{state}</if>and create_user = #{userid}</where></select>
</mapper>
注意事项:
在controller层中需要注意添加@RequestParam(required = false)注解。
在Service层中需要使用pageHelper完成分页查询,需要在pom配置文件中导入pageHelper
我们查询的结果是类似的集合需要向下强转,把它转化成一个Page对象,page是list的一个实现类
mapper层不要使用注解,因为是编译动态SQL,使用映射配置文件的方式更加方便。
获取文章详情
明确业务需求:点击文章列表中的条目即可看到指定文章的详细信息。
查询接口文档:
代码实现:
在接口文档中隐藏了createUser,因此我们可以在pojo包中新建ArticleDTO实体类,隐藏部分信息。
package com.lyc.pojo;import com.fasterxml.jackson.annotation.JsonFormat;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.time.LocalDateTime;@Data@AllArgsConstructor@NoArgsConstructorpublic class ArticleDTO {private Integer id;//主键IDprivate String title;//文章标题private String content;// 文章内容private String coverImg;// 封面图片private String state;//发布状态(已发布/草稿)private Integer categoryId;//分类ID@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private LocalDateTime createTime;//创建时间@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")private LocalDateTime updateTime;//修改时间}
在编译Controller层代码:
@GetMapping("/detail")
public Result<ArticleDTO> detail(Integer id){ArticleDTO article = articleService.detail(id);return Result.success(article);
}
service层:
public ArticleDTO detail(Integer id) {return articleMapper.detail(id);
}
mapper层:
<select id="detail" resultType="com.lyc.pojo.ArticleDTO">select id,title,content,cover_img,state,category_id,DATE_FORMAT(create_time, '%Y-%m-%d %H:%i:%s') AS createTime,DATE_FORMAT(update_time, '%Y-%m-%d %H:%i:%s') AS updateTimefrom article where id = #{id}
</select>
进行测试:
测试成功,业务完成
更新文章
业务分析:弹出表单供客户修改,并最终写入数据库。
查看接口文档并编译代码:
controller:
@PutMappingpublic Result update(@RequestBody @Validated ArticleDTO article) {articleService.update(article);return Result.success();}
service:
public void update(ArticleDTO article) {articleMapper.update(article);}
mapper:
@Update("update article set title = #{title},content = #{content},cover_img = #{coverImg},state = #{state},category_id = #{categoryId},update_time = now() where id = #{id}")void update(ArticleDTO article);
进行测试:
测试成功,业务完成。
删除文章
业务分析:通过id删除文章
查看接口文档:
代码展示:
controller:
@DeleteMappingpublic Result delete(Integer id) {articleService.delete(id);return Result.success();}
Service:
public void delete(Integer id) {articleMapper.delete(id);}
mapper:
@Update("delete from article where id = #{id}")void delete(Integer id);
进行测试:
查看数据库:
测试成功,业务实现。
希望对大家有所帮助