Java实体映射工具:MapStruct

目录

1 简单使用

2 Spring注入

3 自定义映射

4 映射集合

5 忽略映射

6 多参数映射

7 映射规则

8 默认值和常量

9 空Model返回


当我们需要进行Java Model之间的拷贝时;或者项目要求Java Model需要严格区分为数据对象(DO)、数据传输对象(DTO)和展示对象(VO)的时候,我们就不得不把一个实体中的属性映射到另一个实体中。最简单的做法是写一个工具类,进行不断的getter / setter,这样虽然能完成要求但却写了很多冗余代码,维护起来相当恶心。所以这个时候就需要一款能自动映射实体属性的工具了。

Spring自带的BeanUtils工具类算是一款,但是它却不能自定义映射规则;ModelMapper也是一款映射工具框架,虽然它可以自定义映射规则,但写法上却复杂一些。而MapStruct作为一款优秀的Java实体映射工具来说,它也能够自定义映射规则,并且是通过注解的方式来实现的,源和目标看得很清楚明白。MapStruct不同于BeanUtils和ModelMapper是通过反射在运行期生成代码导致性能不高,它是在编译期生成实现类映射代码,生成的代码就是普通的getter / setter代码,和原生使用的性能相差不大。


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>

除此之外如果使用的IDE是idea的话,还可以下载MapStruct的插件:

该插件可以动态地提示当前没有进行映射的字段,以及其他一些对MapStruct的支持(和Lombok不同,该插件不是必须安装的)。

接着准备两个Java Model如下所示,一个DO,一个VO:

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PersonDO implements Serializable {

    private static final long serialVersionUID = -3483764417202514211L;

    private Long personId;

    private String name;

    private Integer sex;

    private Integer age;

    private String address;
}
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PersonVO implements Serializable {

    private static final long serialVersionUID = 7827081422917080855L;

    private Long id;

    private String name;

    private String sex;

    private Integer age;

    private String address;
}

其中用到了Lombok的注解来简化编程,详见笔者的另一篇文章《Lombok概述》。在完成了上述准备之后,就可以进行MapStruct的开发使用了。

我们现在是要把PersonDO转成PersonVO,首先需要写一个接口,如下所示:

import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper
public interface PersonMapper {

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

    PersonVO personDO2VO(PersonDO personDO);
}

之后需要进行打包编译,在对属性进行变动后都要进行打包编译,以此来生成新的实现类。MapStruct并不能及时地反映出属性的变更,比方说接口提供方变更了Model的属性,而调用方只有等到打包编译的时候才能提示出错误,这也许是MapStruct为数不多的缺点了吧,但介于MapStruct是在编译期生成映射代码的机制,这点也无可厚非,只要多加留意即可。

生成的实现类如下所示:

import javax.annotation.Generated;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T18:46:28+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO) {
        if ( personDO == null ) {
            return null;
        }

        PersonVO personVO = new PersonVO();

        personVO.setName( personDO.getName() );
        if ( personDO.getSex() != null ) {
            personVO.setSex( String.valueOf( personDO.getSex() ) );
        }
        personVO.setAge( personDO.getAge() );
        personVO.setAddress( personDO.getAddress() );

        return personVO;
    }
}

由上可以看到,生成的实现类就是通过getter / setter方法来实现的,不损失性能。相应的测试代码如下所示:

PersonDO personDO = PersonDO.builder().personId(1L).name("Robert Hou").sex(1).age(24).address("Beijing").build();
PersonVO personVO = PersonMapper.INSTANCE.personDO2VO(personDO);
System.out.println(personVO);

运行结果如下:

PersonVO(id=null, name=Robert Hou, sex=1, age=24, address=Beijing)

2 Spring注入

除了上节的映射接口中声明INSTANCE的方式来进行调用,MapStruct也同时支持Spring的依赖注入机制,如下所示:

import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface PersonMapper {

    PersonVO personDO2VO(PersonDO personDO);
}

生成的实现类如下:

import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T18:47:41+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO) {
        if ( personDO == null ) {
            return null;
        }

        PersonVO personVO = new PersonVO();

        personVO.setName( personDO.getName() );
        if ( personDO.getSex() != null ) {
            personVO.setSex( String.valueOf( personDO.getSex() ) );
        }
        personVO.setAge( personDO.getAge() );
        personVO.setAddress( personDO.getAddress() );

        return personVO;
    }
}

可以看到是对该类添加了@Component注解,注册成为了一个Bean。相应的测试代码如下所示:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class TestApplicationTests {

    @Autowired
    private PersonMapper personMapper;

    @Test
    void mapperTest() {
        PersonDO personDO = PersonDO.builder().personId(1L).name("Robert Hou").sex(1).age(24).address("Beijing").build();
        PersonVO personVO = personMapper.personDO2VO(personDO);
        System.out.println(personVO);
    }
}

