简化 Java bean 类型之间映射
学习视频链接:https://www.bilibili.com/video/BV1E5411n7HR?from=search&seid=9468054775434592661&spm_id_from=333.337.0.0
目录
1 使用
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.1.Final</version>
</dependency>
...
<properties>
<org.mapstruct.version>1.4.2.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.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
...
可以创建interface或者abstract class
package com.example.demo.mapper;
import com.example.demo.pojo.User;
import com.example.demo.pojo.UserRoleDto;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
/**
* @Author gett
* @Date 2021/12/28 10:33
* @Description MapStruct对象属性转换接口
*/
@Mapper
public interface UserRoleMapper {
//ClassLoader 加载方式
UserRoleMapper INSTANCE=Mappers.getMapper(UserRoleMapper.class);
@Mappings({
@Mapping(source = "id", target = "id"),
@Mapping(source = "username", target = "username"),
@Mapping(source = "role.roleName", target = "roleName")
})
UserRoleDto toUserRoleDto(User user);
}
package com.example.demo.mapper;
import com.example.demo.pojo.User;
import com.example.demo.pojo.UserRoleDto;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @Author gett
* @Date 2021/12/28 10:33
* @Description MapStruct对象属性转换接口
*/
@Mapper
public abstract class UserRoleMapper {
//ClassLoader 加载方式
public static UserRoleMapper INSTANCE=Mappers.getMapper(UserRoleMapper.class);
public abstract UserRoleDto toUserRoleDto(User user);
}
2 @Mapper
- 同类型且同名的属性会自动映射
- MapStruct会自动类型转换
- 8种基本类型和他们对应的包装类型之间
- 8种基本类型(包括他们的包装类型)和string之间
- 日期类型和string之间
3 @Mappings与@Mapping
- 指定属性之间的映射关系
- 日期格式化:dateFormat = "yyyy-MM-dd HH:mm:ss"
- 数字格式化:numberFormat = "#.00"
- source或target多余的属性对方没有,不会报错
- ignore
- 引用对象的映射处理
- 批量映射
4 @MappingTarget和@AfterMapping
在映射最后一步对属性的自定义映射处理
@MappingTarget:表明传来的对象是已经赋过值的
@AfterMapping:表示让MapStruct在调用完自动转换的方法之后,会来自动调用本方法
package com.example.demo.mapper;
import com.example.demo.pojo.*;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import org.springframework.util.StringUtils;
/**
* @Author gett
* @Date 2021/12/28 10:33
* @Description MapStruct对象属性转换接口
*/
@Mapper
public abstract class UserRoleMapper {
//ClassLoader 加载方式
public static UserRoleMapper INSTANCE=Mappers.getMapper(UserRoleMapper.class);
public abstract UserRoleDto toUserRoleDto(User user);
@AfterMapping
//表示让MapStruct在调用完自动转换的方法之后,会来自动调用本方法
void after(User user, @MappingTarget UserRoleDto userRoleDto) {
//@MappingTarget:表明传来的对象是已经赋过值的
String username = user.getUsername();
if (username != null && !StringUtils.isEmpty(username)){
userRoleDto.setRoleName(username);
}
}
}
5 批量转换
package com.example.demo.mapper;
import com.example.demo.pojo.*;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* @Author gett
* @Date 2021/12/28 10:33
* @Description MapStruct对象属性转换接口
*/
@Mapper
public abstract class UserRoleMapper {
//ClassLoader 加载方式
public static UserRoleMapper INSTANCE=Mappers.getMapper(UserRoleMapper.class);
//集合批量转换
public abstract List<UserRoleDto> toListDto(List<User> user);
}
package com.example.demo.test;
import com.example.demo.mapper.UserRoleMapper;
import com.example.demo.pojo.Role;
import com.example.demo.pojo.User;
import com.example.demo.pojo.UserRoleDto;
import java.util.ArrayList;
import java.util.List;
/**
* @Author gett
* @Date 2021/12/28 10:23
* @Description 测试类
*/
public class Test {
public static void main(String[] args) {
Role role = new Role(2L, "administrator", "用户");
User user1 = new User(1001L,"张三","123456","15222222222","[email protected]",role);
User user2 = new User(1002L,"李四","123456","15222222222","[email protected]",role);
User user3 = new User(1003L,"王五","123456","15222222222","[email protected]",role);
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
List<UserRoleDto> dto = UserRoleMapper.INSTANCE.toListDto(users);
System.out.println(dto);
}
}
6 @BeanMapping
ignoreByDefault :忽略MapStruct的默认映射行为。只映射那些@Mapping设置了的属性避免不需要的赋值、避免属性覆盖
@BeanMapping(ignoreByDefault = true)
@Mapping(source = "id", target = "id")
public abstract Ids toIds(User user);
Role role = new Role(2L, "administrator", "用户");
User user1 = new User(1001L,"张三","123456","15222222222","[email protected]",role);
Ids ids = UserRoleMapper.INSTANCE.toIds(user1);
System.out.println("---"+ids);
输出:---Ids(id=1001, username=null)
7 @InheritConfiguration
更新的场景
@BeanMapping(ignoreByDefault = true)
@Mapping(source = "id", target = "id")
@Mapping(source = "username", target = "username")
public abstract Ids toIds(User user);
@InheritConfiguration
@Mapping(target = "id", ignore = true)
public abstract void toUpdate(User user, @MappingTarget Ids Ids) ;
package com.example.demo.test;
import com.example.demo.mapper.UserRoleMapper;
import com.example.demo.pojo.Ids;
import com.example.demo.pojo.Role;
import com.example.demo.pojo.User;
import com.example.demo.pojo.UserRoleDto;
import java.util.ArrayList;
import java.util.List;
/**
* @Author gett
* @Date 2021/12/28 10:23
* @Description 测试类
*/
public class Test {
public static void main(String[] args) {
Role role = new Role(2L, "administrator", "用户");
User user1 = new User(1001L,"zhangsan","123456","null","[email protected]",role);
Ids ids = UserRoleMapper.INSTANCE.toIds(user1);
System.out.println(ids);
User user2 = new User();
user2.setUsername("lisi");
System.out.println(user2);
//通过user2的属性来更新已经存在的对象
UserRoleMapper.INSTANCE.toUpdate(user2,ids);
System.out.println(ids);
}
}
输出:
Ids(id=1001, username=zhangsan, phoneNum=null)
User(id=null, username=lisi, password=null, phoneNum=null, email=null, role=null)
Ids(id=1001, username=lisi, phoneNum=null)
8 @InheritInverseConfiguration
反向映射。只继承@Mapping注解配置,不会继承@BeanMapping
name:指定使用哪一个方法的配置,写方法的名字
@BeanMapping(ignoreByDefault = true)
@Mapping(source = "id", target = "id")
@Mapping(source = "username", target = "username")
public abstract Ids toIds(User user);
@BeanMapping(ignoreByDefault = true)
@InheritInverseConfiguration(name = "toIds")
public abstract User inverse(Ids ids);
package com.example.demo.test;
import com.example.demo.mapper.UserRoleMapper;
import com.example.demo.pojo.Ids;
import com.example.demo.pojo.Role;
import com.example.demo.pojo.User;
import com.example.demo.pojo.UserRoleDto;
import java.util.ArrayList;
import java.util.List;
/**
* @Author gett
* @Date 2021/12/28 10:23
* @Description 测试类
*/
public class Test {
public static void main(String[] args) {
Ids ids = new Ids(1001L,"zhangsan","15222222222");
System.out.println(ids);
User user = UserRoleMapper.INSTANCE.inverse(ids);
System.out.println(user);
}
}
输出:
Ids(id=1001, username=zhangsan, phoneNum=15222222222)
User(id=1001, username=zhangsan, password=null, phoneNum=null, email=null, role=null)
mapper层
@Component
@Mapper
public abstract class UserRoleMapper {
//ClassLoader 加载方式
public static UserRoleMapper INSTANCE=Mappers.getMapper(UserRoleMapper.class);
}
controller层
@Resource
private UserRoleMapper userRoleMapper;