最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot 對象轉換 MapStruct的實現小結

 更新時間:2026年02月12日 11:26:28   作者:油墨香^_^  
MapStruct是一個基于注解的Java對象映射工具,通過在編譯時生成映射代碼實現高效的對象轉換,下面就來詳細的介紹一下SpringBoot 對象轉換 MapStruct的實現,感興趣的可以了解一下

1. MapStruct 簡介與核心概念

1.1 什么是 MapStruct

MapStruct 是一個基于注解的 Java 對象映射工具,它通過在編譯時生成映射代碼來實現對象之間的轉換。與其他映射框架(如 ModelMapper)相比,MapStruct 的主要優(yōu)勢在于:

  • 編譯時生成代碼:性能接近手寫代碼
  • 類型安全:編譯時檢查映射的正確性
  • 零運行時依賴:生成的代碼不依賴 MapStruct
  • 豐富的映射功能:支持復雜映射場景

1.2 核心概念解析

映射器 (Mapper)

  • 負責對象轉換的核心接口
  • 通過 @Mapper 注解標識
  • 編譯時生成實現類

映射方法 (Mapping Method)

  • 在映射器接口中定義的具體轉換方法
  • 支持單個對象、集合、Map 等轉換

轉換規(guī)則 (Mapping Rules)

  • 通過注解配置的屬性映射規(guī)則
  • 支持自定義轉換邏輯

2. 環(huán)境搭建與基礎配置

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. 基礎映射功能詳解

3.1 簡單對象映射

源對象和目標對象定義

// 源對象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String username;
    private String email;
    private String password;
    private LocalDateTime createTime;
    private Integer status;
}

// 目標對象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {
    private Long id;
    private String username;
    private String email;
    private String createTime;
    private String statusDesc;
}

基礎映射器

@Mapper(componentModel = "spring")
public interface UserMapper {
    
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
    
    // 基礎映射 - 屬性名相同時自動映射
    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 類型轉換

內置類型轉換

@Mapper(componentModel = "spring")
public interface UserMapper {
    
    // 自動類型轉換:LocalDateTime -> String
    @Mapping(source = "createTime", target = "createTimeStr")
    // 數字轉字符串
    @Mapping(source = "status", target = "statusStr")
    UserDTO toDTO(User user);
    
    // 使用表達式進行復雜轉換
    @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. 高級映射功能

4.1 嵌套對象映射

復雜對象結構

// 地址對象
@Data
public class Address {
    private String province;
    private String city;
    private String street;
    private String zipCode;
}

// 用戶詳情對象
@Data
public class UserDetail {
    private Long id;
    private String username;
    private Address address;
    private List<String> hobbies;
}

// DTO 對象
@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 集合映射

列表和數組映射

@Mapper(componentModel = "spring")
public interface UserMapper {
    
    // 列表映射
    List<UserDTO> toDTOList(List<User> users);
    
    // 集合映射
    Set<UserDTO> toDTOSet(Set<User> users);
    
    // 數組映射
    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 多源對象映射

@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. 自定義映射與高級配置

5.1 自定義映射方法

@Mapper(componentModel = "spring")
public abstract class CustomUserMapper {
    
    // 使用抽象類以便實現自定義方法
    
    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 使用表達式和常量

@Mapper(componentModel = "spring")
public interface ExpressionMapper {
    
    // 使用常量
    @Mapping(target = "sourceSystem", constant = "WEB_APPLICATION")
    // 使用默認值
    @Mapping(source = "status", target = "status", defaultValue = "1")
    // 使用表達式
    @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 繼承映射配置

// 基礎映射配置
@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 {
    
    // 繼承基礎配置,可以覆蓋或添加新映射
    @Mapping(target = "createTime", source = "registrationDate")
    @Override
    User toEntity(UserDTO dto);
    
    // 新增映射方法
    UserDTO toDTO(User user);
}

6. Spring Boot 集成實踐

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 服務層使用

@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 控制器層應用

@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. 復雜業(yè)務場景實戰(zhàn)

7.1 訂單系統(tǒng)映射

領域模型

// 訂單實體
@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;
}

// 訂單項實體
@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;
}

// 訂單項 DTO
@Data
public class OrderItemDTO {
    private Long productId;
    private String productName;
    private Integer quantity;
    private BigDecimal price;
    private BigDecimal subtotal;
}

復雜映射器

@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 繼承體系映射

繼承結構對象

// 基礎支付類
@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)化與最佳實踐

8.1 性能優(yōu)化策略

批量映射優(yōu)化

@Mapper(componentModel = "spring")
public interface OptimizedMapper {
    
    // 使用 @Named 注解優(yōu)化重復映射
    @Named("toUserDTO")
    @Mapping(target = "statusDesc", expression = "java(convertStatus(user.getStatus()))")
    UserDTO toUserDTO(User user);
    
    // 批量映射使用相同邏輯
    List<UserDTO> toUserDTOList(List<User> users);
    
