DTO、VO、POJO与实体类使用方案(结合Mapper.xml)

结合MyBatis的Mapper.xml文件,展示完整的层级数据流转和数据库操作。

1. 实体类优化(Entity)

// User.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_user")
public class User {@TableId(type = IdType.AUTO)private Long userId;@NotBlankprivate String username;@NotBlankprivate String password;private String email;private String phone;private Date createTime;// 非数据库字段,用于关联查询@TableField(exist = false)private List<Role> roles;
}// Role.java
@Data
@TableName("sys_role")
public class Role {@TableId(type = IdType.AUTO)private Long roleId;private String roleName;private String roleDesc;
}

2. Mapper接口与XML配置

UserMapper.java

@Mapper
public interface UserMapper {// 插入用户并返回主键int insertUser(User user);// 根据ID查询用户(包含角色信息)User selectUserWithRoles(@Param("userId") Long userId);// 分页查询用户List<User> selectUserList(UserQueryDTO queryDTO);// 批量插入用户角色关系int batchInsertUserRoles(@Param("list") List<UserRole> userRoles);
}

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.example.mapper.UserMapper"><!-- 基本结果映射 --><resultMap id="BaseUserMap" type="com.example.entity.User"><id column="user_id" property="userId"/><result column="username" property="username"/><result column="password" property="password"/><result column="email" property="email"/><result column="phone" property="phone"/><result column="create_time" property="createTime"/></resultMap><!-- 包含角色信息的用户映射 --><resultMap id="UserWithRolesMap" type="com.example.entity.User" extends="BaseUserMap"><collection property="roles" ofType="com.example.entity.Role"><id column="role_id" property="roleId"/><result column="role_name" property="roleName"/><result column="role_desc" property="roleDesc"/></collection></resultMap><!-- 插入用户 --><insert id="insertUser" useGeneratedKeys="true" keyProperty="userId">INSERT INTO sys_user (username, password, email, phone)VALUES (#{username}, #{password}, #{email}, #{phone})</insert><!-- 查询用户及其角色 --><select id="selectUserWithRoles" resultMap="UserWithRolesMap">SELECT u.*, r.role_id, r.role_name, r.role_descFROM sys_user uLEFT JOIN sys_user_role ur ON u.user_id = ur.user_idLEFT JOIN sys_role r ON ur.role_id = r.role_idWHERE u.user_id = #{userId}</select><!-- 动态查询用户列表 --><select id="selectUserList" resultMap="BaseUserMap">SELECT * FROM sys_user<where><if test="username != null and username != ''">AND username LIKE CONCAT('%', #{username}, '%')</if><if test="email != null and email != ''">AND email = #{email}</if><if test="phone != null and phone != ''">AND phone = #{phone}</if><if test="createTimeStart != null">AND create_time >= #{createTimeStart}</if><if test="createTimeEnd != null">AND create_time &lt;= #{createTimeEnd}</if></where>ORDER BY create_time DESC</select><!-- 批量插入用户角色关系 --><insert id="batchInsertUserRoles">INSERT INTO sys_user_role (user_id, role_id)VALUES<foreach collection="list" item="item" separator=",">(#{item.userId}, #{item.roleId})</foreach></insert>
</mapper>

