美文网首页
Java对象转换框架(selma、mapstruct)

Java对象转换框架(selma、mapstruct)

作者: TinyThing | 来源:发表于2020-12-25 14:14 被阅读0次

    0x0 背景

    项目中经常会进行对象转换,以往常使用Spring框架的BeanUtils,但是这个工具基于反射,性能较差;因此有些通过编译时生成转换类的工具出现了,例如:Selma和mapstruct等。

    0x1 Selma教程

    官网:http://www.selma-java.org/
    maven依赖:

            <!-- scope provided because the processor is only needed at compile time-->
            <dependency>
                <groupId>fr.xebia.extras</groupId>
                <artifactId>selma-processor</artifactId>
                <version>1.0</version>
                <scope>provided</scope>
            </dependency>
    
            <!-- This is the only real dependency you will have in your binaries -->
            <dependency>
                <groupId>fr.xebia.extras</groupId>
                <artifactId>selma</artifactId>
                <version>1.0</version>
            </dependency>
    
    

    使用demo:

    //定义一个pojo类User
    @Data
    @Accessors(chain = true)
    public class User {
        private Long id;
        private String username;
        private Integer age;
        private String address;
        private String email;
    }
    
    //定义对应的dto,注意,二者有个别字段不同
    @Data
    public class UserDto {
        private Long id;
        private String username;
        private Integer age;
        private String address;
        private String nickname;
    }
    

    定义一个工具类接口
    注意这里的IgnoreMissing.ALL是指忽略转换时不一致的字段
    例如user有email,而userDto没有该字段

    @Mapper(withIgnoreMissing = IgnoreMissing.ALL)
    public interface ConvertUtils {
        ConvertUtils INSTANCE = Selma.builder(ConvertUtils.class).build();
    
        UserDto convertToUserDto(User user);
        User convertToUser(UserDto userDto);
    }
    

    接下来编译后会发现,selma帮我们生成了一个实现类,如下:

    
    public final class ConvertUtilsSelmaGeneratedClass implements ConvertUtils {
        public final UserDto convertToUserDto(User inUser) {
            UserDto out = null;
            if (inUser != null) {
                out = new UserDto();
                out.setAddress(inUser.getAddress());
                out.setAge(inUser.getAge());
                out.setId(inUser.getId());
                out.setUsername(inUser.getUsername());
            }
    
            return out;
        }
    
        public final User convertToUser(UserDto inUserDto) {
            User out = null;
            if (inUserDto != null) {
                out = new User();
                out.setAddress(inUserDto.getAddress());
                out.setAge(inUserDto.getAge());
                out.setId(inUserDto.getId());
                out.setUsername(inUserDto.getUsername());
            }
    
            return out;
        }
    
        public ConvertUtilsSelmaGeneratedClass() {
        }
    }
    

    使用方法:

        public static void main(String[] args) {
            User user = new User().setUsername("AAA")
                    .setId(3423423L)
                    .setAge(23)
                    .setEmail("sdfsdf@qew.com")
                    .setAddress("asdfasdfasdfasd");
    
            UserDto userDto = ConvertUtils.INSTANCE.convertToUserDto(user);
            System.out.println(userDto);
    
            System.out.println(ConvertUtils.INSTANCE.convertToUser(userDto));
        }
    

    对于某些字段需要转换的情况,可以使用类似如下的注解:

        @Maps(withCustomFields = {
                @Field({"Proposal.passenger.age", "ProposalDto.passengerAge"}), 
                @Field({"passenger.card", "passengerCard"}),
                @Field({"Proposal.passenger.date", "ProposalDto.passengerDate"})
        })
        ProposalDto asProposalDto(Proposal proposal);
    

    0x3 MapStruct教程

    同selma类似,maven依赖如下:

            <org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
    
    
            <!-- mapstruct -->
            <dependency>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct</artifactId>
                <version>${org.mapstruct.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${org.mapstruct.version}</version>
                <!-- IntelliJ does not pick up the processor if it is not in the dependencies.
                 There is already an open issue for IntelliJ see https://youtrack.jetbrains.com/issue/IDEA-150621
                -->
                <scope>provided</scope>
            </dependency>
    

    和selma相同,mapstruct需要定义一个接口:

    @Mapper
    public interface MapStructConverter {
    
        MapStructConverter MAPPER = Mappers.getMapper(MapStructConverter.class);
    
        UserDto convertToUserDto(User user);
        User convertToUser(UserDto userDto);
    }
    
    

    编译后,会生成一个实现类,如下:

    public class MapStructConverterImpl implements MapStructConverter {
        public MapStructConverterImpl() {
        }
    
        public UserDto convertToUserDto(User user) {
            if (user == null) {
                return null;
            } else {
                UserDto userDto = new UserDto();
                userDto.setId(user.getId());
                userDto.setUsername(user.getUsername());
                userDto.setAge(user.getAge());
                userDto.setAddress(user.getAddress());
                return userDto;
            }
        }
    
        public User convertToUser(UserDto userDto) {
            if (userDto == null) {
                return null;
            } else {
                User user = new User();
                user.setId(userDto.getId());
                user.setUsername(userDto.getUsername());
                user.setAge(userDto.getAge());
                user.setAddress(userDto.getAddress());
                return user;
            }
        }
    }
    

    类似的,如果需要自定义字段映射,采用如下方法:

        @Mapping(source = "orders", target = "orderItems")
        @Mapping(source = "customerName", target = "name")
        Customer toCustomer(CustomerDto customerDto);
    

    相关文章

      网友评论

          本文标题:Java对象转换框架(selma、mapstruct)

          本文链接:https://www.haomeiwen.com/subject/tdobnktx.html