ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

基于ruoyi后端单表user的CURD功能完善

基于ruoyi后端单表user的CURD功能完善

目录

一.概述

环境准备

一.数据库准备

二.CSMD四层模块创建

1.control层(接口入口)创建:

2.Service 层(业务逻辑)创建:

3.Mapper 层(数据库操作)创建:

4.Domain 层(实体类)创建:

5.回看总体

三.安全机制调整

四.postman进行测试(示例)

一.概述

实现在ruoyi系统中以CSMD四层架构为基础完善后端单表user的CURD功能代码和测试。

适用于刚学完 SpringBoot+MyBatis,想快速上手后台框架,且不写前端,先让接口跑起来。

环境准备

流程:1.数据库准备

2.csmd四层模块创建(重点)

3.调整安全机制以便测试

4.用postman进行测试

一.数据库准备

首先进行sql建表,推荐使用navicat创建

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `age` int NULL DEFAULT NULL, `sex` char(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `creat_time` datetime NULL DEFAULT NULL, PRIMARY KEY (`id` DESC) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (3, 'dog', 1, 'm', '2025-10-07 20:11:44'); INSERT INTO `user` VALUES (2, 'fu', 21, 'w', '2025-10-09 15:07:31'); INSERT INTO `user` VALUES (1, 'chen', 20, 'm', '2025-10-14 15:07:06'); SET FOREIGN_KEY_CHECKS = 1;

二.CSMD四层模块创建

1.control层(接口入口)创建:

  • 提供 HTTP 接口(被前端或 Postman 调用)

  • 请求体会自动转为User对象,响应统一返回AjaxResult

在ruoyi中的路径

usercontroller.java具体代码实现

package com.ruoyi.web.controller.system; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import com.ruoyi.system.domain.User; import com.ruoyi.system.service.UserService; import com.ruoyi.common.core.domain.AjaxResult; @RestController //根路径 @RequestMapping("/system/users") public class UserController { //依赖注入,spring会把实现类UserServiceImpl 塞进来,直接可以调增删改查方法。 @Autowired private UserService userService; @GetMapping("/list") public AjaxResult list(User user) { List<User> list = userService.selectUserList(user); return AjaxResult.success(list); } @PostMapping public AjaxResult add(@RequestBody User user) { return AjaxResult.success(userService.insertUser(user)); } @PutMapping public AjaxResult edit(@RequestBody User user) { return AjaxResult.success(userService.updateUser(user)); } @DeleteMapping("/{id}") public AjaxResult remove(@PathVariable Long id) { return AjaxResult.success(userService.deleteUserById(id)); } }

@GetMapping("/list") @PostMapping @PutMapping @DeleteMapping("/{id}")注解详解

把普通的 Java 方法变成了能通过网址调用的 API,每条注解对应一种“动作 + 地址”的组合,浏览器/Postman/前端都能直接访问,返回值统一用 AjaxResult 包成 JSON。

2.Service 层(业务逻辑)创建:

  • 编写业务逻辑(比如校验、调用多个 Mapper、事务管理等)。

  • 当前我们只是简单转调 Mapper

在ruoyi中的路径

接口文件:UserService.java实现

package com.ruoyi.system.service; import java.util.List; import com.ruoyi.system.domain.User; //声明方法,不实现逻辑 public interface UserService { User selectUserById(Long id); List<User> selectUserList(User user); int insertUser(User user); int updateUser(User user); int deleteUserById(Long id); } //在control层注入的就是这个,但是实际上运行的是UserServiceImpl,此文件只作为一个接口

实体:serServiceImpl.java实现

package com.ruoyi.system.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.ruoyi.system.mapper.UserMapper; import com.ruoyi.system.domain.User; import com.ruoyi.system.service.UserService; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User selectUserById(Long id) { return userMapper.selectUserById(id); } @Override public List<User> selectUserList(User user) { return userMapper.selectUserList(user); } @Override public int insertUser(User user) { return userMapper.insertUser(user); } @Override public int updateUser(User user) { return userMapper.updateUser(user); } @Override public int deleteUserById(Long id) { return userMapper.deleteUserById(id); } }

