[特殊字符] Spring Boot 实战:从零实现一个用户管理模块(附完整代码)

在本篇文章中,我将基于我正在开发的 Spring Boot 项目 yue,带大家一步步实现一个完整的用户管理模块。该模块包括用户的 新增、查询、更新、删除 四大核心功能,并结合了参数校验、统一响应结构、全局异常处理等实用技巧,适合初学者和进阶开发者参考学习。

✅ 源码路径:UserController.java、UserDTO.java、UserService.java、UserMapper.java 等文件


🧱 一、项目结构概览

我们采用标准的 Spring Boot 分层架构:

  • Controller 层:接收 HTTP 请求,调用 Service
  • Service 层:处理业务逻辑
  • Mapper 层:与数据库交互(使用 JPA)
  • Entity/DTO:数据实体类与请求参数类
  • Utils 工具类:封装通用结果返回结构 Result<T> 和全局异常处理器 [GlobalException]
    在这里插入图片描述

📥 二、定义请求参数对象 UserDTO

在 [UserDTO.java] 中,我们定义了用户注册或更新时所需的字段,并添加了验证注解:

package com.example.yue.entity.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Email;
//import org.hibernate.validator.constraints.Length;

public class UserDTO {

    private Integer userId;


//    @NotBlank(message="用户名不能为空") // 去除空格
//    @NotEmpty
    private String userName;
    @NotBlank(message="密码不能为空")
//    @Length(min=6,max=12,message="密码长度在6-12位之间")
    private String userPassword;
    @Email(message="邮箱格式错误")
    private String email;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    @Override
    public String toString() {
        return "UserDTO{" +
                "userName='" + userName + '\'' +
                ", userPassword='" + userPassword + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

使用 @NotBlank@Email 注解可以保证传入的数据符合规范,避免脏数据进入系统。


🖥️ 三、编写 Controller 接口

[UserController.java]是整个模块的入口,提供 RESTful 风格的接口:

package com.example.yue.controller;

import com.example.yue.entity.User;
import com.example.yue.entity.dto.UserDTO;
import com.example.yue.service.UserService;
import com.example.yue.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController // 接口方法返回对象 转成json文本
@RequestMapping("/user")  // 映射路径 localhost:8088/user
public class UserController {

    @Autowired
    private UserService userService;

//增加 Validated校验参数
    @PostMapping
    public Result<User> addUser(@Validated @RequestBody UserDTO user){
        User newUser = userService.addUser(user);
        return Result.success(newUser);
    }
//查询
    @GetMapping("/{userId}")
    public Result<User> getUser(@PathVariable("userId") Integer userId){
        User user = userService.getUser(userId);
        return Result.success(user);
    }

//修改
    @PutMapping
    public Result<User> updateUser(@RequestBody UserDTO user){
        User newUser = userService.updateUser(user);
        return Result.success(newUser);
    }
//删除
    @DeleteMapping("/{userId}")
    public Result<String> deleteUser(@PathVariable Integer userId){
        userService.deleteUser(userId);
        return Result.success("删除成功");
    }

}

使用 @Validated 注解触发参数校验,确保前端传递的参数符合要求。


⚙️ 四、服务层处理业务逻辑

[UserService.java]定义接口,而 [UserServiceImpl.java]实现具体逻辑:

package com.example.yue.service;

import com.example.yue.entity.User;
import com.example.yue.entity.dto.UserDTO;

public interface UserService {

    User addUser(UserDTO user);

    User getUser(Integer userId);

    User updateUser(UserDTO user);

    void deleteUser(Integer userId);
}

package com.example.yue.service.impl;
import com.example.yue.entity.User;
import com.example.yue.entity.dto.UserDTO;
import com.example.yue.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.yue.service.UserService;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    /**
     * 添加用户
     * @param user
     */
    @Override
    public User addUser(UserDTO user) {
        User  userObj = new User();
        BeanUtils.copyProperties(user, userObj);
        return userMapper.save(userObj);
    }
    /**
     * 根据id查询用户
     * @param userId
     */
    @Override
    public User getUser(Integer userId) {
        return userMapper.findById(userId).orElseThrow(()->{
            throw new IllegalArgumentException("用户不存在");
        });
    }
    /**
     * 更新用户
     * @param user
     */
    @Override
    public User updateUser(UserDTO user) {
        User  userObj = new User();
        BeanUtils.copyProperties(user, userObj);
        return userMapper.save(userObj);
    }
    /**
     * 删除用户
     * @param userId
     */
    @Override
    public void deleteUser(Integer userId) {
        userMapper.deleteById(userId);
    }
}

使用 BeanUtils.copyProperties 将 DTO 对象映射到 Entity,简化属性赋值过程。


💾 五、数据访问层(JPA + CrudRepository)

[UserMapper.java]继承 CrudRepository,Spring Data JPA 自动为我们生成基本的 CRUD 方法:

package com.example.yue.mapper;

import com.example.yue.entity.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository // spring的bean
public interface UserMapper extends CrudRepository<User, Integer> {
}

无需手动编写 SQL,即可完成增删改查操作,大大提升开发效率。


🧾 六、统一返回结构 Result

为了前后端分离开发更友好,我们封装了一个通用的返回结构 [Result.java]:

package com.example.yue.utils;

import org.springframework.http.HttpStatus;

public class Result<T> {

    private Integer code;
    private String message;
    private T data;

    public Result(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    //    请求成功
    public static <T> Result<T> success(T data) {
        return new Result<>(HttpStatus.OK.value(), "success!", data);
    }

// 请求失败
    public static <T> Result<T> fail(Integer code,String message) {
        return new Result<>(code, message, null);
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

所有接口都返回 Result<User>Result<String>,便于前端统一解析。


🚨 七、全局异常处理 GlobalException

[GlobalException.java]用于捕获并处理所有未处理的异常:

package com.example.yue.utils;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice // 拦截所有异常
public class GlobalException {

    Logger log = LoggerFactory.getLogger(GlobalException.class);
    @ExceptionHandler({Exception.class})
    public Result<String> handleException(Exception e, HttpServletRequest request, HttpServletResponse response) {
        log.error("[全局异常处理]", e);
        return Result.fail(500, "error");
    }
}

无论是参数校验失败还是运行时异常,都会被统一拦截并返回友好的错误信息。


✅ 八、测试接口

你可以使用 Postman 或 curl 测试以下接口:

方法路径功能说明
POST/user添加用户
GET/user/{id}查询用户详情
PUT/user更新用户信息
DELETE/user/{id}删除用户

示例请求体(JSON):

{
  "userName": "test",
  "userPassword": "123456",
  "email": "test@example.com"
}

📌 九、总结

通过本文你已经掌握了一个 Spring Boot 用户管理模块的核心实现,包括:

  • 使用 DTO 进行参数校验
  • 使用 JPA 快速操作数据库
  • 分层设计(Controller → Service → Mapper)
  • 统一返回结构 Result<T>
  • 全局异常处理机制

这些内容是构建任何 Spring Boot Web 应用的基础,后续可扩展支持分页查询、角色权限、JWT 登录认证等功能。


github地址

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏或分享给更多需要的朋友!如果你对 Spring Boot 的其他功能感兴趣,比如文件上传、定时任务、集成 Redis、Swagger 文档等,也欢迎留言告诉我,我会持续更新系列教程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值