目录
文章分类
1、新增文章分类
前言
代码编写
测试
2、 文章分类列表
前言
代码编写
测试
3、获取文章列表详情
前言
代码实现
测试
4、更新文章分类
前言
代码实现
测试
5、删除文章分类
前言
代码实现
测试
分页查询
文章列表条件分页
前言
代码编写
测试
继续承接springboot课设
新增一个文章分类首先就要查询数据库中是否已经存在该分类。其他的就没什么好说的,有了上两篇博客编写代码的经验,这次的应该就挺容易了
Controller
@RestController
public class CategoryController {
@Autowired
private CategoryService categoryService;
@PostMapping
public Result category(@RequestBody @Validated Category category){
String categoryName = category.getCategoryName();
if (StringUtils.hasLength(categoryService.selectByName(categoryName))){
return Result.error("分类重复");
}
categoryService.category(category);
return Result.success();
}
}
Service
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
private CategoryMapper categoryMapper;
@Override
public String selectByName(String categoryName) {
return categoryMapper.selectByName(categoryName);
}
@Override
public void category(Category category) {
Map map = ThreadLocalUtil.get();
Integer createId = (Integer) map.get("id");
category.setCreateUser(createId);
categoryMapper.category(category);
}
}
mapper
@Select("select * from category where category_name = #{categoryName}")
String selectByName(String categoryName);
@Insert("insert into category (category_name, category_alias, create_user, create_time, update_time) " +
"value(#{categoryName},#{categoryAlias},#{createUser},now(),now())")
void category(Category category);
当数据为空时
当数据重复时
获取文章分类的这个列表,也就是说响应的结果data就是一个list集合,即Result返回的就是Result>
发起这个请求那么就开始查询分类列表,不需要参数,那么Controller空参就可以了
注:这里为什么与新增文章分类的接口都是/category?不会冲突吗?
不会,是因为那个新增的接口的请求方式是post请求,而查询文章列表的请求方式是get请求。因此虽然url的名字一样,但由于请求方式不同,它们实际上并不是同一个接口。
@JsonFormat注解可以更改时间显示的格式
Controller
@GetMapping
public Result> list(){
List categoriesList = categoryService.list();
return Result.success(categoriesList);
}
Service
@Override
public List list() {
Map map = ThreadLocalUtil.get();
Integer userId = (Integer) map.get("id");
return categoryMapper.list(userId);
}
Mapper
@Select("select * from category where create_user = #{userId}")
List list(Integer userId);
就是根据id查询分类,getById
get请求携带的参数直接就在url上,如localhost:8888/category/detail?id=6
Controller
@GetMapping("/detail")
public Result detail(Integer id){
Category category = categoryService.detail(id);
return Result.success(category);
}
Service
@Override
public Category detail(Integer id) {
return categoryMapper.detail(id);
}
Mapper
@Select("select * from category where id = #{id}")
Category detail(Integer id);
前端传递一个category类,修改原本的数据,应用put请求。这里直接根据id修改,但是如果故意选一个不存在的分类id,那就会出现错误。所以可以用Spring Vaildation来加一个@NotNull来标注一下,但这样又会出出现的新的问题,新增分类的接口就无法使用了。因为新增分类不需要填写id,id是数据库自增的,但是此时没有id就无法通过参数校验,所以要使用新的方法,分组校验。
分组校验:把校验项进行归类分组,在完成不同的功能时,校验指定组中的验项
在实体类中添加
@NotNull(groups = Update.class)
private Integer id;//主键ID
@NotNull()
@NotEmpty
private String categoryName;//分类名称
@NotNull()
@NotEmpty
private String categoryAlias;//分类别名
public interface Add extends Default{
}
public interface Update extends Default{
}
Controller
@PutMapping()
public Result updateCategory(@RequestBody @Validated(Category.Update.class) Category category){
categoryService.updateCategory(category);
return Result.success();
}
Service
@Override
public void updateCategory(Category category) {
categoryMapper.updateCategory(category);
}
Mapper
@Update("update category set category_name=#{categoryName},category_alias=#{categoryAlias}" +
",update_time = now() where id = #{id}")
void updateCategory(Category category);
这个就更没什么可说的了
Controller
@DeleteMapping()
public Result deleteCategory(Integer id){
categoryService.deleteCategory(id);
return Result.success();
}
Service
@Override
public void deleteCategory(Integer id) {
categoryMapper.deleteCategory(id);
}
Mapper
@Delete("delete from category where id = #{id}")
void deleteCategory(Integer id);
做分页查询通常需要一个类似的对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean {
private Long total;//总条数
private List items;//当前页数据集合
}
将来后台会将查询好的对象封装到这个对象中。为什么要单独设计一个对象?先看响应数据的例子
由于前端需要一个total参数,来表示此时有多少条信息,而这个参数如果放在items中,也就是文章里面,这是并不合适的。因此需要的独自将文章和这个total参数加起来合成一个新的对象来完成这个需求
在请求中中有四个参数,num和size是必填的,剩下两个参数前面@RequestParam(required = false) ,这样即使不携带这两个参数也不会报错
categoryId和state前端可能不会发送过来,所以后端的sql不能写死,要写成动态sql,因此要使用xml映射文件。
开启分页查询需要引入一个依赖PageHelper
com.github.pagehelper
pagehelper-spring-boot-starter
1.4.6
底层原理就是会自动地将pageNum和pageSize拼接到sql语句后面并加上limit,因此mapper里传递地参数就不再次需要传递pageNum和pageSize。
如果你不想使用PageHelper插件那就得把这两个参数传递进mapper里面自己写limit分页sql了
Controller
@GetMapping
public Result> list(Integer pageNum,Integer pageSize,
@RequestParam(required = false) Integer categoryId,
@RequestParam(required = false) String state){
PageBean pb = articleService.list(pageNum,pageSize,categoryId,state);
return Result.success(pb);
}
Service
@Override
public PageBean list(Integer pageNum, Integer pageSize, Integer categoryId, String state) {
//1、创建PageBean对象
PageBean pb = new PageBean<>();
//2、开启分页查询
PageHelper.startPage(pageNum,pageSize);
//3、调用mapper
Map map = ThreadLocalUtil.get();
Integer userId = (Integer) map.get("id");
List as = articleMapper.list(userId,categoryId,state);
//Page中提供了方法,可以获取PageHelper分页查询后,得到的总记录条数和当前页数据
Page p = (Page) as;
//把数据填充到PageBean对象中
pb.setTotal(p.getTotal());
pb.setItems(p.getResult());
return pb;
}
之所以要把list强转一下是因为Page是List的一个实现类。在多态中,父类无法调用子类的方法,只有强转成子类才可以调用子类中的特有的方法。
Mapper
List list(Integer userId, Integer categoryId, String state);
映射文件