IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Mapstruc对象转换案例 -> 正文阅读

[Java知识库]Mapstruc对象转换案例

Mapstruc是一款高性能的对象转换工具,就性能而言比Beanutils.copy()要快很多。它对于对象转换的处理是在项目编译的时候基于注解配置生成对应的对象转换代码,并且没有各种繁杂的校验逻辑,运行的时候不需要再通过反射获取对象信息。

配置:

        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.4.2.Final</version>
        </dependency>

        <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source> <!-- depending on your project -->
                    <target>1.8</target> <!-- depending on your project -->
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

实体对象:

public class UserDto {
    private String name;
    private Integer age;
    private Date createTime;
}


public class UserPo {
    private String name;
    private Integer age;
    private Date createTime;
    private String city;
    private String mycountry;
    private Status status;
    public enum Status{
        free,
        busy;
    }
}

public class AddressDTO {
    private String country;
    private String province;
    private String city;
}


public class UserDto1 {
    private String nickname;
    private Integer age;
    // 类型和UserDto不同 ->日期类型可以自动转换
    private String createTime;
}

定义转换器:注解来自org.mapstruct.*,不用导成mybatis的包!!!

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
/**
 * componentModel:设置使用模式
 * spring:可以通过注解注入到spring容器中
 */
@Mapper(componentModel = "spring")
public interface SpringUserMapper{
    // 会自动把两个源对象中的属性复制到目标对象
    @Mapping(source = "userDTO.name",target = "name")
    //将AddressDTO的部分属性赋值到UserPo
    @Mapping(source = "addressDTO.city",target = "city")
    @Mapping(source = "addressDTO.country",target = "mycountry")
    UserPo to(UserDto userDTO, AddressDTO addressDTO);
}

源对象和目标对象属性名称一致时自动映射,不一致时通过@mapping指定属性进行赋值。

属性名称一致,类型不一致时mapstruct对部分数据也做了自动映射。

  • 基本类型及其他们对应的包装类型。
  • 基本类型的包装类型和String类型之间
  • String类型和枚举类型之间

案例:

    @Test
    void moreDataSource(){
        UserDto userDTO = new UserDto("张三",10,new Date());
        AddressDTO addressDTO = new AddressDTO("中国","北京","北京");
        UserPo userPo= springUserMapper.to(userDTO, addressDTO);
        System.out.println(userPo);
    }

---------------------
UserPo{name='张三', age=10, createTime=Tue Mar 22 16:18:44 CST 2022, city='北京', mycountry='中国'}

假设所有人的国家都是【中国】,那么可以通过设置固定值来实现。

//old
@Mapping(source = "addressDTO.country",target = "mycountry")
//new  两种方式都可以看场景选择
@Mapping(target = "mycountry",constant = "中国")

忽略字段:赋值时指定字段不做映射

@Mapping(target = "createTime",ignore = true)

日期转字符串:

@Mapping(source="createTime",target = "createTime",dateFormat = "yyyy-MM-dd hh:mm:ss")

对象互转:A转B->B转A

@Mapper(componentModel="spring")
public interface UserMapper{
    @Mappings({
        @Mapping(source="name",target = "nickname"),
        @Mapping(source="createTime",target = "createTime",dateFormat = "yyyy-MM-dd hh:mm:ss")
    })
    UserDto1 to(UserDto userDto);

    @InheritInverseConfiguration(name = "to")
    UserDto from(UserDto1 dto1);
}


    @Test
    void reverse(){
        UserDto userDto = new UserDto("zhangsan",27,new Date());
        UserDto1 to = userMapper.to(userDto);
        System.out.println(to);
        UserDto form = userMapper.from(to);
        System.out.println(form);
    }

UserDto1{ nickname='zhangsan', age=27, createTime='2022-03-22 04:52:42'}
UserDto{name='zhangsan', age=27, createTime=Tue Mar 22 04:52:42 CST 2022}

通用父类:抽取通用的方法定义至父类,直接继承使用

public interface BaseMapper<SOURCE, TARGET> {
    TARGET to(SOURCE var1);

    List<TARGET> to(List<SOURCE> var1);


    SOURCE from(TARGET var1);

    List<SOURCE> from(List<TARGET> var1);
}

@Mapper(componentModel="spring")
public interface User1Mapper extends BaseMapper<UserDto, UserDto1> {
    
