mapstruct的官方网站链接https://mapstruct.org/
idea有mapstruct插件,可以安装下
快速开始
引入pom依赖
我的项目使用了lombok,将lombok和mapstruct配合使用。
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
创建entity和dto
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Car {
private String make;
private Integer numberOfSeats;
private Integer type;
}
@Data
public class CarDto {
private String make;
private int seatCount;
private String type;
}
声明mapper接口
转换规则
- 字段类型和名称一致,无需映射
- 名称不一致需要映射
名称一致类型不一致的情况需要看下mapstruct支不支持,不支持需要自定义转换器
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car);
}
执行转换
public class CarTest {
@Test
public void test_converter() {
//given
Car car = new Car("Morris", 5, 10);
//when
CarDto carDto = CarMapper.INSTANCE.carToCarDto(car);
//then
System.out.println(carDto.getMake());
System.out.println(carDto.getSeatCount());
System.out.println(carDto.getType());
}
}
结合DDD
dto和entity转换
```java public interface Assembler
{ /** - 将entity转为dto *
- @param entity 领域实体
@return dto */ Dto convertToDto(Entity entity);
/**
- 将dto转为entity *
- @param dto 数据传输对象
- @return 领域实体 */ Entity convertToEntity(Dto dto); }
@Mapper(uses = DateMapper.class)
public interface DictDetailAssembler extends Assembler
@Mappings({@Mapping(source = "id", target = "seqNo"),
@Mapping(source = "dictName", target = "name"),
@Mapping(source = "dictType", target = "type"),
@Mapping(source = "createTime", target = "createTime")})
DictDetailItem convertToDto(DictDetail dictDetail);
@Mappings({@Mapping(source = "seqNo", target = "id"),
@Mapping(source = "name", target = "dictName"),
@Mapping(source = "type", target = "dictType")})
DictDetail convertToEntity(DictDetailItem dictDetailItem);
}
<a name="fAXE8"></a>
## DO和entity转换
```java
public interface Converter<DO, Entity> {
/**
* 将entity转为DO
*
* @param entity 领域实体
* @return dto
*/
DO convertToDO(Entity entity);
/**
* 将DO转为entity
*
* @param Do 数据库传输对象
* @return 领域实体
*/
Entity convertToEntity(DO Do);
}
@Mapper
public interface DictDetailConverter extends Converter<DictDetailDO, DictDetail> {
DictDetailConverter INSTANCE = Mappers.getMapper(DictDetailConverter.class);
DictDetailDO convertToDO(DictDetail dictDetail);
DictDetail convertToEntity(DictDetailDO dictDetailDO);
}
自定义转换器
比如有个entity的createTime是timetamp类型的,dto的createTime是string类型的,直接映射会报错的
添加转换器
public class DateMapper {
public String asString(Date date) {
return date != null ? new SimpleDateFormat(QmsConstant.YYYYMMDDHHMMSS)
.format(date) : null;
}
public Date asDate(String date) {
try {
return date != null ? new SimpleDateFormat(QmsConstant.YYYYMMDDHHMMSS)
.parse(date) : null;
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
mapper声明转换器
uses是数组可以声明多个
@Mapper(uses = DateMapper.class)