3. 服务层优化实现

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {private final UserMapper userMapper;private final RoleMapper roleMapper;private final PasswordEncoder passwordEncoder;@Override@Transactionalpublic UserVO createUser(UserDTO userDTO) {// DTO转EntityUser user = new User();BeanUtils.copyProperties(userDTO, user);// 密码加密user.setPassword(passwordEncoder.encode(userDTO.getPassword()));// 保存用户userMapper.insertUser(user);// 保存用户角色关系if (!CollectionUtils.isEmpty(userDTO.getRoleIds())) {List<UserRole> userRoles = userDTO.getRoleIds().stream().map(roleId -> new UserRole(user.getUserId(), roleId)).collect(Collectors.toList());userMapper.batchInsertUserRoles(userRoles);}// 返回完整的用户信息return getUserVO(user.getUserId());}@Overridepublic PageVO<UserVO> getUsers(UserQueryDTO queryDTO) {// 设置分页参数PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize());// 查询用户列表List<User> users = userMapper.selectUserList(queryDTO);PageInfo<User> pageInfo = new PageInfo<>(users);// 转换为VO列表List<UserVO> userVOs = users.stream().map(user -> UserVO.fromEntity(user, getRolesByUserId(user.getUserId()))).collect(Collectors.toList());// 构建分页VOreturn new PageVO<>(pageInfo.getTotal(),pageInfo.getPageNum(),pageInfo.getPageSize(),userVOs);}@Overridepublic UserVO getUserVO(Long userId) {User user = userMapper.selectUserWithRoles(userId);return UserVO.fromEntity(user, user.getRoles());}private List<Role> getRolesByUserId(Long userId) {return roleMapper.selectByUserId(userId);}
}

4. DTO/VO优化设计

UserDTO.java

@Data
public class UserDTO {@NotBlank(message = "用户名不能为空")@Size(min = 4, max = 20)private String username;@NotBlank(message = "密码不能为空")@Size(min = 6, max = 20)@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d).*$", message = "密码必须包含字母和数字")private String password;@Emailprivate String email;@Pattern(regexp = "^1[3-9]\\d{9}$")private String phone;@NotEmpty(message = "至少分配一个角色")private List<Long> roleIds;// 自定义转换方法public User toEntity() {User user = new User();BeanUtils.copyProperties(this, user);return user;}
}

UserVO.java

@Data
@Accessors(chain = true)
public class UserVO {private Long userId;private String username;private String email;private String phone;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createTime;private List<RoleVO> roles;// 静态工厂方法public static UserVO fromEntity(User user, List<Role> roles) {return new UserVO().setUserId(user.getUserId()).setUsername(user.getUsername()).setEmail(user.getEmail()).setPhone(user.getPhone()).setCreateTime(user.getCreateTime()).setRoles(roles.stream().map(RoleVO::fromEntity).collect(Collectors.toList()));}
}

PageVO.java (通用分页VO)

@Data
@AllArgsConstructor
public class PageVO<T> {private Long total;private Integer pageNum;private Integer pageSize;private List<T> list;// 计算总页数public Integer getPages() {if (pageSize == 0) return 0;return (int) Math.ceil((double) total / pageSize);}
}

5. 控制器层优化

@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {private final UserService userService;@PostMappingpublic ResponseEntity<Result<UserVO>> createUser(@Valid @RequestBody UserDTO userDTO) {UserVO userVO = userService.createUser(userDTO);return ResponseEntity.ok(Result.success(userVO));}@GetMappingpublic ResponseEntity<Result<PageVO<UserVO>>> getUsers(@Valid UserQueryDTO queryDTO) {PageVO<UserVO> page = userService.getUsers(queryDTO);return ResponseEntity.ok(Result.success(page));}@GetMapping("/{userId}")public ResponseEntity<Result<UserVO>> getUser(@PathVariable Long userId) {UserVO userVO = userService.getUserVO(userId);return ResponseEntity.ok(Result.success(userVO));}
}// 通用返回结果
@Data
@AllArgsConstructor
class Result<T> {private int code;private String message;private T data;public static <T> Result<T> success(T data) {return new Result<>(200, "success", data);}
}

6. 优化后的数据流转流程

  1. 前端请求Controller(接收DTO并校验)
  2. ControllerService(传递DTO)
  3. Service
    • 将DTO转换为Entity
    • 调用Mapper进行数据库操作
    • 将查询结果Entity转换为VO
  4. ServiceController(返回VO)
  5. Controller前端(返回VO数据)

7. 关键优化点

  1. Mapper.xml优化

    • 使用resultMap实现复杂结果映射
    • 动态SQL处理各种查询条件
    • 批量操作提高性能
  2. 对象转换优化

    • 在DTO/VO中定义转换方法
    • 使用链式调用简化代码
    • 静态工厂方法提高可读性
  3. 分页处理

    • 使用PageHelper实现物理分页
    • 统一分页返回结构
  4. 验证增强

    • 在DTO中使用更精细的验证注解
    • 密码复杂度验证
  5. 性能优化

    • 关联查询减少数据库访问次数
    • 批量插入提高效率