3 自定义映射

由上面的映射规则可知,Mapstruct默认只会对同名的属性进行映射,对于不同名的属性则不会映射,如PersonDO的personId属性就没有映射到PersonVO的id属性中。这种情况下就需要手动选择映射属性,如下所示:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

@Mapper(componentModel = "spring")
public interface PersonMapper {

    @Mappings({
            @Mapping(source = "personId", target = "id")
    })
    PersonVO personDO2VO(PersonDO personDO);
}

如果映射属性只有一个的话,则可以不用使用@Mappings注解而只使用@Mapping注解也都是可以的。这回再来看一下生成的实现类代码:

import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T18:48:47+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO) {
        if ( personDO == null ) {
            return null;
        }

        PersonVO personVO = new PersonVO();

        personVO.setId( personDO.getPersonId() );
        personVO.setName( personDO.getName() );
        if ( personDO.getSex() != null ) {
            personVO.setSex( String.valueOf( personDO.getSex() ) );
        }
        personVO.setAge( personDO.getAge() );
        personVO.setAddress( personDO.getAddress() );

        return personVO;
    }
}

在第行可以看到对Id属性也进行了映射。


4 映射集合

MapStruct也支持对集合的映射,开发起来也相当简单。比如说我们现在需要将一个PersonDO的List集合转换成PersonVO的List集合,MapStruct的写法如下所示:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

import java.util.List;

@Mapper(componentModel = "spring")
public interface PersonMapper {

    @Mappings({
            @Mapping(source = "personId", target = "id")
    })
    PersonVO personDO2VO(PersonDO personDO);

    List<PersonVO> personDOs2VOs(List<PersonDO> personDOList);
}

可以看到只需要在第行添加一个对集合进行映射的方法就行了,并不需要显示地调用personDO2VO方法,这完全得益于MapStruct的自动类型探测,生成的实现类代码如下所示:

import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T18:51:17+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO) {
        if ( personDO == null ) {
            return null;
        }

        PersonVO personVO = new PersonVO();

        personVO.setId( personDO.getPersonId() );
        personVO.setName( personDO.getName() );
        if ( personDO.getSex() != null ) {
            personVO.setSex( String.valueOf( personDO.getSex() ) );
        }
        personVO.setAge( personDO.getAge() );
        personVO.setAddress( personDO.getAddress() );

        return personVO;
    }

    @Override
    public List<PersonVO> personDOs2VOs(List<PersonDO> personDOList) {
        if ( personDOList == null ) {
            return null;
        }

        List<PersonVO> list = new ArrayList<PersonVO>( personDOList.size() );
        for ( PersonDO personDO : personDOList ) {
            list.add( personDO2VO( personDO ) );
        }

        return list;
    }
}

由上可以看到personDOs2VOs方法实现了对personDO2VO方法的调用。


5 忽略映射

在某些情况下我们不需要对某些字段进行映射,MapStruct也是支持的。比方说现在不需要对address字段进行映射,那么写法如下所示:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

@Mapper(componentModel = "spring")
public interface PersonMapper {

    @Mappings({
            @Mapping(source = "personId", target = "id"),
            @Mapping(target = "address", ignore = true)
    })
    PersonVO personDO2VO(PersonDO personDO);
}

如第行代码所示,将ignore选项值赋为true即可。这样的话生成的实现类就不会对address字段进行映射了。


6 多参数映射

有些时候我们的入参不止一个,而是有多个,这样的情况MapStruct也是支持的,如下所示:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

@Mapper(componentModel = "spring")
public interface PersonMapper {

    @Mappings({
            @Mapping(source = "personDO1.personId", target = "id"),
            @Mapping(source = "personDO1.name", target = "name"),
            @Mapping(source = "personDO1.sex", target = "sex"),
            @Mapping(source = "personDO2.age", target = "age"),
            @Mapping(source = "personDO2.address", target = "address")
    })
    PersonVO personDO2VO(PersonDO personDO1, PersonDO personDO2);
}

入参有两个PersonDO,将第一个PersonDO的personId、name和sex属性赋值给PersonVO,而将第二个PersonDO的age和address属性赋值给PersonVO。需要注意的是如果多个入参的属性名相同,则需要起别名来进行区别,否则编译会报错。生成的实现类代码如下:

