java对象相互转化多种实现方式

方式一:MapStruct

是一个代码生成器,它基于约定优于配置的方法,极大地简化了 Java bean 类型之间的映射实现。
生成的映射代码使用普通的方法调用,因此速度快、类型安全且易于理解。

官方文档
https://mapstruct.org/documentation/installation/
更多使用示例
https://github.com/kevinLuan/mapstruct-examples
mapper-struct使用比较灵活,性能非常出色。由于它的实现是通过在开发中生成源代码的方式实现,所以对于动态对象数据拷贝并不适合。

使用示例:

// 编写User实体类和DTO实体类
  @Data
  public class User {
      private int id;
      private String nickname;
      private boolean sex;
      private Date registerTime;
      private int status;
  }
  @Data
  public class UserDTO {
      private int id;
      private String nickname;
      private boolean sex;
      private Date registerTime;
  }


  @Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
      nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
  public interface UserMapper {
      UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
      UserDTO map(User user);
      User map(UserDTO userDTO);
  }
  //maven工程编译项目: mvn compile  

  //测试方法:
  @Test
  public void test_copyUserDtoFromUser() {
    UserDto userDto = UserMapper.INSTANCE.map(user);
    Assert.assertEquals(userDto.getId(), 100);
  }

  //介绍几个常用的注解:
  @Mapping 描述转换源对象中的属性名称到目标属性名称的映射,如下
  User -> UserDTO 转换示例
  @Mapping(source = "users", target = "userList")
  UserDTO convert(User user);
  //反向转换 UserDTO -> User
  @Mapping(source = "userList", target = "users")
  User convert(UserDTO userDTO);
  //反向转换还可以使用如下注解来完成相同的效果,当转换映射参数比较复杂的情况下,可以使用该注解简化配置
  @InheritInverseConfiguration  //指示方法应继承响应反向的配置
  User convert(UserDTO userDTO);
  //使用java表达式,来生成数据,如下示例演示,通过执行表达式中的代码动态生成数据填充到目标属性中
  @Mapping(target = "uniqueId", expression = "java(CommonConverter.generateUniqueId())")
  User convert(UserDTO userDTO);
  //演示实现装饰器自定义映射实现
  @Mapper(imports = CommonConverter.class)
  //通过定义装饰器模式实现
  @DecoratedWith(value = AbstractCarMapperDecorated.class)
  public interface CarMapper {
      CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
      CarDto map(Car car);
      //使用java表达式,来生成数据
      @Mapping(target = "uniqueId", expression = "java(CommonConverter.generateUniqueId())")
      Car map(CarDto car);
  }
  /**
  * 实现装饰器自定义映射实现
  */
  public abstract class AbstractCarMapperDecorated implements CarMapper {
      private CarMapper delegate;
      public AbstractCarMapperDecorated(CarMapper delegate) {
          this.delegate = delegate;
      }
      public CarDto map(Car car) {
          CarDto dto = delegate.map(car);
          dto.setTitle("title:" + dto.getTitle());
          return dto;
      }
  }

方式二:BeanCopier

BeanCopier 底层依赖cglib通过生成字节码来实现对象拷贝,性能同样非常出色。
  由于使用到字节码生成方式技术,所以在动态生成字节码实现类时性能消耗比较大,不过可以通过提前预生成实现类并添加到cache中。

final static BeanCopier beanCopier = BeanCopier.create(Goods.class, GoodsDto.class, false);
//深拷贝数据
beanCopier.copy(goods, goodsDto, null);

public class Goods{
  //...
}
public class GoodsDto{
  //...
}

方式三:Spring BeanUtils

Spring BeanUtils实现原理是基于反射实现的数据拷贝处理,性能上相比通过字节码生成实现要慢很多。
  org.springframework.beans.BeanUtils.copyProperties(source, target);

方式四:apache BeanUtils

org.apache.commons.beanutils.BeanUtils.copyProperties(do, entity);
  该方法同样使用反射调用实现数据拷贝处理,性能相比Spring BeanUtils还要差一些,适合使用场景较为简单,调用频率比高的场景。

方式五:IDE idea插件:GenerateAllSetter

安装插件:using IDE plugin system
  Preferences(Settings) > Plugins > Browse repositories... > find"GenerateAllSetter" > Install      Plugin源码地址:    https://github.com/gejun123456/intellij-generateAllSetMethod

// 编写User实体类和DTO实体类
  @Data
  public class User {
      private int id;
      private String nickname;
      private boolean sex;
      private Date registerTime;
      private int status;
  }
  @Data
  public class UserDTO {
      private int id;
      private String nickname;
      private boolean sex;
      private Date registerTime;
  }
  //然后编写转换方法
  public UserDTO convertUserDTO(User user){
      //TODO 将光标移到方法中空白处,使用快捷键:alt + enter(回车键) 当前使用的mac系统
      //弹出:Generate setter getter converter
  }
  //生成后的代码如下:
  public UserDTO convertUserDTO(User user){
      UserDTO userDTO = new UserDTO();
      userDTO.setId(user.getId());
      userDTO.setNickname(user.getNickname());
      userDTO.setSex(user.isSex());
      userDTO.setRegisterTime(user.getRegisterTime());
      return userDTO;
  }    

详细测试用例请查阅:在路上/lyh-api - Gitee.comhttps://gitee.com/kevinLuan/lyh-api/tree/master/pojo-convert-demo

你可能感兴趣的:(java,java)