mapstruct-plus/docs/guide/annotations.md
linpeilie d78923e327 - 更新docs,添加部分用例
- 增加Lombok适配用例
- 修复map转换的一个问题
2023-02-26 13:25:13 +08:00

318 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 注解
order: 5
---
# 注解
## @AutoMapper
`@AutoMapper` 定义**标识需要生成类转换接口**
需要在实体类上面定义
### **`target`**
- 类型:`Class<?>`
**指定需要转换的目标类**
**该属性表明会生成被注解的类,转换为目标类的接口**
示例::
如下配置,默认会生成 `Car` 转为 `CarDto` 的逻辑,如果没有配置 `CarDto``Car`
细节的话,还会根据默认的规则,生成相反的转换逻辑。具体细节,参考[转换接口生成约定](/guide/mapper-generate-appoint)
```java
@AutoMapper(target = CarDto.class)
public class Car {
// ...
}
```
### `uses`
- 类型:`Class<?>[]`
**使用自定义类转换器**
**该属性可以将自定义映射器,传递给生成的转换接口使用。常用于在进行一些属性转换时,针对一些特定目标类型进行自定义的映射**
示例场景:
项目中会有字符串用 `,` 分隔,在一些类中,需要根据逗号拆分为字符串集合。针对于这种场景,可以有两种方式:首先可以指定字段映射时的表达式,但需要对每种该情况的字段,都添加表达式,复杂且容易出错。
第二,就可以自定义一个类型转换器,通过 `uses` 来使用
```java
public interface StringToListString {
default List<String> stringToListString(String str) {
return StrUtil.split(str);
}
}
@AutoMapper(target = User.class, uses = StringToListStringConverter.class)
public class UserDto {
private String username;
private int age;
private boolean young;
@AutoMapping(target = "educationList")
private String educations;
// ......
}
```
测试:
```java
@SpringBootTest
public class QuickStartTest {
@Autowired
private Converter converter;
@Test
public void ueseTest() {
UserDto userDto = new UserDto();
userDto.setEducations("1,2,3");
final User user = converter.convert(userDto, User.class);
System.out.println(user.getEducationList()); // [1, 2, 3]
assert user.getEducationList().size() == 3;
}
}
```
## @AutoMappers
`@AutoMappers` 定义标识需要生成多个类的转换接口
需要在实体类上面定义
当同时需要转换多个类时,不同类之间的属性配置,需要结合 `@AutoMappings` 来使用
例如,如下配置,同时会生成 `User <---> UserDto``User <---> UserVO` 之间的映射
```java
@AutoMappers({
@AutoMapper(target = UserDto.class),
@AutoMapper(target = UserVO.class)
})
public class User {
// ...
}
```
## @AutoMapMapper
`@AutoMapMapper` 标识需要生成 `Map<String, Object>` 转为当前对象的转换接口
需要在实体类上定义
其中,`value` 支持的类型如下:
- String
- BigDecimal
- BigInteger
- Integer
- Long
- Double
- Number
- Boolean
- Date
- LocalDateTime
- LocalDate
- LocalTime
- URI
- URL
- Calendar
- Currency
- 自定义类(自定义类也需要增加 `@AutoMapMapper` 注解)
其中,类型的转换,交由 [hutool](https://hutool.cn) 包中的 `Convert` 接口实现,如果要转换的类已经是目标类型,则直接执行强转,否则,根据类型进行一定的适配转换。
例如:
定义两个对象,`MapModelA``MapModelB`
- `MapModelA`
```java
@AutoMapMapper
@Data
public class MapModelA {
private String str;
private int i1;
private Long l2;
private MapModelB mapModelB;
}
```
- `MapModelB`
```java
@AutoMapMapper
@Data
public class MapModelB {
private Date date;
}
```
测试:
```java
@SpringBootTest
public class QuickStartTest {
@Autowired
private Converter converter;
@Test
public void test() {
Map<String, Object> mapModel1 = new HashMap<>();
mapModel1.put("str", "1jkf1ijkj3f");
mapModel1.put("i1", 111);
mapModel1.put("l2", 11231);
Map<String, Object> mapModel2 = new HashMap<>();
mapModel2.put("date", DateUtil.parse("2023-02-23 01:03:23"));
mapModel1.put("mapModelB", mapModel2);
final MapModelA mapModelA = converter.convert(mapModel1, MapModelA.class);
System.out.println(mapModelA); // MapModelA(str=1jkf1ijkj3f, i1=111, l2=11231, mapModelB=MapModelB(date=2023-02-23 01:03:23))
}
}
```
## @AutoMapping
`@AutoMapping` 用于**字段**上面,**配置特定属性映射时的规则**,该注解会在生成时,转换为 Mapstruct 中的 `@Mapping` 注解
### `targetClass`
**应用于的目标类**
用于多类转换时,区分当前规则,只应用于哪个类型之间的转换。
当指定了多个类转换时,如果该注解没有配置 `targetClass`,则当前配置的规则应用于所有的类型转换中。
例如:
```java
@AutoMappers({
@AutoMapper(target = UserDto.class),
@AutoMapper(target = UserVO.class)
})
public class User {
@AutoMapping(targetClass = UserDto.class, target = "educations", expression = "java(java.lang.String.join(\",\", source.getEducationList()))")
private List<String> educationList;
@AutoMappings({
@AutoMapping(targetClass = UserDto.class, target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss"),
@AutoMapping(targetClass = UserVO.class, target = "birthday", ignore = true)
})
private Date birthday;
@AutoMapping(target = "money", numberFormat = "$0.00")
private double money;
}
```
### `target`
- 类型:`String`
**目标字段,指定该注解的配置,应用于目标类中的哪个字段**
示例:
```java
@AutoMapper(target = Goods.class)
public class GoodsDto {
@AutoMapping(target = "price", numberFormat = "$#.00")
private int price;
// ...
}
```
### dateFormat
- 类型:`String`
**在字段映射时,进行时间格式化,应用于 Date 类型转为 String 类型**
例如:
```java
@AutoMapper(target = Goods.class)
public class GoodsDto {
@AutoMapping(target = "takeDownTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date takeDownTime;
}
```
### numberFormat
- 类型:`String`
**在字段映射时,进行数字格式化,应用于数字类型转换为 String 类型,可以指定 `java.text.DecimalFormat` 所支持的格式化字符串**
例如:
```java
@AutoMapper(target = Goods.class)
public class GoodsDto {
@AutoMapping(target = "price", numberFormat = "$#.00")
private int price;
}
```
### expression
- 类型:`String`
**类型,这个比较强大,其字符串实际上是一行可执行的 Java 代码,需要写在 `java()` 括号内**
例如,用该属性,实现前面的列表转字符串:
```java
@AutoMapper(target = UserDto.class)
public class User {
@AutoMapping(target = "educations", expression = "java(java.lang.String.join(\",\", source.getEducationList()))")
private List<String> educationList;
}
```
## @AutoMappings
`@AutoMappings` 定义该字段在不同类之间的转换规则,一般和 `@AutoMappers` 结合使用。
例如:
下面的配置,当 `User` to `UserDto` 时,需要进行时间格式化转换;当 `User` to `UserVO` 时,忽略该字段。
```java
@AutoMappers({
@AutoMapper(target = UserDto.class),
@AutoMapper(target = UserVO.class)
})
public class User {
@AutoMappings({
@AutoMapping(targetClass = UserDto.class, target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss"),
@AutoMapping(targetClass = UserVO.class, target = "birthday", ignore = true)
})
private Date birthday;
}
```