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

后端开发CRUD实现

目录

一、环境依赖(pom.xml 核心依赖)

二、数据库表设计(以sys_user为例)

三、核心代码实现

1. 实体类(Entity)

2. DTO 类(数据传输对象)

(1)新增 / 修改请求 DTO

(2)条件查询相关 DTO: 涵盖单条件精确查询、多条件组合查询、模糊查询、范围查询等常见场景

(3)响应 DTO

3. MapStruct 映射接口

4. Mapper 接口(MyBatis-Plus)

5. Service 层(业务逻辑)

(1)Service 接口

(2)Service 实现类

6. Controller 层(接口暴露)

四、关键配置

1. MyBatis-Plus 配置

2. application.yml 配置


基于 Spring Boot + MyBatis-Plus + MapStruct 的完整 CRUD 实现,包含实体、DTO、映射、Service、Controller 全流程。

一、环境依赖(pom.xml 核心依赖)

<!-- Spring Boot Web -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- MyBatis-Plus -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency><!-- MapStruct(DTO与Entity映射) -->
<dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>1.5.5.Final</version>
</dependency>
<dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>1.5.5.Final</version><scope>provided</scope>
</dependency><!-- 数据库驱动(以MySQL为例) -->
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
</dependency><!-- Lombok(简化实体类) -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>

二、数据库表设计(以sys_user为例)

CREATE TABLE `sys_user` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',`username` varchar(50) NOT NULL COMMENT '用户名',`password` varchar(100) NOT NULL COMMENT '密码',`email` varchar(100) DEFAULT NULL COMMENT '邮箱',`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

三、核心代码实现

1. 实体类(Entity)

与数据库表字段一一对应,用于 MyBatis-Plus 操作数据库

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;@Data
@TableName("sys_user")
public class UserEntity {@TableId(type = IdType.AUTO)private Long id;                // 主键IDprivate String username;        // 用户名private String password;        // 密码private String email;           // 邮箱private LocalDateTime createTime; // 创建时间private LocalDateTime updateTime; // 更新时间
}

2. DTO 类(数据传输对象)

用于接收前端请求参数和返回响应数据,避免直接暴露 Entity。

(1)新增 / 修改请求 DTO
// 新增用户请求DTO
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Email;
import javax.validation.constraints.Size;@Data
public class UserAddDTO {@NotBlank(message = "用户名不能为空")@Size(max = 50, message = "用户名长度不能超过50字符")private String username;        // 用户名@NotBlank(message = "密码不能为空")@Size(min = 6, max = 20, message = "密码长度需在6-20字符之间")private String password;        // 密码@Email(message = "邮箱格式不正确")private String email;           // 邮箱
}// 修改用户请求DTO
@Data
public class UserUpdateDTO {@NotBlank(message = "用户ID不能为空")private Long id;                // 主键ID(修改需传)@Size(max = 50, message = "用户名长度不能超过50字符")private String username;        // 用户名(可选修改)@Size(min = 6, max = 20, message = "密码长度需在6-20字符之间")private String password;        // 密码(可选修改)@Email(message = "邮箱格式不正确")private String email;           // 邮箱(可选修改)
}
(2)条件查询相关 DTO: 涵盖单条件精确查询、多条件组合查询、模糊查询、范围查询等常见场景
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Pattern;
import java.time.LocalDateTime;
import java.util.List;/*** 用户表条件查询DTO* 支持:分页参数、模糊查询、精确查询、范围查询、多值查询、排序参数* 说明:所有参数均为可选,不传则不参与筛选*/
@Data
public class UserQueryDTO {// ======================== 分页参数(用于分页查询,非分页查询可忽略) ========================/*** 页码(默认1,最小1)*/@Min(value = 1, message = "页码不能小于1")private Integer pageNum = 1;/*** 每页条数(默认10,最小1,最大100)*/@Min(value = 1, message = "每页条数不能小于1")@Max(value = 100, message = "每页条数不能大于100")private Integer pageSize = 10;// ======================== 模糊查询条件 ========================/*** 用户名(模糊匹配,例如输入"张"可查询所有姓张的用户)*/private String username;/*** 邮箱(模糊匹配,例如输入"example.com"可查询所有该域名的邮箱)* 格式要求:为空或符合邮箱格式(如xxx@xxx.com)*/@Pattern(regexp = "^$|^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$", message = "邮箱格式不正确(可为空)")private String email;// ======================== 精确查询条件 ========================/*** 用户状态(精确匹配:1-正常,2-禁用,不传则不筛选)*/private Integer status;// ======================== 范围查询条件 ========================/*** 创建时间起始(>=,格式:yyyy-MM-dd HH:mm:ss,例如"2023-01-01 00:00:00")*/@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTimeStart;/*** 创建时间结束(<,格式:yyyy-MM-dd HH:mm:ss,例如"2023-12-31 23:59:59")*/@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTimeEnd;/*** 用户ID范围起始(>=,例如100表示查询ID>=100的用户)*/private Long idStart;/*** 用户ID范围结束(<=,例如200表示查询ID<=200的用户)*/private Long idEnd;// ======================== 多值查询条件 ========================/*** 用户ID列表(精确匹配列表中的ID,例如[1,2,3]表示查询ID为1、2、3的用户)*/private List<Long> idList;/*** 排除的用户ID列表(排除列表中的ID,例如[4,5,6]表示查询ID不是4、5、6的用户)*/private List<Long> excludeIdList;// ======================== 排序参数 ========================/*** 排序字段(默认createTime,可选值:id、username、createTime)*/@Pattern(regexp = "^$|id|username|createTime", message = "排序字段只能是id、username、createTime")private String sortField = "createTime";/*** 排序方式(asc-升序,desc-降序,默认desc)*/@Pattern(regexp = "^(asc|desc)$", message = "排序方式只能是asc或desc")private String sortOrder = "desc";
}
(3)响应 DTO
// 用户响应DTO(前端展示用,隐藏敏感字段如密码)
import lombok.Data;
import java.time.LocalDateTime;@Data
public class UserRespDTO {private Long id;                // 主键IDprivate String username;        // 用户名private String email;           // 邮箱private LocalDateTime createTime; // 创建时间
}

