您的位置:首页 > 编程语言 > Java开发

使用MapStruct处理javabean之间的转换

2017-11-14 14:12 363 查看
项目中经常会遇到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);
}


@Mapper 表示该接口作为映射接口,编译时MapStruct处理器的入口。

@Mappings 一组映射关系

@Mapping 一对映射关系,target:目标类字段,source :源字段,expression :target字段使用改表达式获取值

@InheritInverseConfiguration,表示方法继承相应的反向方法的反向配置。

@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 ) {
v
a49a
o.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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息