这种结构清晰地区分了各层职责,使代码更易维护和扩展,同时保证了良好的性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89259.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89259.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源|VDBBench 1.0正式官宣,完全复刻业务场景,支持用户自定义数据集

宣布个好消息&#xff0c;大家期待已久的VDBBench 1.0更新啦。 尝鲜链接&#xff1a; https://github.com/zilliztech/VectorDBBench/releases/tag/v1.0.0 对于这个功能的更新&#xff0c;我们准备了很久&#xff0c;也思考了很多。 因为对我们来说&#xff0c;VDBBench 从来不…

7,FreeRTOS列表与列表项的插入删除

一、实验目标 创建三个动态任务&#xff0c;栈空间大小均为128字。startTask、Task1、Task2。startTask仅运行一次&#xff0c;负责task1、task2任务的创建&#xff0c;startTask任务的删除。Task1负责初始化列表、列表项123&#xff0c;并进行列表项的插入实验与删除实验。Tas…

两款支持3D地图的WebGIS框架对比

前言 在当前的WebGIS技术发展中&#xff0c;3D地形图的可视化已经成为一个非常重要的功能&#xff0c;尤其是在城市规划、环境监测和虚拟旅游等领域中的应用。对于开发者而言&#xff0c;选择一个强大且适合的WebGIS框架是实现这些功能的关键。目前市场上较为流行的支持3D地形…

Github 2025-06-26 Go开源项目日报Top10