    // 避免在循環(huán)中調用復雜邏輯
    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 最佳實踐

配置統(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 {
    // 具體映射方法
}

錯誤處理

@Mapper(componentModel = "spring")
public interface SafeMapper {
    
    default UserDTO safeToDTO(User user) {
        try {
            return toDTO(user);
        } catch (Exception e) {
            log.error("對象轉換失敗: {}", 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("轉換失敗");
        }
        return dto;
    }
}

9. 測試策略

9.1 單元測試

@ExtendWith(MockitoExtension.class)
class UserMapperTest {
    
    @InjectMocks
    private UserMapperImpl userMapper;
    
    @Test
    void testToDTO() {
        // 準備測試數據
        User user = new User();
        user.setId(1L);
        user.setUsername("testuser");
        user.setEmail("test@example.com");
        user.setCreateTime(LocalDateTime.now());
        user.setStatus(1);
        
        // 執(zhí)行轉換
        UserDTO dto = userMapper.toDTO(user);
        
        // 驗證結果
        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 集成測試

@SpringBootTest
@Transactional
class UserMapperIntegrationTest {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private UserRepository userRepository;
    
    @Test
    void testEntityToDTOMapping() {
        // 創(chuàng)建并保存實體
        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);
        
        // 測試映射
        UserDTO dto = userMapper.toDTO(savedUser);
        
        assertThat(dto.getId()).isNotNull();
        assertThat(dto.getUsername()).isEqualTo("integrationuser");
        assertThat(dto.getEmail()).isEqualTo("integration@example.com");
    }
}

10. 常見問題與解決方案

10.1 編譯問題

問題1:映射器實現類未生成

// 解決方案:檢查注解處理器配置
@Mapper(componentModel = "spring") // 確保使用正確注解
public interface UserMapper {
    UserDTO toDTO(User user);
}

問題2:依賴沖突

<!-- 確保 MapStruct 版本兼容 -->
<properties>
    <org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
</properties>

10.2 運行時問題

問題1:空指針異常

@Mapper(componentModel = "spring")
public interface SafeMapper {
    
    // 使用 nullValuePropertyMappingStrategy 避免 NPE
    @Mapping(target = "statusDesc", 
             nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_NULL)
    UserDTO toDTO(User user);
}

問題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);
    }
}

總結

MapStruct 是一個功能強大、性能優(yōu)異的對象映射框架,特別適合在 Spring Boot 項目中使用。通過本文的詳細講解,您應該已經掌握了

  • 基礎配置和簡單映射 - 快速上手基礎功能
  • 高級映射特性 - 處理復雜業(yè)務場景
  • Spring Boot 集成 - 在實際項目中的應用
  • 性能優(yōu)化 - 提升系統(tǒng)性能的最佳實踐
  • 測試策略 - 保證代碼質量的方法
  • 問題解決 - 應對常見問題的方案

到此這篇關于SpringBoot 對象轉換 MapStruct的實現小結的文章就介紹到這了,更多相關SpringBoot 對象轉換 MapStruct內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java實現二分法的完整代碼

    java實現二分法的完整代碼

    這篇文章主要為大家詳細介紹了java實現二分法的完整代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • IntelliJ IDEA窗口組件具體操作方法

    IntelliJ IDEA窗口組件具體操作方法

    IDEA剛接觸不久,各種常用工具窗口找不到,不小心關掉不知道從哪里打開,今天小編給大家分享這個問題的解決方法,感興趣的朋友一起看看吧
    2021-09-09
  • Java實現阿里云短信接口的示例

    Java實現阿里云短信接口的示例

    這篇文章主要介紹了Java實現阿里云短信接口的示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • Java接口和抽象類有什么區(qū)別

    Java接口和抽象類有什么區(qū)別

    這篇文章主要介紹了Java接口和抽象類有什么區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • 淺談一下maven優(yōu)缺點及使用和特點

    淺談一下maven優(yōu)缺點及使用和特點

    這篇文章主要介紹了淺談一下maven優(yōu)缺點及使用和特點,一個項目管理工具軟件,那么maven項目有什么優(yōu)缺點呢,讓我們一起來看看吧
    2023-03-03
  • idea2020導入spring5.1的源碼詳細教程

    idea2020導入spring5.1的源碼詳細教程

    這篇文章主要介紹了idea2020導入spring5.1的源碼的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Freemarker中的3種循環(huán)模式

    Freemarker中的3種循環(huán)模式

    這篇文章主要介紹了Freemarker中的3種循環(huán)模式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Java遞歸遍歷文件目錄代碼實例

    Java遞歸遍歷文件目錄代碼實例

    這篇文章主要介紹了Java遞歸遍歷文件目錄代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • Java如何實現圖片的疊加與拼接操作

    Java如何實現圖片的疊加與拼接操作

    這篇文章主要介紹了Java如何實現圖片的疊加與拼接操作,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • FreeSWITCH跨NAT部署配置詳解

    FreeSWITCH跨NAT部署配置詳解

    這篇文章主要為大家介紹了FreeSWITCH跨NAT部署配置詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02

最新評論

沿河| 和龙市| 财经| 平安县| 夹江县| 蛟河市| 福安市| 汝城县| 桑植县| 会昌县| 涞水县| 法库县| 郓城县| 青阳县| 铜山县| 平乐县| 河北省| 潼关县| 贺兰县| 兴山县| 吉水县| 嵩明县| 鄢陵县| 镇江市| 凯里市| 潮安县| 日照市| 竹北市| 奉节县| 灯塔市| 湘阴县| 内江市| 读书| 临西县| 临桂县| 镇巴县| 洛阳市| 房产| 博乐市| 墨玉县| 泊头市|