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

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. 性能优化

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

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

相关文章:

  • 专做苹果二手手机的网站百度主页
  • 网站维护费一般多少钱网络营销图片素材
  • 宁波高等级公路建设指挥部网站哪个平台视频资源多
  • 怎么做局域网asp网站百度搜索推广优化师工作内容
  • 在pc端网站基础上做移动端英文seo推广
  • 郴州网搜索引擎优化培训班
  • HCIA-IP路由基础
  • 计算机网络-----详解HTTPS协议
  • 7.Spring框架
  • 个人技术文档库构建实践:基于Cursor和GitHub的知识管理系统(含cursor rules)
  • 半导体FAB中的服务器硬件故障监控与预防全方案:从预警到零宕机实战
  • 量学云讲堂王岩江宇龙2025年第58期视频 主课正课系统课+收评
  • CTF Writeup: [强网杯 2019]随便注挑战解析
  • 用 Boost 库解析 .ini 和 .json 文件时的“坑”:注释导致的解析错误与解决方案
  • Linux驱动学习day7
  • 【JAVA】idea中打成jar包后报错错误: 找不到或无法加载主类
  • 鸿蒙系统(HarmonyOS)经典红色风格登录页布局
  • 磁悬浮轴承刚度设计:高速转子的稳定秘诀
  • 优化 ArcPy 脚本性能
  • AI知识库搭建需要的开源技术方案
  • Azure 自动化:所需状态配置 (DSC)
  • 【iSAQB软件架构】架构模式
  • (LeetCode 面试经典 150 题) 122. 买卖股票的最佳时机 II (贪心)
  • C#高级:Winform桌面开发中DataGridView的详解(新)
  • 鸿蒙 GridRow 与 GridCol 组件解析:响应式网格布局指南
  • Wpf中控件作为Binding的源