在这个service层中:userservice只作为接口进行方法的声明,实际调用和运作的是serServiceImpl,它实现了UserService接口的 5 个方法,Spring 启动时会自动生成代理并注入到 Controller,并调用了UserMapper(DAO)完成 SQL 执行。

注解详解:

@Service:告诉 Spring“这是业务 Bean”,可被@Autowired注入

@Override:表明是接口方法的实现,编译器会帮你检查拼写/参数

3.Mapper 层(数据库操作)创建:

  • Mapper 层直接操作数据库。

  • SQL 写在 XML 文件里,Java 代码通过接口调用。

在ruoyi中的路径

Mapper接口:usermapper实现

package com.ruoyi.system.mapper; import java.util.List; import com.ruoyi.system.domain.User; public interface UserMapper { User selectUserById(Long id); List<User> selectUserList(User user); int insertUser(User user); int updateUser(User user); int deleteUserById(Long id); }

Mapper.xml 文件实现:

具体要放在:src/main/resources/mapper/system/UserMapper.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.ruoyi.system.mapper.UserMapper"> <resultMap id="UserResult" type="com.ruoyi.system.domain.User"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <result property="sex" column="sex"/> <result property="createTime" column="create_time"/> </resultMap> <select id="selectUserById" resultMap="UserResult"> SELECT * FROM mybatis.user WHERE id = #{id} </select> <select id="selectUserList" resultMap="UserResult"> SELECT * FROM mybatis.user <where> <if test="name != null and name != ''"> AND name LIKE CONCAT('%', #{name}, '%') </if> </where> </select> <insert id="insertUser" parameterType="User"> INSERT INTO mybatis.user (name, age, sex, create_time) VALUES (#{name}, #{age}, #{sex}, NOW()) </insert> <update id="updateUser" parameterType="User"> UPDATE mybatis.user SET name = #{name}, age = #{age}, sex = #{sex} WHERE id = #{id} </update> <delete id="deleteUserById"> DELETE FROM mybatis.user WHERE id = #{id} </delete> </mapper>

这里的mapper中接口只定义方法签名 → 编译期类型安全、可被 Spring 注入。而XML给出 SQL 文本、参数、结果映射 → 运行期由 MyBatis 解析。

xml做了什么?为什么mapper层要牵扯到resource中的xml

usermapper依然相当于是接口,XML 是 Mapper 层的“SQL 实现体”,当 Java 代码调用哪个方法时,应该去数据库执行哪条 SQL、怎么传参、怎么封装结果;resources 是“唯一能被 Maven 打包进 classpath 的目录”。把 XML 放 resources 下,MyBatis 才能在运行时找到它,把接口方法真正“粘”到 SQL 上。

4.Domain 层(实体类)创建:

  • 用于封装数据库表中的一行数据。

  • Controller、Service、Mapper 都会使用这个类。

在ruoyi中的路径

user.java实现

package com.ruoyi.system.domain; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.core.domain.BaseEntity; public class User extends BaseEntity { private static final long serialVersionUID = 1L; private Long id; private String name; private Integer age; private String sex; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; // Getter 和 Setter public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } }

这是 MyBatis 的“数据实体”,把数据库一行记录变成 Java 对象,把 Java 对象变成 JSON,是整个 CURD 流程的数据载体。

5.回看总体

我们通常在ruoyi-admin 模块实现接口入口 Controller。

在ruoyi-system 模块实现主要逻辑。

以下可以从总体上看到上述实施后的CSMD的关系

三.安全机制调整

Postman 测试/system/user/list [添加用户信息需传较多参数,故测试查询接口],修改如下代码:
屏蔽Spring Security 相关安全防护策略和检测。

因为ruoyi或者idea的版本不同,在实现上会有一些区别和改变,此处以idea2025.2.2和ruoyi3.9为例

在src/main/java/com/ruoyi/framework/config/SecurityConfig.java中添加

在src/main/java/com/ruoyi/web/controller/system/SysUserController.java中注释掉

在src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java中注释掉



四.postman进行测试(示例)

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进