import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T20:58:00+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO1, PersonDO personDO2) {
        if ( personDO1 == null && personDO2 == null ) {
            return null;
        }

        PersonVO personVO = new PersonVO();

        if ( personDO1 != null ) {
            personVO.setName( personDO1.getName() );
            personVO.setId( personDO1.getPersonId() );
            if ( personDO1.getSex() != null ) {
                personVO.setSex( String.valueOf( personDO1.getSex() ) );
            }
        }
        if ( personDO2 != null ) {
            personVO.setAddress( personDO2.getAddress() );
            personVO.setAge( personDO2.getAge() );
        }

        return personVO;
    }
}

7 映射规则

对于一些简单的类型转换,例如int转String,boolean转Boolean等等,MapStruct都可以自动完成。在上面的例子中也有所体现,例如PersonDO的sex字段是Integer类型的,而PersonVO的sex字段是String类型的,MapStruct通过String.valueOf的方式完成了转换,不需要使用者操心。

而对于Date和String类型之间的相互转换,MapStruct也是支持的,这里我们往PersonDO中新添加一个Date类型的birthday属性,在PersonVO中新添加一个String类型的birthday属性,两者进行映射。然后MapStruct的接口类代码如下所示:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

@Mapper(componentModel = "spring")
public interface PersonMapper {

    @Mappings({
            @Mapping(source = "personId", target = "id"),
            @Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
    })
    PersonVO personDO2VO(PersonDO personDO);
}

生成的实现类如下:

import java.text.SimpleDateFormat;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T19:17:11+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO) {
        if ( personDO == null ) {
            return null;
        }

        PersonVO personVO = new PersonVO();

        if ( personDO.getBirthday() != null ) {
            personVO.setBirthday( new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( personDO.getBirthday() ) );
        }
        personVO.setId( personDO.getPersonId() );
        personVO.setName( personDO.getName() );
        if ( personDO.getSex() != null ) {
            personVO.setSex( String.valueOf( personDO.getSex() ) );
        }
        personVO.setAge( personDO.getAge() );
        personVO.setAddress( personDO.getAddress() );

        return personVO;
    }
}

由上面第行代码可以看到,MapStruct是通过SimpleDateFormat的方式完成的转换。dateFormat配置日期的格式,另外MapStruct还提供了一个numberFormat关于数据精度的配置,读者可自行尝试,这里就不再演示了。

有些情况下可能需要完成更加复杂、更加定制化的映射规则,这时候就需要我们自己来写映射代码了,这在MapStruct中实现也非常容易。现在我们不需要从PersonDO中的sex字段映射到PersonVO中的sex字段,而是通过身份证号的倒数第二位来进行判断,如果为奇数,则为男,反之则为女。继续往PersonDO中新添加一个String类型的idNumber属性,然后需要写一个转换的工具方法:

public class PersonUtils {

    private PersonUtils() {
    }

    public static String getSex(String idNumber) {
        if (idNumber == null) {
            return null;
        }
        //截取身份证倒数第二位数字
        String in = idNumber.substring(idNumber.length() - 2, idNumber.length() - 1);
        int i = Integer.parseInt(in);
        //如果为奇数,则是男,反之则为女
        return (i & 1) == 1 ? "男" : "女";
    }
}

MapStruct的接口类改造如下:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

@Mapper(componentModel = "spring", imports = PersonUtils.class)
public interface PersonMapper {

    @Mappings({
            @Mapping(source = "personId", target = "id"),
            @Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "sex", expression = "java(PersonUtils.getSex(personDO.getIdNumber()))")
    })
    PersonVO personDO2VO(PersonDO personDO);
}

首先需要在类上的@Mapper注解中加上imports选项来引入这个工具类,然后通过在@Mapping注解中添加expression选项来完成调用,如第行所示。需要注意的是expression配置项中首先需要写“java()”,然后再在其中写具体的调用代码。生成的实现类代码如下所示:

import java.text.SimpleDateFormat;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T20:04:35+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO) {
        if ( personDO == null ) {
            return null;
        }

        PersonVO personVO = new PersonVO();

        if ( personDO.getBirthday() != null ) {
            personVO.setBirthday( new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( personDO.getBirthday() ) );
        }
        personVO.setId( personDO.getPersonId() );
        personVO.setName( personDO.getName() );
        personVO.setAge( personDO.getAge() );
        personVO.setAddress( personDO.getAddress() );

        personVO.setSex( PersonUtils.getSex(personDO.getIdNumber()) );

        return personVO;
    }
}

如上第行所示,通过调用PersonUtils的工具类方法,完成了sex字段的映射。同时如果使用的Java版本是8或者以上,那么可以使用从Java 8开始的接口中的default语句来简化编程,不用再单独写一个工具类了。比如说现在我们需要将PersonDO中的age字段的值加上10,然后赋值给PersonVO中的age字段。如下所示:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

@Mapper(componentModel = "spring", imports = PersonUtils.class)
public interface PersonMapper {

