MapStruct 对象转换工具【DDD 架构】

server/2025/3/1 20:46:37/

文章目录

    • 一、前言
    • 二、对象模型
      • 1. DTO 数据传输对象
      • 2. BO 业务对象
      • 3. PO 持久化对象
      • 4. VO 值对象
    • 三、MapStruct 对象转换
      • 1. 工具介绍
      • 2. 代码演示

一、前言

上篇我们学习了 DDD 架构,从上到下依次是:用户接口层、应用层、领域层和基础层。
那么不同层的实体类是怎么定义的呢?
这些实体类之间又该如何互相转换?
请记住这两个问题。

本篇由你的栈☞
带你一探究竟。

二、对象模型

在软件开发中,DTO、BO、PO、VO 是常见的对象模型,用于在不同的层次和场景中传递和处理数据。

の......咳咳,实际上都是实体类,只是名字叫的花里胡哨,但是为了开发更规范,来?

1. DTO 数据传输对象

官方的回答(它的废话):用于在用户接口层传输数据的对象,避免直接暴露领域模型给外部,减少不必要的数据传输,只传递需要的字段。

说人话:在 Controller 用户接口层,将前端传过来的数据封装为DTO,对应的实体类的名字应为 XXXDTO。

public class UserDTO {private Long id;private String name;private String email;// Getters and Setters
}
@RestController
@RequestMapping("/users")
public class UserController {private UserService userService;// 接收前端传递的 DTO@PostMappingpublic ResponseEntity<String> createUser(@RequestBody UserDTO userDTO) {userService.createUser(userDTO);return ResponseEntity.ok("User created successfully");}
}

2. BO 业务对象

官方的回答(它的废话):封装了业务逻辑的对象,包含与业务相关的状态和行为。

说人话:在 应用层和领域层,将上一层传过来的数据封装为BO,对应的实体类的名字应为 XXXBO。

3. PO 持久化对象

官方的回答(它的废话):与数据库表直接映射的对象,字段与数据库表的列一一对应。

说人话:在DAO 基础层,将上一层传过来的数据封装为PO,对应的实体类的名字应为 XXXPO。

4. VO 值对象

官方的回答(它的废话):用于标识一个不可变的对象,一旦创建就不能修改,通常用于展示数据。

说人话:各层返回的数据都用 VO 包装,对应的实体类的名字应为 XXXVO。

@Service
public class UserService {// 模拟从数据库获取用户信息public UserVO getUserVO(Long userId) {// 假设从数据库查询到用户信息UserPO userPO = new UserPO(1L, "John Doe", "john.doe@example.com");// 将 PO 转换为 VOreturn new UserVO(userPO.getId(), userPO.getName(), userPO.getEmail());}
}
@RestController
@RequestMapping("/users")
public class UserController {private final UserService userService;@Autowiredpublic UserController(UserService userService) {this.userService = userService;}@GetMapping("/{id}")public ResponseEntity<UserVO> getUser(@PathVariable Long id) {UserVO userVO = userService.getUserVO(id);return ResponseEntity.ok(userVO);}
}

三、MapStruct 对象转换

1. 工具介绍

在业务流程进行中,数据想要往下传递,首先得保证数据类型一致,那么不同的实体类之间就需要互相转换,如果不使用 MapStruct,我们的转换方法就是手动复制 DTO 数据到 BO,代码耦合度较高,且编码效率低。

MapStruct 是一个用于 Java Bean 映射的代码生成库。它通过注解自动生成对象转换代码,减少手动编写映射逻辑的工作量。

特点:
① 高效,生成的代码是原生的 Java 方法调用,性能接近手写代码;
② 类型安全,编译时生成代码,避免运行时错误;
③ 易用,通过简单的注解配置,即可实现复杂映射。

2. 代码演示

① 引入依赖

<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>

② 定义源对象和目标对象

//源对象
public class User {private Long id;private String name;private String email;// Getters and Setters
}
//目标对象
public class UserDTO {private Long id;private String name;private String email;// Getters and Setters
}

③ 定义映射接口

使用 @Mapper 注解定义一个映射接口,MapStruct 会自动生成实现类!

