当前位置: 首页 > article >正文

BigEvent项目后端学习笔记(二)文章分类模块 | 文章分类增删改查全流程解析(含优化)

📖 模块概述

  • 文章分类模块包括 新增文章分类、文章分类列表、获取文章分类详情、更新文章分类、删除文章分类 功能。
  • 本篇对于原项目进行了代码优化,将原先写在 Controller 层的业务逻辑代码迁移至了 Service 层。

🛠️ 技术实现要点

  • 分组校验
    • 定义分组:在实体类内部定义接口
    • 对校验项进行分组:通过 groups 属性指定
    • 校验时指定分组:给 @Validated 注解的 value 属性赋值
    • 校验项默认属于:Default 分组

⚙️ 各层职责与代码规范

🔗 Controller 层

@RestController
@RequiredArgsConstructor
@RequestMapping("/category")
public class CategoryController {
	...
}

🔗 Service 层

public interface CategoryService {
	...
}
@Service
@RequiredArgsConstructor
public class CategoryServiceImpl implements CategoryService {
	...
}

🔗 Mapper 层

@Mapper
public interface CategoryMapper {
	...
}

🔗 层间交互与依赖注入

@Service
@RequiredArgsConstructor
public class CategoryServiceImpl implements CategoryService {
	private final CategoryMapper categoryMapper;
	...
}
@RestController
@RequiredArgsConstructor
@RequestMapping("/category")
public class CategoryController {
    private final CategoryService categoryService;
    ...
}

🔍 功能实现详解

🎯 新增文章分类

🧩 Controller 层

请求路径:/category
请求方式:POST
接口描述:该接口用于新增文章分类

@PostMapping
public Result addCategory(@RequestBody @Validated(Category.Add.class) Category category) {
    categoryService.addCategory(category);
    return Result.success();
}

🧩 Service 层

  • 接口
// 新增分类
void addCategory(Category category);

// 根据分类名称查询分类信息
Category findCategoryByName(String categoryName);

// 根据分类别名查询分类信息
Category findCategoryByAlias(String categoryAlias);
  • 实现
/**
 * 添加分类
 *
 * @param category 分类对象
 */
@Override
public void addCategory(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);

    // 判断分类名称是否已存在
    Category categoryByName = findCategoryByName(category.getCategoryName());
    if (categoryByName != null) {
        throw new RuntimeException("分类名称已存在");
    }
    // 判断分类别名是否已存在
    Category categoryByAlias = findCategoryByAlias(category.getCategoryAlias());
    if (categoryByAlias != null) {
        throw new RuntimeException("分类别名已存在");
    }
    categoryMapper.addCategory(category);
}

/**
 * 根据分类名称查询分类对象
 *
 * @param categoryName 分类名称
 * @return 分类对象
 */
@Override
public Category findCategoryByName(String categoryName) {
    return categoryMapper.findCategoryByName(categoryName);
}

/**
 * 根据分类别名查询分类对象
 *
 * @param categoryAlias 分类别名
 * @return 分类对象
 */
@Override
public Category findCategoryByAlias(String categoryAlias) {
    return categoryMapper.findCategoryByAlias(categoryAlias);
}

Mapper 层

// 新增文章分类
@Insert("insert into category(category_name, category_alias, create_user, create_time, update_time) " +
        "values(#{categoryName}, #{categoryAlias}, #{createUser}, #{createTime}, #{updateTime})")
void addCategory(Category category);

// 根据分类名称查询分类
@Select("select * from category where category_name = #{categoryName}")
Category findCategoryByName(String categoryName);

// 根据分类别名查询分类
@Select("select * from category where category_alias = #{categoryAlias}")
Category findCategoryByAlias(String categoryAlias);

🎯 文章分类列表

🧩 Controller 层

请求路径:/category
请求方式:GET
接口描述:该接口用于获取当前已登录用户创建的所有文章分类

