假设我们有两个类 Person
和 PersonDTO
,我们需要将 Person
对象转换成 PersonDTO
对象。Person
类有 firstName
, lastName
, age
属性,而 PersonDTO
类有 fullName
, age
属性。我们的任务是将 Person
中的信息映射到 PersonDTO
中。
public class Person {
private String firstName;
private String lastName;
private int age;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class PersonDTO {
private String fullName;
private int age;
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
定义: Apache Commons BeanUtils 是一个开源的Java库,它提供了一系列操作JavaBean的工具,包括对属性的访问和设置、属性转换、克隆等。
实现原理:
copyProperties
方法时,BeanUtils会遍历源对象的所有可读属性(即带有getter方法的属性),并尝试将这些属性的值设置到目标对象的对应属性中。这要求目标对象具有与源对象属性名相匹配的setter方法。使用场景: 适用于简单的属性复制,但性能上可能不如直接编码或使用更专业的映射库。
示例:
Apache Commons BeanUtils 提供了一个简单的方法来复制两个 JavaBean 之间的属性。它要求源对象和目标对象具有相同的属性名。如果属性名不同或者需要做一些额外的处理(如合并 firstName
和 lastName
),则需要手动编写代码。
import org.apache.commons.beanutils.BeanUtils;
public class Main {
public static void main(String[] args) throws Exception {
Person person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
person.setAge(30);
PersonDTO personDTO = new PersonDTO();
// 使用BeanUtils.copyProperties复制属性
BeanUtils.copyProperties(personDTO, person);
// 手动设置 fullName
personDTO.setFullName(person.getFirstName() + " " + person.getLastName());
System.out.println(personDTO.getFullName()); // John Doe
System.out.println(personDTO.getAge()); // 30
}
}
定义: Spring框架中也提供了一个BeanUtils工具类,用于简化JavaBean之间的属性复制。
实现原理:
区别: Spring的BeanUtils通常用于Spring框架内部或与其相关的项目中,而Apache Commons BeanUtils是一个更通用的库。
使用场景: 与Apache Commons BeanUtils相似,但更常见于Spring项目中。
示例:
Spring Framework 的 BeanUtils
类与 Apache Commons BeanUtils 类似,但它还提供了更多的功能,比如自动类型转换。同样,它也要求属性名相同,否则需要手动处理。
import org.springframework.beans.BeanUtils;
public class Main {
public static void main(String[] args) {
Person person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
person.setAge(30);
PersonDTO personDTO = new PersonDTO();
// 使用Spring的BeanUtils.copyProperties复制属性
BeanUtils.copyProperties(person, personDTO);
// 手动设置 fullName
personDTO.setFullName(person.getFirstName() + " " + person.getLastName());
System.out.println(personDTO.getFullName()); // John Doe
System.out.println(personDTO.getAge()); // 30
}
}
定义: ModelMapper是一个对象映射库,它提供了一个简单的API来映射对象到对象(包括标准Java对象、POJOs等)。
实现原理:
使用场景: 适用于复杂的对象映射场景,特别是当源对象和目标对象之间的属性名不完全一致时。
示例:
ModelMapper 是一个强大的对象映射库,它可以自动映射属性,并且允许配置自定义映射逻辑。它非常适合处理属性名不匹配的情况,以及进行一些简单的转换操作。
import org.modelmapper.ModelMapper;
public class Main {
public static void main(String[] args) {
ModelMapper modelMapper = new ModelMapper();
Person person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
person.setAge(30);
// 使用 ModelMapper 映射对象
PersonDTO personDTO = modelMapper.map(person, PersonDTO.class);
// 输出结果
System.out.println(personDTO.getFullName()); // John Doe
System.out.println(personDTO.getAge()); // 30
}
}
定义: Dozer是一个Java Bean到Java Bean的映射器,它使用XML或注解来定义映射规则。
实现原理:
使用场景: 适用于需要高度可配置映射规则的场景,特别是当项目中有多个复杂的映射需求时。
示例:
Dozer 是一个用于对象映射的工具,它允许用户通过 XML 文件或注解来配置映射规则。Dozer 也可以处理属性名不匹配的情况,并且可以进行一些基本的数据转换。
import org.dozer.DozerBeanMapper;
public class Main {
public static void main(String[] args) {
DozerBeanMapper dozerMapper = new DozerBeanMapper();
Person person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
person.setAge(30);
// 使用 Dozer 映射对象
PersonDTO personDTO = dozerMapper.map(person, PersonDTO.class);
// 输出结果
System.out.println(personDTO.getFullName()); // John Doe
System.out.println(personDTO.getAge()); // 30
}
}
定义: MapStruct是一个基于约定优于配置原则的Java注解处理器,用于生成类型安全的bean映射类。
实现原理:
@Mapper
、@Mapping
等)来定义映射规则。使用场景: 适用于性能敏感的项目,特别是在大型项目中,因为编译时生成的代码通常比运行时反射要快得多。
示例:
MapStruct 是一个代码生成器,它通过注解来定义映射接口,并自动生成实现类。这使得 MapStruct 在性能方面表现得非常好,并且可以轻松处理复杂映射逻辑。
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper
public interface PersonMapper {
@Mapping(source = "firstName", target = "fullName")
@Mapping(source = "lastName", target = "fullName", qualifiedByName = "appendSpace")
@Mapping(source = "age", target = "age")
PersonDTO toDto(Person person);
@Named("appendSpace")
default String appendSpace(String firstName, String lastName) {
return firstName + " " + lastName;
}
}
public class Main {
public static void main(String[] args) {
PersonMapper personMapper = PersonMapper.INSTANCE;
Person person = new Person();
person.setFirstName("John");
person.setLastName("Doe");
person.setAge(30);
// 使用 MapStruct 映射对象
PersonDTO personDTO = personMapper.toDto(person);
// 输出结果
System.out.println(personDTO.getFullName()); // John Doe
System.out.println(personDTO.getAge()); // 30
}
}
每个工具都有其适用的场景和优缺点。选择哪个工具取决于具体项目的需求、性能要求以及个人或团队的偏好。对于简单的属性复制,Apache Commons BeanUtils或Spring BeanUtils可能就足够了。对于复杂的映射关系,ModelMapper、Dozer或MapStruct可能更合适。特别是MapStruct,由于其编译时生成代码的特性,它在性能上通常优于其他运行时映射工具。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有