3. MapStruct 映射接口

用于 DTO 与 Entity 之间的自动转换,替代手动BeanUtils.copyProperties

import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;// 映射接口,componentModel = "spring"表示交给Spring管理
@Mapper(componentModel = "spring")
public interface UserMapper {// 单例实例(也可通过Spring注入)UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);// UserAddDTO -> UserEntity(新增时转换)UserEntity addDtoToEntity(UserAddDTO dto);// UserUpdateDTO -> UserEntity(更新时转换,覆盖已有字段)void updateDtoToEntity(UserUpdateDTO dto, @MappingTarget UserEntity entity);// UserEntity -> UserRespDTO(查询响应时转换)UserRespDTO entityToRespDto(UserEntity entity);
}

4. Mapper 接口(MyBatis-Plus)

继承BaseMapper,无需手动写 SQL(简单 CRUD)。

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;@Repository
public interface UserMapper extends BaseMapper<UserEntity> {// 复杂查询可在此添加注解SQL或XML映射
}

5. Service 层(业务逻辑)

(1)Service 接口
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;public interface UserService extends IService<UserEntity> {// 新增用户boolean addUser(UserAddDTO dto);// 修改用户boolean updateUser(UserUpdateDTO dto);// 根据ID删除用户boolean removeUserById(Long id);// 根据ID查询用户UserRespDTO getUserById(Long id);// 查询所有用户List<UserRespDTO> listAllUsers();
}
(2)Service 实现类
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {@Autowiredprivate UserMapper userMapper; // MapStruct映射接口@Overridepublic boolean addUser(UserAddDTO dto) {// DTO转EntityUserEntity entity = userMapper.addDtoToEntity(dto);// 保存到数据库return save(entity);}@Overridepublic boolean updateUser(UserUpdateDTO dto) {// 先查询原实体UserEntity entity = getById(dto.getId());if (entity == null) {return false; // 用户不存在}// DTO数据更新到EntityuserMapper.updateDtoToEntity(dto, entity);// 保存更新return updateById(entity);}@Overridepublic boolean removeUserById(Long id) {return removeById(id);}@Overridepublic UserRespDTO getUserById(Long id) {UserEntity entity = getById(id);return entity != null ? userMapper.entityToRespDto(entity) : null;}@Overridepublic List<UserRespDTO> listAllUsers() {List<UserEntity> entityList = list();// 批量Entity转DTOreturn entityList.stream().map(userMapper::entityToRespDto).collect(Collectors.toList());}
}

6. Controller 层(接口暴露)