@GetMapping
public Result<List<Category>> getCategoryList() {
    List<Category> categoryList = categoryService.getCategoryList();
    return Result.success(categoryList);
}

🧩 Service 层

  • 接口
// 列表查询
List<Category> getCategoryList();
  • 实现
/**
 * 查询分类列表
 *
 * @return 分类列表
 */
@Override
public List<Category> getCategoryList() {
    Map<String, Object> map = ThreadLocalUtil.get();
    Integer userId = (Integer) map.get("id");
    return categoryMapper.getCategoryList(userId);
}

🧩 Mapper 层

// 查询某用户的所有文章分类
@Select("select * from category where create_user = #{userId}")
List<Category> getCategoryList(Integer userId);

🎯 获取文章分类详情

🧩 Controller 层

请求路径:/category/detail
请求方式:GET
接口描述:该接口用于根据ID获取文章分类详情

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

🧩 Service 层

  • 接口
// 根据 id 查询分类信息
Category findCategoryById(Integer id);
  • 实现
/**
 * 根据id查询分类对象
 *
 * @param id 分类id
 * @return 分类对象
 */
@Override
public Category findCategoryById(Integer id) {
    Category category = categoryMapper.findCategoryById(id);
    return category;
}

🧩 Mapper 层

// 根据 id 查询文章分类
@Select("select * from category where id = #{id}")
Category findCategoryById(Integer id);

🎯 更新文章分类

🧩 Controller 层

请求路径:/category
请求方式:PUT
接口描述:该接口用于更新文章分类

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

🧩 Service 层

  • 接口
// 更新文章分类
void updateCategory(Category category);
  • 实现
/**
 * 修改分类
 *
 * @param category 分类对象
 */
@Override
public void updateCategory(Category category) {
    category.setUpdateTime(LocalDateTime.now());
    categoryMapper.updateCategory(category);
}

🧩 Mapper 层

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

🎯 删除文章分类

请求路径:/category
请求方式:DELETE
接口描述:该接口用于根据ID删除文章分类

🧩 Controller 层

@DeleteMapping
public Result deleteCategory(Integer id){
    categoryService.deleteCategoryById(id);
    return Result.success();
}

🧩 Service 层

  • 接口
// 删除文章分类
void deleteCategoryById(Integer id);
  • 实现
/**
 * 根据id删除分类
 *
 * @param id 分类id
 */
@Override
public void deleteCategoryById(Integer id) {
    categoryMapper.deleteCategoryById(id);
}

🧩 Mapper 层

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

http://www.kler.cn/a/599536.html

相关文章:

  • python多线程和多进程的区别有哪些
  • Spring Boot整合Activiti工作流详解
  • C++|面试准备二(常考)
  • 【差分隐私相关概念】约束下的列联表边缘分布计算方法
  • 以mysql 为例, 在cmd 命令行连接数据,操作数据库,关闭数据库的详细步骤
  • 【C++进阶学习】第三讲----多态的概念和使用
  • 华为OD机试2025A卷 - 天然蓄水库(Java Python JS C++ C )
  • 链表中倒数第K个节点
  • 地平线AlphaDrive:首个基于GRPO的自动驾驶大模型,仅用20%数据,性能超越SFT 35%!
  • 2025-03-24 学习记录--C/C++-PTA 习题9-1 时间换算
  • unable to load vboxguest kernel module
  • FreeSWITCH入门到精通系列(四):FreeSWITCH模块介绍与使用
  • langchain-ollama的ragflow简单实现
  • [Windows] AI智能音频分离软件SpleeterGui v2.9.5.0【官方中文版】
  • 作业12 (2023-05-15 指针概念)
  • 卷积神经网络 - LeNet-5
  • Python+AI助力智能仓储:效率与科技的完美融合
  • Xamarin.Android实现本地化部署DeepSeek的对话功能
  • 【DFS】羌笛何须怨杨柳,春风不度玉门关 - 4. 二叉树中的深搜
  • STM32八股【3】------RAM和片上FLASH