SpringBoot 對(duì)象轉(zhuǎn)換 MapStruct的實(shí)現(xiàn)小結(jié)
1. MapStruct 簡(jiǎn)介與核心概念
1.1 什么是 MapStruct
MapStruct 是一個(gè)基于注解的 Java 對(duì)象映射工具,它通過(guò)在編譯時(shí)生成映射代碼來(lái)實(shí)現(xiàn)對(duì)象之間的轉(zhuǎn)換。與其他映射框架(如 ModelMapper)相比,MapStruct 的主要優(yōu)勢(shì)在于:
- 編譯時(shí)生成代碼:性能接近手寫代碼
- 類型安全:編譯時(shí)檢查映射的正確性
- 零運(yùn)行時(shí)依賴:生成的代碼不依賴 MapStruct
- 豐富的映射功能:支持復(fù)雜映射場(chǎng)景
1.2 核心概念解析
映射器 (Mapper)
- 負(fù)責(zé)對(duì)象轉(zhuǎn)換的核心接口
- 通過(guò)
@Mapper注解標(biāo)識(shí) - 編譯時(shí)生成實(shí)現(xiàn)類
映射方法 (Mapping Method)
- 在映射器接口中定義的具體轉(zhuǎn)換方法
- 支持單個(gè)對(duì)象、集合、Map 等轉(zhuǎn)換
轉(zhuǎn)換規(guī)則 (Mapping Rules)
- 通過(guò)注解配置的屬性映射規(guī)則
- 支持自定義轉(zhuǎn)換邏輯
2. 環(huán)境搭建與基礎(chǔ)配置
2.1 依賴配置
Maven 配置
<properties>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>Gradle 配置
plugins {
id 'java'
}
dependencies {
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
}
compileJava {
options.annotationProcessorPath = configurations.annotationProcessor
}2.2 Spring Boot 集成
@Configuration
public class MapStructConfig {
@Bean
public UserMapper userMapper() {
return Mappers.getMapper(UserMapper.class);
}
}或者使用組件掃描:
@Mapper(componentModel = "spring")
public interface UserMapper {
// 映射方法
}3. 基礎(chǔ)映射功能詳解
3.1 簡(jiǎn)單對(duì)象映射
源對(duì)象和目標(biāo)對(duì)象定義
// 源對(duì)象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String username;
private String email;
private String password;
private LocalDateTime createTime;
private Integer status;
}
// 目標(biāo)對(duì)象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {
private Long id;
private String username;
private String email;
private String createTime;
private String statusDesc;
}基礎(chǔ)映射器
@Mapper(componentModel = "spring")
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
// 基礎(chǔ)映射 - 屬性名相同時(shí)自動(dòng)映射
UserDTO toDTO(User user);
// 反向映射
User toEntity(UserDTO userDTO);
}3.2 屬性名不同的映射
@Mapper(componentModel = "spring")
public interface UserMapper {
@Mapping(source = "username", target = "name")
@Mapping(source = "createTime", target = "registrationDate")
@Mapping(source = "status", target = "userStatus")
UserDTO toDTO(User user);
@Mapping(source = "name", target = "username")
@Mapping(source = "registrationDate", target = "createTime")
@Mapping(source = "userStatus", target = "status")
User toEntity(UserDTO userDTO);
}3.3 類型轉(zhuǎn)換
內(nèi)置類型轉(zhuǎn)換
@Mapper(componentModel = "spring")
public interface UserMapper {
// 自動(dòng)類型轉(zhuǎn)換:LocalDateTime -> String
@Mapping(source = "createTime", target = "createTimeStr")
// 數(shù)字轉(zhuǎn)字符串
@Mapping(source = "status", target = "statusStr")
UserDTO toDTO(User user);
// 使用表達(dá)式進(jìn)行復(fù)雜轉(zhuǎn)換
@Mapping(target = "statusDesc",
expression = "java(convertStatus(user.getStatus()))")
UserDTO toDTOWithExpression(User user);
default String convertStatus(Integer status) {
switch (status) {
case 0: return "禁用";
case 1: return "啟用";
default: return "未知";
}
}
}4. 高級(jí)映射功能
4.1 嵌套對(duì)象映射
復(fù)雜對(duì)象結(jié)構(gòu)
// 地址對(duì)象
@Data
public class Address {
private String province;
private String city;
private String street;
private String zipCode;
}
// 用戶詳情對(duì)象
@Data
public class UserDetail {
private Long id;
private String username;
private Address address;
private List<String> hobbies;
}
// DTO 對(duì)象
@Data
public class UserDetailDTO {
private Long id;
private String username;
private String province;
private String city;
private String street;
private String zipCode;
private String hobbies;
}嵌套映射配置
@Mapper(componentModel = "spring")
public interface UserDetailMapper {
@Mapping(source = "address.province", target = "province")
@Mapping(source = "address.city", target = "city")
@Mapping(source = "address.street", target = "street")
@Mapping(source = "address.zipCode", target = "zipCode")
@Mapping(source = "hobbies", target = "hobbies")
UserDetailDTO toDTO(UserDetail userDetail);
// 反向映射
@Mapping(target = "address.province", source = "province")
@Mapping(target = "address.city", source = "city")
@Mapping(target = "address.street", source = "street")
@Mapping(target = "address.zipCode", source = "zipCode")
UserDetail toEntity(UserDetailDTO dto);
}4.2 集合映射
列表和數(shù)組映射
@Mapper(componentModel = "spring")
public interface UserMapper {
// 列表映射
List<UserDTO> toDTOList(List<User> users);
// 集合映射
Set<UserDTO> toDTOSet(Set<User> users);
// 數(shù)組映射
UserDTO[] toDTOArray(User[] users);
}Map 映射
@Mapper(componentModel = "spring")
public interface UserMapper {
// Map 值映射
@Mapping(source = "value", target = "value")
Map<String, UserDTO> toDTOMap(Map<String, User> userMap);
// Map 鍵值都映射
@MapMapping(keyTargetType = String.class, valueTargetType = UserDTO.class)
Map<String, UserDTO> toDTOFullMap(Map<Long, User> userMap);
}4.3 多源對(duì)象映射
@Data
public class UserBasicInfo {
private String firstName;
private String lastName;
private Integer age;
}
@Data
public class UserContactInfo {
private String email;
private String phone;
private Address address;
}
@Data
public class CompleteUserDTO {
private String fullName;
private Integer age;
private String email;
private String phone;
private String address;
}
@Mapper(componentModel = "spring")
public interface MultiSourceMapper {
@Mapping(target = "fullName", expression = "java(basicInfo.getFirstName() + \" \" + basicInfo.getLastName())")
@Mapping(source = "basicInfo.age", target = "age")
@Mapping(source = "contactInfo.email", target = "email")
@Mapping(source = "contactInfo.phone", target = "phone")
@Mapping(target = "address", expression = "java(formatAddress(contactInfo.getAddress()))")
CompleteUserDTO toCompleteDTO(UserBasicInfo basicInfo, UserContactInfo contactInfo);
default String formatAddress(Address address) {
return address.getProvince() + address.getCity() + address.getStreet();
}
}5. 自定義映射與高級(jí)配置
5.1 自定義映射方法
@Mapper(componentModel = "spring")
public abstract class CustomUserMapper {
// 使用抽象類以便實(shí)現(xiàn)自定義方法
public abstract UserDTO toDTO(User user);
public abstract List<UserDTO> toDTOList(List<User> users);
// 自定義映射邏輯
public UserDTO toCustomDTO(User user) {
if (user == null) {
return null;
}
UserDTO dto = new UserDTO();
dto.setId(user.getId());
dto.setUsername(user.getUsername().toUpperCase()); // 自定義處理
dto.setEmail(user.getEmail());
dto.setCreateTime(formatDateTime(user.getCreateTime()));
return dto;
}
protected String formatDateTime(LocalDateTime dateTime) {
if (dateTime == null) {
return null;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return dateTime.format(formatter);
}
}5.2 使用表達(dá)式和常量
@Mapper(componentModel = "spring")
public interface ExpressionMapper {
// 使用常量
@Mapping(target = "sourceSystem", constant = "WEB_APPLICATION")
// 使用默認(rèn)值
@Mapping(source = "status", target = "status", defaultValue = "1")
// 使用表達(dá)式
@Mapping(target = "createTime",
expression = "java(java.time.LocalDateTime.now())")
@Mapping(target = "fullName",
expression = "java(user.getFirstName() + \" \" + user.getLastName())")
UserDTO toDTO(User user);
// 條件映射
@Mapping(target = "email",
condition = "java(user.getEmail() != null && user.getEmail().contains(\"@\"))")
UserDTO toDTOConditional(User user);
}5.3 繼承映射配置
// 基礎(chǔ)映射配置
@MapperConfig
public interface BaseMapperConfig {
@Mapping(target = "createTime", ignore = true)
@Mapping(target = "updateTime", ignore = true)
User toEntity(UserDTO dto);
}
// 具體映射器繼承配置
@Mapper(componentModel = "spring", config = BaseMapperConfig.class)
public interface UserMapper extends BaseMapperConfig {
// 繼承基礎(chǔ)配置,可以覆蓋或添加新映射
@Mapping(target = "createTime", source = "registrationDate")
@Override
User toEntity(UserDTO dto);
// 新增映射方法
UserDTO toDTO(User user);
}6. Spring Boot 集成實(shí)踐
6.1 配置類定義
@Configuration
@MapperScan(basePackages = "com.example.mapper")
public class MapStructAutoConfiguration {
@Bean
@Primary
public UserMapper userMapper() {
return new UserMapperImpl();
}
@Bean
public ProductMapper productMapper() {
return new ProductMapperImpl();
}
}6.2 服務(wù)層使用
@Service
@Transactional
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
public UserService(UserRepository userRepository, UserMapper userMapper) {
this.userRepository = userRepository;
this.userMapper = userMapper;
}
public UserDTO createUser(UserCreateRequest request) {
User user = userMapper.toEntity(request);
user.setCreateTime(LocalDateTime.now());
user.setStatus(1);
User savedUser = userRepository.save(user);
return userMapper.toDTO(savedUser);
}
public UserDTO getUserById(Long id) {
return userRepository.findById(id)
.map(userMapper::toDTO)
.orElseThrow(() -> new ResourceNotFoundException("用戶不存在"));
}
public Page<UserDTO> getUsers(Pageable pageable) {
Page<User> userPage = userRepository.findAll(pageable);
return userPage.map(userMapper::toDTO);
}
public List<UserDTO> searchUsers(UserSearchCriteria criteria) {
List<User> users = userRepository.findByCriteria(criteria);
return userMapper.toDTOList(users);
}
}6.3 控制器層應(yīng)用
@RestController
@RequestMapping("/api/users")
@Validated
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping
public ResponseEntity<UserDTO> createUser(@Valid @RequestBody UserCreateRequest request) {
UserDTO userDTO = userService.createUser(request);
return ResponseEntity.status(HttpStatus.CREATED).body(userDTO);
}
@GetMapping("/{id}")
public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
UserDTO userDTO = userService.getUserById(id);
return ResponseEntity.ok(userDTO);
}
@GetMapping
public ResponseEntity<Page<UserDTO>> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sort) {
Pageable pageable = PageRequest.of(page, size, Sort.by(sort));
Page<UserDTO> userPage = userService.getUsers(pageable);
return ResponseEntity.ok(userPage);
}
@PutMapping("/{id}")
public ResponseEntity<UserDTO> updateUser(
@PathVariable Long id,
@Valid @RequestBody UserUpdateRequest request) {
UserDTO userDTO = userService.updateUser(id, request);
return ResponseEntity.ok(userDTO);
}
}7. 復(fù)雜業(yè)務(wù)場(chǎng)景實(shí)戰(zhàn)
7.1 訂單系統(tǒng)映射
領(lǐng)域模型
// 訂單實(shí)體
@Data
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String orderNo;
private BigDecimal totalAmount;
private Integer status;
private LocalDateTime createTime;
private LocalDateTime updateTime;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> items;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
// 訂單項(xiàng)實(shí)體
@Data
@Entity
public class OrderItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "order_id")
private Order order;
@ManyToOne
@JoinColumn(name = "product_id")
private Product product;
private Integer quantity;
private BigDecimal price;
private BigDecimal subtotal;
}
// 訂單 DTO
@Data
public class OrderDTO {
private Long id;
private String orderNo;
private BigDecimal totalAmount;
private String statusDesc;
private String createTime;
private String updateTime;
private String customerName;
private String customerEmail;
private List<OrderItemDTO> items;
}
// 訂單項(xiàng) DTO
@Data
public class OrderItemDTO {
private Long productId;
private String productName;
private Integer quantity;
private BigDecimal price;
private BigDecimal subtotal;
}復(fù)雜映射器
@Mapper(componentModel = "spring", uses = {ProductMapper.class})
public interface OrderMapper {
@Mapping(source = "user.username", target = "customerName")
@Mapping(source = "user.email", target = "customerEmail")
@Mapping(target = "statusDesc", expression = "java(convertOrderStatus(order.getStatus()))")
@Mapping(source = "createTime", target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(source = "updateTime", target = "updateTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
OrderDTO toDTO(Order order);
List<OrderDTO> toDTOList(List<Order> orders);
@Mapping(source = "product.id", target = "productId")
@Mapping(source = "product.name", target = "productName")
OrderItemDTO itemToDTO(OrderItem item);
List<OrderItemDTO> itemsToDTO(List<OrderItem> items);
default String convertOrderStatus(Integer status) {
switch (status) {
case 0: return "待支付";
case 1: return "已支付";
case 2: return "已發(fā)貨";
case 3: return "已完成";
case 4: return "已取消";
default: return "未知狀態(tài)";
}
}
// 更新映射 - 只更新非空字段
@Mapping(target = "id", ignore = true)
@Mapping(target = "orderNo", ignore = true)
@Mapping(target = "createTime", ignore = true)
void updateOrderFromDTO(OrderUpdateDTO dto, @MappingTarget Order order);
}7.2 繼承體系映射
繼承結(jié)構(gòu)對(duì)象
// 基礎(chǔ)支付類
@Data
public abstract class Payment {
private Long id;
private BigDecimal amount;
private Integer status;
private LocalDateTime createTime;
}
// 支付寶支付
@Data
@EqualsAndHashCode(callSuper = true)
public class AlipayPayment extends Payment {
private String alipayTradeNo;
private String buyerId;
private String buyerEmail;
}
// 微信支付
@Data
@EqualsAndHashCode(callSuper = true)
public class WechatPayment extends Payment {
private String wechatTradeNo;
private String openId;
private String appId;
}
// 支付 DTO
@Data
public class PaymentDTO {
private Long id;
private BigDecimal amount;
private String statusDesc;
private String createTime;
private String paymentType;
private Map<String, Object> extraInfo;
}繼承映射器
@Mapper(componentModel = "spring")
public interface PaymentMapper {
// 使用子類映射器
AlipayMapper alipayMapper();
WechatMapper wechatMapper();
default PaymentDTO toDTO(Payment payment) {
if (payment instanceof AlipayPayment) {
return alipayMapper.toDTO((AlipayPayment) payment);
} else if (payment instanceof WechatPayment) {
return wechatMapper.toDTO((WechatPayment) payment);
} else {
return baseToDTO(payment);
}
}
@Mapping(target = "paymentType", constant = "BASE")
@Mapping(target = "extraInfo", ignore = true)
PaymentDTO baseToDTO(Payment payment);
List<PaymentDTO> toDTOList(List<Payment> payments);
}
@Mapper(componentModel = "spring")
public interface AlipayMapper {
@Mapping(target = "paymentType", constant = "ALIPAY")
@Mapping(target = "extraInfo", expression = "java(createAlipayExtraInfo(alipayPayment))")
PaymentDTO toDTO(AlipayPayment alipayPayment);
default Map<String, Object> createAlipayExtraInfo(AlipayPayment payment) {
Map<String, Object> extra = new HashMap<>();
extra.put("alipayTradeNo", payment.getAlipayTradeNo());
extra.put("buyerId", payment.getBuyerId());
extra.put("buyerEmail", payment.getBuyerEmail());
return extra;
}
}
@Mapper(componentModel = "spring")
public interface WechatMapper {
@Mapping(target = "paymentType", constant = "WECHAT")
@Mapping(target = "extraInfo", expression = "java(createWechatExtraInfo(wechatPayment))")
PaymentDTO toDTO(WechatPayment wechatPayment);
default Map<String, Object> createWechatExtraInfo(WechatPayment payment) {
Map<String, Object> extra = new HashMap<>();
extra.put("wechatTradeNo", payment.getWechatTradeNo());
extra.put("openId", payment.getOpenId());
extra.put("appId", payment.getAppId());
return extra;
}
}8. 性能優(yōu)化與最佳實(shí)踐
8.1 性能優(yōu)化策略
批量映射優(yōu)化
@Mapper(componentModel = "spring")
public interface OptimizedMapper {
// 使用 @Named 注解優(yōu)化重復(fù)映射
@Named("toUserDTO")
@Mapping(target = "statusDesc", expression = "java(convertStatus(user.getStatus()))")
UserDTO toUserDTO(User user);
// 批量映射使用相同邏輯
List<UserDTO> toUserDTOList(List<User> users);
// 避免在循環(huán)中調(diào)用復(fù)雜邏輯
default List<UserDTO> optimizedToDTOList(List<User> users) {
if (users == null) {
return null;
}
List<UserDTO> list = new ArrayList<>(users.size());
for (User user : users) {
list.add(toUserDTO(user));
}
return list;
}
}懶加載處理
@Mapper(componentModel = "spring")
public interface LazyLoadingMapper {
@Mapping(target = "orderItems", expression = "java(handleLazyItems(order.getItems()))")
OrderDTO toDTO(Order order);
default List<OrderItemDTO> handleLazyItems(List<OrderItem> items) {
// 處理 Hibernate 懶加載
if (items instanceof PersistentCollection && !((PersistentCollection) items).wasInitialized()) {
return Collections.emptyList();
}
return itemsToDTO(items);
}
List<OrderItemDTO> itemsToDTO(List<OrderItem> items);
}8.2 最佳實(shí)踐
配置統(tǒng)一管理
@MapperConfig(
componentModel = "spring",
unmappedTargetPolicy = ReportingPolicy.IGNORE,
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE
)
public interface CentralConfig {
@Mapping(target = "id", ignore = true)
@Mapping(target = "createTime", ignore = true)
@Mapping(target = "updateTime", ignore = true)
void toEntity(Object dto, @MappingTarget Object entity);
}
@Mapper(config = CentralConfig.class)
public interface UserMapper extends CentralConfig {
// 具體映射方法
}錯(cuò)誤處理
@Mapper(componentModel = "spring")
public interface SafeMapper {
default UserDTO safeToDTO(User user) {
try {
return toDTO(user);
} catch (Exception e) {
log.error("對(duì)象轉(zhuǎn)換失敗: {}", user, e);
return createFallbackDTO(user);
}
}
UserDTO toDTO(User user);
default UserDTO createFallbackDTO(User user) {
UserDTO dto = new UserDTO();
if (user != null) {
dto.setId(user.getId());
dto.setUsername("轉(zhuǎn)換失敗");
}
return dto;
}
}9. 測(cè)試策略
9.1 單元測(cè)試
@ExtendWith(MockitoExtension.class)
class UserMapperTest {
@InjectMocks
private UserMapperImpl userMapper;
@Test
void testToDTO() {
// 準(zhǔn)備測(cè)試數(shù)據(jù)
User user = new User();
user.setId(1L);
user.setUsername("testuser");
user.setEmail("test@example.com");
user.setCreateTime(LocalDateTime.now());
user.setStatus(1);
// 執(zhí)行轉(zhuǎn)換
UserDTO dto = userMapper.toDTO(user);
// 驗(yàn)證結(jié)果
assertThat(dto.getId()).isEqualTo(1L);
assertThat(dto.getUsername()).isEqualTo("testuser");
assertThat(dto.getEmail()).isEqualTo("test@example.com");
assertThat(dto.getStatusDesc()).isEqualTo("啟用");
}
@Test
void testToDTOList() {
List<User> users = Arrays.asList(
createUser(1L, "user1"),
createUser(2L, "user2")
);
List<UserDTO> dtos = userMapper.toDTOList(users);
assertThat(dtos).hasSize(2);
assertThat(dtos.get(0).getUsername()).isEqualTo("user1");
assertThat(dtos.get(1).getUsername()).isEqualTo("user2");
}
private User createUser(Long id, String username) {
User user = new User();
user.setId(id);
user.setUsername(username);
user.setEmail(username + "@example.com");
user.setStatus(1);
return user;
}
}9.2 集成測(cè)試
@SpringBootTest
@Transactional
class UserMapperIntegrationTest {
@Autowired
private UserMapper userMapper;
@Autowired
private UserRepository userRepository;
@Test
void testEntityToDTOMapping() {
// 創(chuàng)建并保存實(shí)體
User user = new User();
user.setUsername("integrationuser");
user.setEmail("integration@example.com");
user.setPassword("password");
user.setCreateTime(LocalDateTime.now());
user.setStatus(1);
User savedUser = userRepository.save(user);
// 測(cè)試映射
UserDTO dto = userMapper.toDTO(savedUser);
assertThat(dto.getId()).isNotNull();
assertThat(dto.getUsername()).isEqualTo("integrationuser");
assertThat(dto.getEmail()).isEqualTo("integration@example.com");
}
}10. 常見問(wèn)題與解決方案
10.1 編譯問(wèn)題
問(wèn)題1:映射器實(shí)現(xiàn)類未生成
// 解決方案:檢查注解處理器配置
@Mapper(componentModel = "spring") // 確保使用正確注解
public interface UserMapper {
UserDTO toDTO(User user);
}問(wèn)題2:依賴沖突
<!-- 確保 MapStruct 版本兼容 -->
<properties>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
</properties>10.2 運(yùn)行時(shí)問(wèn)題
問(wèn)題1:空指針異常
@Mapper(componentModel = "spring")
public interface SafeMapper {
// 使用 nullValuePropertyMappingStrategy 避免 NPE
@Mapping(target = "statusDesc",
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_NULL)
UserDTO toDTO(User user);
}問(wèn)題2:循環(huán)依賴
// 使用 @Context 避免循環(huán)依賴
@Mapper(componentModel = "spring")
public interface OrderMapper {
OrderDTO toDTO(Order order, @Context CycleAvoidingMappingContext context);
}
// 循環(huán)依賴上下文
public class CycleAvoidingMappingContext {
private Map<Object, Object> knownInstances = new IdentityHashMap<>();
@SuppressWarnings("unchecked")
public <T> T getMappedInstance(Object source, Class<T> targetType) {
return (T) knownInstances.get(source);
}
public void storeMappedInstance(Object source, Object target) {
knownInstances.put(source, target);
}
}總結(jié)
MapStruct 是一個(gè)功能強(qiáng)大、性能優(yōu)異的對(duì)象映射框架,特別適合在 Spring Boot 項(xiàng)目中使用。通過(guò)本文的詳細(xì)講解,您應(yīng)該已經(jīng)掌握了
- 基礎(chǔ)配置和簡(jiǎn)單映射 - 快速上手基礎(chǔ)功能
- 高級(jí)映射特性 - 處理復(fù)雜業(yè)務(wù)場(chǎng)景
- Spring Boot 集成 - 在實(shí)際項(xiàng)目中的應(yīng)用
- 性能優(yōu)化 - 提升系統(tǒng)性能的最佳實(shí)踐
- 測(cè)試策略 - 保證代碼質(zhì)量的方法
- 問(wèn)題解決 - 應(yīng)對(duì)常見問(wèn)題的方案
到此這篇關(guān)于SpringBoot 對(duì)象轉(zhuǎn)換 MapStruct的實(shí)現(xiàn)小結(jié)的文章就介紹到這了,更多相關(guān)SpringBoot 對(duì)象轉(zhuǎn)換 MapStruct內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot整合MybatisPlus的簡(jiǎn)單教程實(shí)現(xiàn)(簡(jiǎn)單整合)
這篇文章主要介紹了SpringBoot整合MybatisPlus的簡(jiǎn)單教程實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
Spring AOP切點(diǎn)表達(dá)式使用及說(shuō)明
這篇文章主要介紹了Spring AOP切點(diǎn)表達(dá)式使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
淺談兩個(gè)jar包中包含完全相同的包名和類名的加載問(wèn)題
下面小編就為大家?guī)?lái)一篇淺談兩個(gè)jar包中包含完全相同的包名和類名的加載問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
springboot定時(shí)任務(wù)備份mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)示例
為了防止數(shù)據(jù)庫(kù)被清庫(kù)或者誤刪數(shù)據(jù)庫(kù)的情況,所以需要定時(shí)將mysql數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行備份,本文主要介紹了springboot定時(shí)任務(wù)備份mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)示例,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03
SpringBoot與rabbitmq的結(jié)合的示例
這篇文章主要介紹了SpringBoot與rabbitmq的結(jié)合的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03

