用户管理系统 06 实现后端用户管理功能 Java新手实战
B站视频教程:https://space.bilibili.com/3493114532596161/lists/6609623?type=season
关注B站"90后小陈老师",私信回复"Java"获取资料!
手把手教你完成用户管理核心功能,掌握企业级CRUD开发技巧
本文是用户管理系统实战系列的第六篇,专为Java新手设计。我们将基于前面搭建的基础架构,实现用户管理的核心功能:查询列表、新增、编辑、删除。采用MVP最小架构,让你快速理解企业级开发的完整流程。
🎯🎯🎯 本章学习目标
- ✅ 掌握用户列表分页查询实现
- ✅ 学会用户信息的增删改查操作
- ✅ 理解前后端数据交互流程
- ✅ 掌握MyBatis Plus高级查询技巧
🏗🏗🏗️ 用户管理功能架构
功能模块全景图
用户管理模块
├── 用户列表查询(分页+条件)
├── 新增用户(表单验证)
├── 编辑用户(数据回显)
└── 删除用户(逻辑删除)
🔧🔧 代码实现详解
1. Controller层实现 - 接口定义
位置:src/main/java/com/jackson/usermanager/controller/UserController.java
package com.jackson.usermanager.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jackson.usermanager.common.Result;
import com.jackson.usermanager.model.domain.User;
import com.jackson.usermanager.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.util.List;
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
/**
* 用户列表分页查询
*/
@GetMapping("/list")
public Result<Page<User>> getUserList(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String nickName) {
return userService.getUserList(pageNum, pageSize, nickName);
}
/**
* 根据ID查询用户详情
*/
@GetMapping("/{id}")
public Result<User> getUserById(@PathVariable Integer id) {
if (id == null || id <= 0) {
return Result.error("用户ID不能为空");
}
return userService.getUserById(id);
}
/**
* 新增用户
*/
@PostMapping("/add")
public Result<String> addUser(@RequestBody User user, HttpSession session) {
// 检查登录状态
User loginUser = (User) session.getAttribute("loginUser");
if (loginUser == null) {
return Result.error("未登录或登录已过期");
}
return userService.addUser(user);
}
/**
* 编辑用户信息
*/
@PutMapping("/update")
public Result<String> updateUser(@RequestBody User user, HttpSession session) {
// 检查登录状态
User loginUser = (User) session.getAttribute("loginUser");
if (loginUser == null) {
return Result.error("未登录或登录已过期");
}
return userService.updateUser(user);
}
/**
* 删除用户(逻辑删除)
*/
@DeleteMapping("/delete/{id}")
public Result<String> deleteUser(@PathVariable Integer id, HttpSession session) {
// 检查登录状态
User loginUser = (User) session.getAttribute("loginUser");
if (loginUser == null) {
return Result.error("未登录或登录已过期");
}
return userService.deleteUser(id);
}
// 原有的登录和注册方法保持不变...
}
2. Service层实现 - 业务逻辑
位置:src/main/java/com/jackson/usermanager/service/UserService.java
package com.jackson.usermanager.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jackson.usermanager.common.Result;
import com.jackson.usermanager.model.domain.User;
public interface UserService {
// 原有的登录注册方法...
Result<User> login(String phone, String pwd);
Result<String> register(User user);
// 新增用户管理方法
Result<Page<User>> getUserList(Integer pageNum, Integer pageSize, String nickName);
Result<User> getUserById(Integer id);
Result<String> addUser(User user);
Result<String> updateUser(User user);
Result<String> deleteUser(Integer id);
}
位置:src/main/java/com/jackson/usermanager/service/impl/UserServiceImpl.java
package com.jackson.usermanager.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jackson.usermanager.common.Result;
import com.jackson.usermanager.mapper.UserMapper;
import com.jackson.usermanager.model.domain.User;
import com.jackson.usermanager.service.UserService;
import lombok.RequiredArgsConstructor;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.Date;
import java.util.regex.Pattern;
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
// 常量定义
private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
private static final int MIN_PASSWORD_LENGTH = 8;
/**
* 用户列表分页查询
*/
@Override
public Result<Page<User>> getUserList(Integer pageNum, Integer pageSize, String nickName) {
try {
// 创建分页对象
Page<User> page = new Page<>(pageNum, pageSize);
// 构建查询条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 昵称模糊查询
if (StringUtils.hasText(nickName)) {
queryWrapper.like("nick_name", nickName);
}
// 只查询未删除的用户
queryWrapper.eq("status", 0);
// 按创建时间倒序排列
queryWrapper.orderByDesc("create_time");
// 执行分页查询
Page<User> userPage = userMapper.selectPage(page, queryWrapper);
// 数据脱敏处理
userPage.getRecords().forEach(this::desensitizeUserInfo);
return Result.success("查询成功", userPage);
} catch (Exception e) {
return Result.error("查询失败:" + e.getMessage());
}
}
/**
* 根据ID查询用户详情
*/
@Override
public Result<User> getUserById(Integer id) {
try {
User user = userMapper.selectById(id);
if (user == null) {
return Result.error("用户不存在");
}
// 检查用户状态
if (user.getStatus() != null && user.getStatus() == 1) {
return Result.error("用户已被删除");
}
// 数据脱敏后返回
User safeUser = desensitizeUserInfo(user);
return Result.success("查询成功", safeUser);
} catch (Exception e) {
return Result.error("查询失败:" + e.getMessage());
}
}
/**
* 新增用户
*/
@Override
@Transactional
public Result<String> addUser(User user) {
try {
// 1. 参数校验
Result<String> validateResult = validateUserParams(user);
if (validateResult.getCode() != 200) {
return validateResult;
}
// 2. 检查手机号是否已存在
if (isPhoneRegistered(user.getPhone())) {
return Result.error("该手机号已被注册");
}
// 3. 密码加密处理
if (StringUtils.hasText(user.getPwd())) {
String encryptedPassword = encryptPassword(user.getPwd());
user.setPwd(encryptedPassword);
}
// 4. 设置默认值
setDefaultValues(user);
// 5. 保存用户信息
int result = userMapper.insert(user);
if (result <= 0) {
return Result.error("新增用户失败");
}
return Result.success("新增用户成功");
} catch (Exception e) {
return Result.error("新增用户失败:" + e.getMessage());
}
}
/**
* 编辑用户信息
*/
@Override
@Transactional
public Result<String> updateUser(User user) {
try {
// 1. 基本参数校验
if (user.getId() == null || user.getId() <= 0) {
return Result.error("用户ID不能为空");
}
// 2. 检查用户是否存在
User existingUser = userMapper.selectById(user.getId());
if (existingUser == null) {
return Result.error("用户不存在");
}
// 3. 如果修改了手机号,检查是否重复
if (StringUtils.hasText(user.getPhone()) &&
!user.getPhone().equals(existingUser.getPhone())) {
if (isPhoneRegistered(user.getPhone())) {
return Result.error("该手机号已被其他用户使用");
}
}
// 4. 密码处理:如果有新密码则加密
if (StringUtils.hasText(user.getPwd())) {
if (user.getPwd().length() < MIN_PASSWORD_LENGTH) {
return Result.error("密码长度不能少于8位");
}
String encryptedPassword = encryptPassword(user.getPwd());
user.setPwd(encryptedPassword);
} else {
// 不更新密码,保持原密码
user.setPwd(null);
}
// 5. 设置更新时间
user.setUpdateTime(new Date());
// 6. 更新用户信息
int result = userMapper.updateById(user);
if (result <= 0) {
return Result.error("更新用户失败");
}
return Result.success("更新用户成功");
} catch (Exception e) {
return Result.error("更新用户失败:" + e.getMessage());
}
}
/**
* 删除用户(逻辑删除)
*/
@Override
@Transactional
public Result<String> deleteUser(Integer id) {
try {
// 1. 参数校验
if (id == null || id <= 0) {
return Result.error("用户ID不能为空");
}
// 2. 检查用户是否存在
User user = userMapper.selectById(id);
if (user == null) {
return Result.error("用户不存在");
}
// 3. 逻辑删除:更新状态为1
user.setStatus(1);
user.setUpdateTime(new Date());
int result = userMapper.updateById(user);
if (result <= 0) {
return Result.error("删除用户失败");
}
return Result.success("删除用户成功");
} catch (Exception e) {
return Result.error("删除用户失败:" + e.getMessage());
}
}
/**
* 用户参数校验
*/
private Result<String> validateUserParams(User user) {
// 手机号格式校验
if (!StringUtils.hasText(user.getPhone()) ||
!patternMatches(PHONE_REGEX, user.getPhone())) {
return Result.error("手机号格式不正确");
}
// 昵称非空校验
if (!StringUtils.hasText(user.getNickName())) {
return Result.error("昵称不能为空");
}
// 密码强度校验(新增用户时必填)
if (!StringUtils.hasText(user.getPwd())) {
return Result.error("密码不能为空");
}
if (user.getPwd().length() < MIN_PASSWORD_LENGTH) {
return Result.error("密码长度不能少于8位");
}
return Result.success("参数校验通过");
}
/**
* 用户信息脱敏
*/
private User desensitizeUserInfo(User user) {
User safeUser = new User();
safeUser.setId(user.getId());
safeUser.setNickName(user.getNickName());
safeUser.setPhone(desensitizePhone(user.getPhone()));
safeUser.setRole(user.getRole());
safeUser.setCreateTime(user.getCreateTime());
safeUser.setUpdateTime(user.getUpdateTime());
return safeUser;
}
/**
* 手机号脱敏
*/
private String desensitizePhone(String phone) {
if (StringUtils.hasText(phone) && phone.length() == 11) {
return phone.substring(0, 3) + "****" + phone.substring(7);
}
return phone;
}
// 原有的工具方法保持不变...
private boolean isPhoneRegistered(String phone) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("phone", phone);
queryWrapper.eq("status", 0);
Long count = userMapper.selectCount(queryWrapper);
return count != null && count > 0;
}
private String encryptPassword(String plainPassword) {
return BCrypt.hashpw(plainPassword, BCrypt.gensalt());
}
private void setDefaultValues(User user) {
if (user.getRole() == null) {
user.setRole(0);
}
if (user.getStatus() == null) {
user.setStatus(0);
}
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
}
private boolean patternMatches(String regex, String input) {
if (!StringUtils.hasText(input)) {
return false;
}
Pattern pattern = Pattern.compile(regex);
return pattern.matcher(input).matches();
}
// 原有的登录方法保持不变...
}
📊📊 前端接口调用示例
用户列表查询
// GET请求示例
fetch('/api/user/list?pageNum=1&pageSize=10&nickName=张三')
.then(response => response.json())
.then(data => {
console.log(data);
});
新增用户
// POST请求示例
fetch('/api/user/add', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
nickName: '新用户',
phone: '13800138000',
pwd: '12345678',
role: 0
})
})
.then(response => response.json())
.then(data => {
console.log(data);
});
🧪🧪 功能测试指南
1. 用户列表查询测试
请求:
GET http://localhost:8080/api/user/list?pageNum=1&pageSize=5
预期响应:
{
"code": 200,
"message": "查询成功",
"data": {
"records": [
{
"id": 1,
"nickName": "管理员",
"phone": "138****8000",
"role": 1,
"createTime": "2024-01-01 10:00:00"
}
],
"total": 10,
"size": 5,
"current": 1
}
}
2. 测试用例覆盖场景
| 功能模块 | 测试场景 | 预期结果 |
|---|---|---|
| 列表查询 | 正常分页查询 | 返回分页数据 |
| 列表查询 | 带条件查询 | 返回筛选结果 |
| 新增用户 | 正常新增 | 新增成功 |
| 新增用户 | 重复手机号 | 提示"手机号已存在" |
| 编辑用户 | 正常编辑 | 更新成功 |
| 编辑用户 | 不存在的ID | 提示"用户不存在" |
| 删除用户 | 正常删除 | 逻辑删除成功 |
🌟🌟🌟 核心知识点总结
✅ 完整CRUD功能实现
- 分页查询 - MyBatis Plus分页插件使用
- 条件查询 - QueryWrapper构建查询条件
- 数据验证 - 参数校验和业务规则检查
- 事务管理 - 保证数据一致性
✅ 企业级开发技巧
- 逻辑删除 - 数据安全保护
- 数据脱敏 - 隐私信息保护
- 统一返回 - 标准化接口响应
- 异常处理 - 系统健壮性保障
🎯🎯🎯 下一步学习预告
第七篇:项目前端初始化
💫💫💫 本章总结
通过本章学习,我们完成了用户管理系统的核心功能:
✅ 功能实现成果
- 完整的CRUD操作 - 增删改查全流程实现
- 分页查询优化 - 大数据量高效处理
- 业务逻辑完善 - 参数校验+数据验证
- 安全机制加强 - 权限检查+数据脱敏
💡💡💡 新手成长收获
- 掌握MyBatis Plus高级用法
- 理解企业级数据交互流程
- 学会完整的功能模块开发
- 具备独立开发业务功能的能力
🚀🚀🚀 立即实践建议
按照文章步骤亲手实现用户管理功能,并使用Postman进行完整测试!
💬💬💬 互动话题:在实现用户管理功能时,你遇到了哪些挑战?或者对哪个技术点最感兴趣?欢迎在评论区分享你的学习心得!
📌📌📌 下篇预告:下一篇我们将进入前端开发,使用Vue3实现漂亮的用户管理界面!
关注B站"90后小陈老师",私信回复"Java"获取资料!

被折叠的 条评论
为什么被折叠?