    //存在定制属性时通过重写实现自己的需求
    @Mappings({
            @Mapping(source = "createTime",target = "createTime",dateFormat = "yyyyMMdd"),
            @Mapping(source = "name",target = "nickname")
    })
    @Override
    UserDto1 to(UserDto var1);
}

    @Test
    void testlist(){
        UserDto userDTO = new UserDto("张三",10,new Date());
        //时间转字符串
        UserDto1 userDto1= user1Mapper.to(userDTO);
        System.out.println(userDto1);
        List<UserDto> userDTOS = new ArrayList<UserDto>(){{add(userDTO);}};
        //***集合转集合 ->  user1Mapper中并没有集合转换的方法,使用继承自父类BaseMapper的方法
        List<UserDto1> userDto1s = user1Mapper.to(userDTOS);
        System.out.println(userDto1s);
    }
-----------------------------------------------------------------
UserDto1{ nickname='张三', age=10, createTime='20220322'}
[UserDto1{ nickname='张三', age=10, createTime='20220322'}]

对象转字符串:person中存在Homeaddress对象,但是personDto存储的地址是String可通过@mapping中的expression来实现转换

public class PersonDO {
    private Integer id;
    private String name;
    private int age;
    private Date birthday;
    private String gender;
    private String address;
}
public class PersonDTO {
    private String userName;
    private Integer age;
    private Date birthday;
    private Gender gender;
    private HomeAddress address;
}
public class HomeAddress {
    private String city;
    private String street;
}

@Mapper(componentModel="spring")
public interface PersonConverter {
    @Mapping(source = "name", target = "userName")
    @Mapping(target = "address",expression = "java(stringToHomeAddress(person.getAddress()))")
    PersonDTO do2dto(PersonDO person);
    default HomeAddress stringToHomeAddress(String address){
        //JSON.parseObject(address,HomeAddress.class)
        String[] split = address.split("-");
        HomeAddress homeAddress = new HomeAddress(split[0],split[1]);
        return homeAddress;
    }

    @Mapping(source = "userName", target = "name")
    @Mapping(target = "address",expression = "java(homeAddressToString(dto2do.getAddress()))")
    PersonDO dto2do(PersonDTO dto2do);
    default String homeAddressToString(HomeAddress address){
        //JSON.toJSONString(address);
        return address.getCity()+"-"+address.getStreet();
    }
}

    @Test
    void test(){
        HomeAddress homeAddress = new HomeAddress("shanghai","jutailu");
        PersonDTO personDTO = new PersonDTO("chensan",20,new Date(),PersonDTO.Gender.MALE,homeAddress);
        PersonDO personDO = personConverter.dto2do(personDTO);
        System.out.println(personDO);
        PersonDTO personDTO1 = personConverter.do2dto(personDO);
        System.err.println(personDTO1);
    }
--------------------------------------------------------------
PersonDTO{userName='chensan', age=20, birthday=Tue Mar 22 17:16:30 CST 2022, gender=MALE, address=HomeAddress{city='shanghai', street='jutailu'}}
PersonDO{id=null, name='chensan', age=20, birthday=Tue Mar 22 17:16:30 CST 2022, gender='MALE', address='shanghai-jutailu'}

更新bean映射:有些情况下不需要映射转换产生新的bean,而是更新已有的bean。

    @Mapping(source = "name", target = "nickname")     
    void updateDTOFromDto1(UserDto userDto, @MappingTarget UserDto1 dto);

Map映射:map的值转换成指定格式的字符串

    @MapMapping(valueDateFormat = "dd.MM.yyyy")     
    Map<String, String> longDateMapToStringStringMap(Map<Long, Date> source);

默认值设置

 @Mapping(target = "longProperty", source = "longProp", defaultValue = "-1")     

装饰器自定义映射:

在某些情况下,可能需要自定义生成的映射方法,例如在目标对象中设置无法由生成的方法实现设置的附加属性。

实现起来也很简单,用装饰器模式实现映射器的一个抽象类,在映射器Mapper中添加注解@DecoratedWith指向装饰器类,使用时还是正常调用。


@Mapper 
@DecoratedWith(CarMapperDecorator.class) 
public interface CarMapper {     
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);     

    @Mapping(source = "numberOfSeats", target = "seatCount")     
    CarDTO CarToCarDTO(Car car); 
}

public abstract class CarMapperDecorator implements CarMapper {     
    private final CarMapper delegate;     
    protected CarMapperDecorator(CarMapper delegate) {         
        this.delegate = delegate;     
    }     
    @Override     
    public CarDTO CarToCarDTO(Car car) {         
        CarDTO dto = delegate.CarToCarDTO(car);         
        dto.setMakeInfo(car.getMake() + " " + new SimpleDateFormat( "yyyy-MM-dd" ).format(car.getCreateDate()));         
        return dto;     
    } 
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:21:19  更:2022-03-24 00:22:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:45:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码