根据Github Trendings的统计,今日(2025-06-26统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10PureBasic项目1使用Gitleaks保护和发现机密信息 创建周期:2203 天开发语言:Go协议类型:MIT LicenseStar数量:14645 个Fork数量:13…

C++实现鱿鱼、羊了个羊、扫雷、原神模拟

C++ 鱿鱼游戏模拟实现 鱿鱼游戏中的经典场景可以通过C++模拟实现,例如“红绿灯”游戏。以下是一个简化版本的核心代码框架: #include <iostream> #include <thread> #include <chrono> #include <cstdlib> #include <ctime> #include <ve…

从用户到权限:解密 AWS IAM Identity Center 的授权之道

大家好&#xff0c;今天我们来解决一个非常具体的实战问题&#xff1a;如何让 IAM Identity Center 中创建的用户真正获得 AWS 账户的操作权限&#xff0c;从而取代老旧的 IAM 用户管理模式&#xff1f; 如果我们盯着用户详情页&#xff0c;想找一个“附加角色”的按钮&#x…

在 Spring Boot 中使用 MyBatis-Plus 的详细教程

前言 在现代的 Java Web 开发中&#xff0c;Spring Boot 和 MyBatis 已经成为主流框架组合。为了提升开发效率和简化数据库操作&#xff0c;MyBatis-Plus&#xff08;简称 MP&#xff09;应运而生。它是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改…

AI生成内容泛滥时代:从“袋鼠登机“视频看AI鉴伪与游戏智能的未来

近年来&#xff0c;AI生成内容的质量突飞猛进&#xff0c;从文本到图像再到视频&#xff0c;几乎达到了以假乱真的程度。近期一段"人类在飞机上吵架看呆袋鼠"的视频在社交网络疯传&#xff0c;获得数千万次观看后&#xff0c;才被证实是AI生成内容&#xff0c;这一事…

为什么在linux中不能直接使用pip进行安装

您好&#xff0c;这是一个非常深刻且关键的问题&#xff0c;触及了 Linux 系统管理与 Python 开发实践的核心原则。理解了这一点&#xff0c;您就真正开始像一位经验丰富的开发者那样思考了。 简单来说&#xff0c;答案是&#xff1a;为了保护操作系统自身的稳定和完整性。 让…

IDEA相关配置记录

IDEA相关配置记录 参考链接&#xff1a; 参考链接&#xff1a; 1、安装jdk D:\Program Files\Java\jdk-21 https://blog.csdn.net/2302_81410974/article/details/142031416 2、安装maven D:\Java\workspace-maven\apache-maven-3.9.10 . ├── LICENSE ├── NOTICE ├──…

FastGPT私有化部署完整指南

&#x1f680; FastGPT 私有化部署完整指南 &#x1f4cb; 环境要求 硬件要求 最低配置:CPU: 4核内存: 8GB存储: 50GB网络: 稳定互联网连接推荐配置:CPU: 8核内存: 16GB存储: 100GB SSD网络: 10Mbps带宽软件环境 必需软件:- Docker: > 20.10.0- Docker Compose: > 2.…

系统架构设计师论文分享-基于架构的软件设计方法及应用

我的软考历程 摘要 2023年2月&#xff0c;我所在的公司做了开发纱线MES系统的决定&#xff0c;该系统为国内纱线工厂提供SAAS服务&#xff0c;旨在提高纱线工厂的智能化和数字化水平。我在该项目中被任命为系统架构设计师&#xff0c;全面掌管该项目的架构设计工作。本文将结…

团结引擎发布纯鸿蒙应用

大家好&#xff0c;我是阿赵。   这里尝试一下用团结引擎发布纯鸿蒙系统的应用。 一、 安装鸿蒙系统发布需要的组件 在团结引擎的Hub里面找到Add modules: 然后找到OpenHarmony的支持选项&#xff0c;由于我已经安装过了&#xff0c;所以会显示Installed&#xff0c;如果没…

C++基础(FreeRDP编译)

安装 先安装openssl 保姆级OpenSSL下载及安装教程,OpenSSL下载及安装教程-CSDN博客 vcpkg integrate install 安装 vcpkg install zlib vcpkg install ffmpeg:x64-windows 编译指令 PS D:\freerdp\FreeRDP\build> cmake .. -G "Visual Studio 17 2022" -A x…

用celery作为信息中间件

要在 Django 的 settings.py 中设置 Redis 作为 Celery 的 broker 和(可选)backend,你需要添加如下配置: 安装依赖(如未安装): pip install celery redis在 settings.py 中添加 Celery 配置(推荐放在文件底部): # Celery 配置 CELERY_BROKER_URL = redis://127.0.0.1…

Postman介绍及使用

Postman 是一个强大的 API 开发、测试和文档化工具&#xff0c;广泛用于开发者、测试人员和 API 设计者。以下是 Postman 的核心使用指南&#xff0c;涵盖基础操作到进阶功能&#xff1a; 一、基础使用 安装与界面 下载&#xff1a;官网下载&#xff08;支持 Windows/macOS/Lin…

Android14音频子系统-ASoC-ALSA之DAPM电源管理子系统

文章目录 概述1&#xff09;codec对象-WM89602&#xff09;ALSA下的kcontrol的构造与使用3&#xff09;ASOC-ALSA下的kcontrol构造与使用1、通用寄存器对象 - kcontrol2、DAPM下的寄存器对象-widget3、如何构造widget&#xff1f;4、抽象对象widget、route与path1&#xff09;r…

如何修改anaconda 创建新虚拟环境的路径(默认是C:\.conda\envs)

参考文章&#xff1a; 如何修改anaconda 创建新虚拟环境的路径(默认是C&#xff1a;\.conda\envs)_anaconda创建环境怎么改路径-CSDN博客

前缀和计算

前缀和 输入一个长度为n的整数序列。接下来再输入m个询问&#xff0c;每个询问输入一对l, r。对于每个询问&#xff0c;输出原序列中从第l个数到第r个数的和。 所用方法和基本原理 前缀和数组的构建&#xff1a; 首先定义了一个方法getPrefixSum来构建前缀和数组。前缀和数组…

BP神经网络支持向量机实现风机故障诊断

BP神经网络&#xff0c;支持向量机等用于风机故障诊断 BP神经网络&#xff0c;支持向量机等用于风机故障诊断/成功算法/bp20111202_FDD.m , 1580 BP神经网络&#xff0c;支持向量机等用于风机故障诊断/成功算法/BP_FDD.m , 6044 BP神经网络&#xff0c;支持向量机等用于风机故…