    @Mappings({
            @Mapping(source = "personId", target = "id"),
            @Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "sex", expression = "java(PersonUtils.getSex(personDO.getIdNumber()))")
    })
    PersonVO personDO2VO(PersonDO personDO);

    default Integer addAge(Integer age) {
        return age + 10;
    }
}

不需要显式地进行调用,MapStruct会自己推测出来。生成的实现类代码如下:

import java.text.SimpleDateFormat;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T20:32:12+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO) {
        if ( personDO == null ) {
            return null;
        }

        PersonVO personVO = new PersonVO();

        if ( personDO.getBirthday() != null ) {
            personVO.setBirthday( new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( personDO.getBirthday() ) );
        }
        personVO.setId( personDO.getPersonId() );
        personVO.setName( personDO.getName() );
        personVO.setAge( addAge( personDO.getAge() ) );
        personVO.setAddress( personDO.getAddress() );

        personVO.setSex( PersonUtils.getSex(personDO.getIdNumber()) );

        return personVO;
    }
}

从第行代码可以看到,显式调用了addAge方法完成了转换的操作。但是有一点需要注意,MapStruct是通过入参和出参的类型进行判断,从而进行赋值的。拿这个例子来说,MapStruct会把所有的源Model类型为Integer和目标Model类型为Integer的属性都添加上这个addAge方法,这往往会造成把不想要转换的属性也给转换了。在这种情况下就不能使用default语句了,而转而使用上文所说的expression配置项,写一个工具类方法,显示地对属性进行调用即可,这点需要多加留意。


8 默认值和常量

同时MapStruct也支持默认值和常量,如下所示:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

@Mapper(componentModel = "spring")
public interface PersonMapper {

    @Mappings({
            @Mapping(source = "personId", target = "id"),
            @Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "sex", constant = "男"),
            @Mapping(target = "address", defaultValue = "中国"),
    })
    PersonVO personDO2VO(PersonDO personDO);
}

如上第行和第行代码所示,sex字段常量赋值为“男”,address字段使用了默认值,即该字段如果值为null的情况下赋值为“中国”,不为null则照常进行赋值。生成的实现类代码如下:

import java.text.SimpleDateFormat;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T21:20:11+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO) {
        if ( personDO == null ) {
            return null;
        }

        PersonVO personVO = new PersonVO();

        if ( personDO.getBirthday() != null ) {
            personVO.setBirthday( new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( personDO.getBirthday() ) );
        }
        personVO.setId( personDO.getPersonId() );
        personVO.setName( personDO.getName() );
        personVO.setAge( personDO.getAge() );
        if ( personDO.getAddress() != null ) {
            personVO.setAddress( personDO.getAddress() );
        }
        else {
            personVO.setAddress( "中国" );
        }

        personVO.setSex( "男" );

        return personVO;
    }
}

9 空Model返回

通过上面的例子可以看到,当入参Model本身为null的时候,则直接返回null赋值给出参Model。有些情况下我们想返回一个空属性的Model而不是null,这样可以不用再在后续进行空指针判断。如下所示:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.NullValueMappingStrategy;

@Mapper(componentModel = "spring", nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
public interface PersonMapper {

    @Mappings({
            @Mapping(source = "personId", target = "id"),
            @Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(target = "sex", constant = "男"),
            @Mapping(target = "address", defaultValue = "中国"),
    })
    PersonVO personDO2VO(PersonDO personDO);
}

在类上的@Mapper注解中加上nullValueMappingStrategy配置项,并配置为NullValueMappingStrategy.RETURN_DEFAULT即可,默认为.RETURN_NULL,即返回null。生成的实现类代码如下:

import java.text.SimpleDateFormat;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-02-08T21:24:37+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_201 (Oracle Corporation)"
)
@Component
public class PersonMapperImpl implements PersonMapper {

    @Override
    public PersonVO personDO2VO(PersonDO personDO) {

        PersonVO personVO = new PersonVO();

        if ( personDO != null ) {
            if ( personDO.getBirthday() != null ) {
                personVO.setBirthday( new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( personDO.getBirthday() ) );
            }
            personVO.setId( personDO.getPersonId() );
            personVO.setName( personDO.getName() );
            personVO.setAge( personDO.getAge() );
            if ( personDO.getAddress() != null ) {
                personVO.setAddress( personDO.getAddress() );
            }
            else {
                personVO.setAddress( "中国" );
            }
        }
        personVO.setSex( "男" );

        return personVO;
    }
}

可以看到如果PersonDO为null的话,会返回一个空属性的PersonVO,而不是直接返回null。

发布了64 篇原创文章 · 获赞 81 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_30342639/article/details/104223046