目录
一.概述
环境准备
一.数据库准备
二.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中注释掉