接收前端请求,调用 Service 处理,返回响应结果。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;// 新增用户@PostMappingpublic ResponseEntity<Boolean> addUser(@Validated @RequestBody UserAddDTO dto) {boolean success = userService.addUser(dto);return new ResponseEntity<>(success, HttpStatus.CREATED);}// 修改用户@PutMappingpublic ResponseEntity<Boolean> updateUser(@Validated @RequestBody UserUpdateDTO dto) {boolean success = userService.updateUser(dto);return ResponseEntity.ok(success);}// 删除用户@DeleteMapping("/{id}")public ResponseEntity<Boolean> removeUser(@PathVariable Long id) {boolean success = userService.removeUserById(id);return ResponseEntity.ok(success);}// 根据ID查询用户@GetMapping("/{id}")public ResponseEntity<UserRespDTO> getUserById(@PathVariable Long id) {UserRespDTO dto = userService.getUserById(id);return dto != null ? ResponseEntity.ok(dto) : ResponseEntity.notFound().build();}// 查询所有用户@GetMappingpublic ResponseEntity<List<UserRespDTO>> listAllUsers() {List<UserRespDTO> dtoList = userService.listAllUsers();return ResponseEntity.ok(dtoList);}
}
 @Validated 分组校验

新增用户时无需校验  id ,修改时必须校验  id ,可通过分组实现:

7. 全局异常处理(捕获校验失败信息)

添加全局异常处理器,统一返回校验失败的提示,避免直接返回 400 原始错误:

import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;/*** 全局异常处理器:处理参数校验失败异常*/
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 捕获 @Validated 分组校验失败的异常*/@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {Map<String, String> errors = new HashMap<>();// 获取所有校验失败的字段信息BindingResult bindingResult = ex.getBindingResult();for (FieldError fieldError : bindingResult.getFieldErrors()) {// 字段名 -> 错误提示errors.put(fieldError.getField(), fieldError.getDefaultMessage());}return errors;}
}

校验失败示例响应:

{"username": "用户名不能为空","password": "密码长度需在6-20字符之间"
}

四、关键配置

1. MyBatis-Plus 配置

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@MapperScan("com.example.demo.mapper") // Mapper接口所在包
public class MyBatisPlusConfig {// 分页插件(可选,用于复杂查询分页)@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

2. application.yml 配置

spring:# 数据库配置datasource:url: jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=trueusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus:# 实体类包名(用于自动扫描)type-aliases-package: com.example.demo.entity#  mapper.xml文件路径(若有自定义SQL)mapper-locations: classpath:mapper/*.xml# 日志配置(打印SQL,开发环境用)configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

http://www.dtcms.com/a/594381.html

相关文章:

  • 4.忘记密码页测试用例
  • 怎么建设个网站做网站用啥软件
  • 凡科可以做淘宝客网站吗上海企业登记在线电子签名
  • 网站关键词优化代理山东临沂市需要建设网站的公司
  • Hello-Agents task1 智能体与语言模型基础
  • 做宣传手册的网站智慧团建网站登录忘记密码
  • 山西省建设监理协会官方网站外链代发免费
  • 区间|单调栈
  • 基于Springboot的电器商城管理系统
  • 做摄影网站的目的是什么意思wordpress创建角色
  • 公司网站设计开发公司注册域名阿里云
  • 强化学习3 Q-learning
  • 惠州制作公司网站pythone网站开发
  • 企业只有建立自己的网站平台广西麒铭建设有限公司网站
  • 使用gpio 的/sys 属性来模拟调试信号的操作
  • 专业网站建设公司兴田德润怎么样沈阳网站建设小工作室
  • 秦皇岛建设网站官网农产品跨境电商平台有哪些
  • 回溯专题之二叉树
  • 网站建设工具的种类aspnet网站开发实例项目
  • 怎样制造网站图片教程公司网站建设费用 知乎
  • Python 3.6.1 报错 “module ‘enum‘ has no attribute ‘IntFlag‘” 的真正原因与解决办法
  • 建设网站的重要意义wordpress 去除归档链接
  • 官方网站welcome在家办厂小型加工项目
  • 啥前端框架可以做网站首页企业网站建设招标书
  • 有域名一定要买空间做网站河北沙河市规划局或建设局网站
  • git diff 输出空,但 git status 提示 Motified(M)解决办法
  • 超市设计保定官网seo分析
  • 曼朗策划响应式网站建设网站建设 图书
  • 网站建设模板后台网站建设款分录
  • 【第1章>第5节】图像“膨胀”处理的理论分析与MATLAB仿真测试