使用MapStruct处理javabean之间的转换

项目中经常会遇到javabean之间的转换,比如entity转成vo用于前端展示,原始代码中常常是一堆entity的getter,与vo的setter的堆砌,当映射很多时就会发现既不优雅还很繁琐。
MapStruct就是解决转换问题的一个java工具。

MapStruct的maven配置

  • 今年10月出的1.2.0.Final版本中特性说明,这两点感觉对本人是最实用的

MapStruct can be used with Lombok out of the box
Java 8 Stream support

  • maven配置
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.2.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.2.0.Final</version>
        </dependency>

MapStruct使用

这边来写一个列子来感受下MapStruct是如何使用的。

entity

@Data
public class UserEntity {
    private String name;
    private String password;
    private Integer age;
    private Date birthday;
    private String sex;
}

vo

@Data
public class UserVO {
    private String name;
    private String age;
    private String birthday;
    private String gender;
}

mapper

@Mapper
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    /**
     * 1、entity与vo中属性名相同的默认映射(如这两个都有name属性)
     * 2、entity与vo中属性名不同的,需要通过@Mapping明确关系来形成映射(如sex对应gender)
     * 3、形成映射关系的属性类型不同的,需要通过表达式转换数据类型类型(如Date对应String)
     * 4、无映射关系属性被忽略(如UserEntity的password)
     */
    @Mappings({
            @Mapping(target = "gender", source = "sex"),
            //@Mapping(target = "birthday", expression = "java(new java.text.SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\").format(entity.getBirthday()))"),
            @Mapping(target = "birthday", dateFormat = "yyyy-MM-dd"),
    })
    UserVO entityToVO(UserEntity entity);

    /**
     * 以entityToVO的映射关系反转,vo转为entity
     */
    @InheritInverseConfiguration(name = "entityToVO")
    UserEntity VOToEntity(UserVO vo);

    /**
     * 将entity更新到以存在的实体vo中
     */
    @InheritConfiguration(name = "entityToVO")
    void updateVOFromEntity(UserEntity entity, @MappingTarget UserVO vo);

    /**
     * 集合的批量转换,会调用entityToVO
     */
    List<UserVO> entitiesToVOs(List<UserEntity> entities);

    /**
     * 使用stream
     */
    List<UserVO> entitiesToVOs(Stream<UserEntity> stream);
}
  1. @Mapper 表示该接口作为映射接口,编译时MapStruct处理器的入口。
  2. @Mappings 一组映射关系
  3. @Mapping 一对映射关系,target:目标类字段,source :源字段,expression :target字段使用改表达式获取值
  4. @InheritInverseConfiguration,表示方法继承相应的反向方法的反向配置。
  5. @InheritConfiguration,指定映射方法

test

public class UserTest {

    public static void main(String[] args)  {
        UserEntity userEntity = new UserEntity();
        userEntity.setAge("1");
        userEntity.setName("bob");
        userEntity.setPassword("123");
        userEntity.setSex("男");
        userEntity.setBirthday(new Date());

        UserVO userVO = UserMapper.INSTANCE.entityToVO(userEntity);
        System.out.println(userVO);
        System.out.println("=================");

        UserEntity userEntity1 = UserMapper.INSTANCE.VOToEntity(userVO);
        System.out.println(userEntity1);
        System.out.println("=================");

        userEntity1.setName("jack");
        UserMapper.INSTANCE.updateVOFromEntity(userEntity1,userVO);
        System.out.println(userVO);
        System.out.println("=================");

        List<UserEntity> entities = new ArrayList<>();
        entities.add(userEntity);
        List<UserVO> vos1 = UserMapper.INSTANCE.entitiesToVOs(entities);
        System.out.println(vos1);
        System.out.println("=================");

        List<UserVO> vos2 = UserMapper.INSTANCE.entitiesToVOs(entities.stream());
        System.out.println(vos2);
        System.out.println("=================");

    }
}

test结果

UserVO(name=bob, age=1, birthday=2017-11-14, gender=男)
=================
UserEntity(name=bob, password=null, age=1, birthday=Tue Nov 14 00:00:00 CST 2017, sex=男)
=================
UserVO(name=jack, age=1, birthday=2017-11-14, gender=男)
=================
[UserVO(name=bob, age=1, birthday=2017-11-14, gender=男)]
=================
[UserVO(name=bob, age=1, birthday=2017-11-14, gender=男)]
=================

compile后MapStruct产生的Mapper接口实现代码

public class UserMapperImpl implements UserMapper {

    @Override
    public UserVO entityToVO(UserEntity entity) {
        if ( entity == null ) {
            return null;
        }

        UserVO userVO = new UserVO();

        userVO.setGender( entity.getSex() );
        userVO.setName( entity.getName() );
        if ( entity.getAge() != null ) {
            userVO.setAge( Integer.parseInt( entity.getAge() ) );
        }
        if ( entity.getBirthday() != null ) {
            userVO.setBirthday( new SimpleDateFormat( "yyyy-MM-dd" ).format( entity.getBirthday() ) );
        }

        return userVO;
    }

    @Override
    public UserEntity VOToEntity(UserVO vo) {
        if ( vo == null ) {
            return null;
        }

        UserEntity userEntity = new UserEntity();

        userEntity.setSex( vo.getGender() );
        userEntity.setName( vo.getName() );
        if ( vo.getAge() != null ) {
            userEntity.setAge( String.valueOf( vo.getAge() ) );
        }
        try {
            if ( vo.getBirthday() != null ) {
                userEntity.setBirthday( new SimpleDateFormat( "yyyy-MM-dd" ).parse( vo.getBirthday() ) );
            }
        }
        catch ( ParseException e ) {
            throw new RuntimeException( e );
        }

        return userEntity;
    }

    @Override
    public void updateVOFromEntity(UserEntity entity, UserVO vo) {
        if ( entity == null ) {
            return;
        }

        vo.setGender( entity.getSex() );
        vo.setName( entity.getName() );
        if ( entity.getAge() != null ) {
            vo.setAge( Integer.parseInt( entity.getAge() ) );
        }
        if ( entity.getBirthday() != null ) {
            vo.setBirthday( new SimpleDateFormat( "yyyy-MM-dd" ).format( entity.getBirthday() ) );
        }
    }

    @Override
    public List<UserVO> entitiesToVOs(List<UserEntity> entities) {
        if ( entities == null ) {
            return null;
        }

        List<UserVO> list = new ArrayList<UserVO>( entities.size() );
        for ( UserEntity userEntity : entities ) {
            list.add( entityToVO( userEntity ) );
        }

        return list;
    }

    @Override
    public List<UserVO> entitiesToVOs(Stream<UserEntity> stream) {
        if ( stream == null ) {
            return null;
        }

        return stream.map( userEntity -> entityToVO( userEntity ) )
        .collect( Collectors.toCollection( ArrayList<UserVO>::new ) );
    }
}

MapStruct的实现也很简单,但帮我们省力很多。

更多MapStruct特性与功能

本文只列举了简单常用的一些功能,更多更强大的可以见官方文档:
http://mapstruct.org/documentation/stable/reference/html/

发布了12 篇原创文章 · 获赞 13 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览