MapStruct 是一個基于注解的 Java 對象映射工具,它能夠在編譯時生成類型安全的映射代碼。與傳統的反射機制相比,MapStruct 生成的代碼更加高效,且易于調試。MapStruct 的主要目標是通過減少樣板代碼來提高開發效率。
在 pom.xml
中添加以下依賴:
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
在 build.gradle
中添加以下依賴:
dependencies {
implementation 'org.mapstruct:mapstruct:1.5.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.2.Final'
}
首先,定義一個映射接口,并使用 @Mapper
注解標記:
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(source = "make", target = "manufacturer")
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car);
}
在代碼中使用映射接口進行對象轉換:
Car car = new Car("Toyota", 5);
CarDto carDto = CarMapper.INSTANCE.carToCarDto(car);
如果源對象和目標對象的字段名稱相同,MapStruct 會自動進行映射,無需額外配置。
@Mapper
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
UserDto userToUserDto(User user);
}
如果某些字段的映射邏輯比較復雜,可以定義一個自定義方法:
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(source = "make", target = "manufacturer")
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car);
default String mapEngine(Engine engine) {
return engine.getType() + " " + engine.getHorsepower() + "hp";
}
}
MapStruct 支持從多個源對象映射到一個目標對象:
@Mapper
public interface OrderMapper {
OrderMapper INSTANCE = Mappers.getMapper(OrderMapper.class);
@Mapping(source = "customer.name", target = "customerName")
@Mapping(source = "address.street", target = "street")
OrderDto orderToOrderDto(Order order, Customer customer, Address address);
}
MapStruct 支持集合類型的映射:
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
List<CarDto> carsToCarDtos(List<Car> cars);
}
如果對象中包含嵌套對象,MapStruct 會自動進行遞歸映射:
@Mapper
public interface PersonMapper {
PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
PersonDto personToPersonDto(Person person);
}
MapStruct 支持使用表達式進行映射:
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(target = "fullName", expression = "java(car.getMake() + ' ' + car.getModel())")
CarDto carToCarDto(Car car);
}
可以在映射中使用常量:
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(target = "country", constant = "USA")
CarDto carToCarDto(Car car);
}
可以為目標字段設置默認值:
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(target = "seatCount", defaultValue = "4")
CarDto carToCarDto(Car car);
}
可以根據條件進行映射:
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(target = "seatCount", source = "numberOfSeats", conditionExpression = "java(numberOfSeats > 0)")
CarDto carToCarDto(Car car);
}
可以定義自定義注解來實現復雜的映射邏輯:
@Retention(RetentionPolicy.CLASS)
@Mapping(target = "manufacturer", source = "make")
public @interface CarToDto {
}
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@CarToDto
CarDto carToCarDto(Car car);
}
可以將多個映射器組合在一起使用:
@Mapper(uses = {EngineMapper.class, WheelMapper.class})
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
CarDto carToCarDto(Car car);
}
MapStruct 支持通過依賴注入框架(如 Spring)來管理映射器實例:
@Mapper(componentModel = "spring")
public interface CarMapper {
CarDto carToCarDto(Car car);
}
MapStruct 可以與 Lombok 一起使用,但需要確保 Lombok 在 MapStruct 之前處理:
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
問題描述:在編譯項目時,MapStruct 沒有生成映射器實現類。
解決方案:
- 確保 mapstruct-processor
依賴已正確配置。
- 確保 IDE 中啟用了注解處理器。
問題描述:源對象和目標對象的字段名稱不一致,導致映射失敗。
解決方案:
- 使用 @Mapping
注解顯式指定源字段和目標字段的映射關系。
問題描述:嵌套對象未正確映射。
解決方案:
- 確保嵌套對象的映射器已正確配置。
- 使用 @Mapper(uses = {NestedMapper.class})
來指定嵌套對象的映射器。
問題描述:集合類型的字段未正確映射。
解決方案:
- 確保集合元素的類型已正確映射。
- 使用 @Mapping
注解顯式指定集合元素的映射關系。
問題描述:自定義映射方法未正確調用。
解決方案:
- 確保自定義方法的簽名與映射字段的類型匹配。
- 使用 @Mapping
注解顯式指定自定義方法的調用。
MapStruct 是一個功能強大且高效的 Java 對象映射工具,能夠顯著減少開發中的樣板代碼。通過本文的介紹,您應該已經掌握了 MapStruct 的基本用法和高級特性。在實際開發中,合理使用 MapStruct 可以大大提高代碼的可維護性和開發效率。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。