import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;@Mapper
public interface UserMapper {// 获取映射器实例UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);// 将 User 对象转换为 UserDTO 对象UserDTO toDTO(User user);// 将 UserDTO 对象转换为 User 对象User toEntity(UserDTO userDTO);
}

④ 使用映射器

public class Main {public static void main(String[] args) {// 创建 User 对象User user = new User();user.setId(1L);user.setName("John Doe");user.setEmail("john.doe@example.com");// 使用映射器将 User 转换为 UserDTOUserDTO userDTO = UserMapper.INSTANCE.toDTO(user);// 打印结果System.out.println(userDTO);}
}

http://www.ppmy.cn/server/171625.html

相关文章

版图自动化连接算法开发 00002 ------ 添加一个中间点实现 Manhattan 方式连接两个给定的坐标点

版图自动化连接算法开发 00002 ------ 添加一个中间点实现 Manhattan 方式连接两个给定的坐标点 引言正文引言 必读文章 ------ 版图自动化连接算法开发 00001 ------ 直接连接两个给定的坐标点 之前,我们实现了两个坐标点之间的直接连接,属于最简单的布线方式,但是对于光…

DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求

DeepSeek 新的 LLM 推理方法 DeepSeek 通过强化学习&#xff08;RL&#xff09;提出了一种创新的改进大规模语言模型&#xff08;LLM&#xff09;推理能力的方法&#xff0c;这在他们最近关于 DeepSeek-R1 的论文中有详细介绍。这项研究代表了在不依赖于大量有监督微调的情况下…

软件高级架构师 - 设计模式

六大原则 1. 单一职责原则 一个类只负责一项职责。 案例 餐厅中的厨师和服务员&#xff1a; 厨师的职责是做饭&#xff0c;服务员的职责是上菜。 如果让厨师同时负责做饭和上菜&#xff0c;会导致职责混乱&#xff0c;效率降低。 2. 开放-封闭原则&#xff08;OCP&#xff09…

Apache Doris 索引的全面剖析与使用指南

搞大数据开发的都知道&#xff0c;想要在海量数据里快速查数据&#xff0c;就像在星图里找一颗特定的星星&#xff0c;贼费劲。不过别慌&#xff0c;数据库索引就是咱们的 “定位神器”&#xff0c;能让查询效率直接起飞&#xff01;就拿 Apache Doris 这个超火的分析型数据库来…

RFID:汽车智能化产线工艺加工的指挥棒

RFID&#xff1a;汽车智能化产线工艺加工的指挥棒 南通某汽车涂装装配现场问题&#xff1a; 目前使用视觉读取二维码的形式&#xff0c;二维码的数据无法重复利用。因为现场有喷漆的工艺&#xff0c;二维码被漆挡住了就无法识别。无法修改数据&#xff0c;所以无法告诉下一道…

Opencv 图像形态学操作

3.1 形态学-腐蚀操作 img cv2.imread(CSDN.png) cv2.imshow(CSDN, img) cv2.waitKey(0) cv2.destroyAllWindows如果腐蚀核的覆盖区域内的所有像素值都满足条件&#xff08;阈值&#xff09;&#xff0c;则中心像素的值保持不变&#xff1b;如果有任何像素值不满足条件&#x…

原子性(Atomicity)和一致性(Consistency)的区别?

原子性&#xff08;Atomicity&#xff09;和一致性&#xff08;Consistency&#xff09;是数据库事务ACID特性中的两个核心概念&#xff0c;虽然它们密切相关&#xff0c;但解决的问题和侧重点完全不同。原子性关注事务的操作完整性&#xff0c;而一致性关注数据的逻辑正确性。…

蓝桥杯 之 填空题-位运算与循环

文章目录 循环握手问题门牌制作-循环小球反弹幸运数艺术与篮球跑步 位运算3个1美丽的2024 位运算 可以关注这个Lowbit(x) 如何判断最低位是否是1&#xff1f; num&1 1就说明num最低位是1 循环 循环 握手问题 握手问题 思路分析&#xff1a; 可以直接计算出来&#xff…