JavaDTOPOVO 类相互转换的工具类
Posted 张学徒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaDTOPOVO 类相互转换的工具类相关的知识,希望对你有一定的参考价值。
DTO、PO、VO 相互转换的工具
这里我使用一个 Builder 将要赋值的属性映射添加进去,然后使用的时候直接传入对应的类对象即可
先写个 Builder 类
PropertyMapCopyBuilder
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
/**
* <p>数据属性的映射构建器</p>
*
* <p>创建一个构造器实例,添加每个类对应的复制到对应的属性的方法。使用构造器的@link FunctionMap#map(Class)方法获取数据来源类的映射
* 对象,然后调用@link FunctionMap#add(BiConsumer, Function)方法添加映射的属性方法。添加完成之后使用@link FunctionMap#build()
* 方法构建出构建器对象。</p>
*
* <p>使用@link PropertyMapCopyBuilder对象的@link PropertyMapCopyBuilder#copy(Object, Object...)方法将数据复制到目标对象上,
* 或使用@link PropertyMapCopyBuilder#create(Object...)方法创建出来实例对象,将属性复制到这个对象身上。</p>
*
* <p>示例:</p>
*
* <pre>@code
* final PropertyMapCopyBuilder<UserDTO> builder = PropertyCopyBuilder.instance(UserDTO.class)
* .map(UserPO.class)
* .add(UserDTO::setId, UserPO::getId)
* .add(UserDTO::setUsername, UserPO::getUsername)
* .map(RolePO.class)
* .add(UserDTO::setRolename, RolePO::getName)
* .add(UserDTO::setPermission, RolePO::getPermission)
* .build();
* final UserPO userPO = new UserPO(2, "zhangsan", "123456", "1567778889");
* final RolePO rolePO = new RolePO(1, "admin", "/user,/log");
* final UserDTO userDTO = builder.create(userPO, rolePO);
* System.out.println(userDTO);
* </pre>
*
* <p>可以预先创建一个<code>PropertyMapConfig</code>属性映射配置类,用以预先设置好要映射的类的属性</p>
*
* @param <Target> 要复制到的目标对象的类型
* @author zhangxuetu
* @date 2022-11-24
* @since 1.8
*/
public class PropertyMapCopyBuilder<Target>
/**
* 项目中的类对应的@link PropertyMapCopyBuilder,这个 map 已经包含有这个 Class,则不重新创建新的@link PropertyMapCopyBuilder
*/
private final static Map<Class, PropertyMapCopyBuilder> BUILDER_MAP = new HashMap<>();
/**
* 转换到的类
*/
private final Class<Target> clazz;
/**
* 不同的类的方法可以设置的值
*/
private final Map<Class, FunctionMap> classToFunctionMap = new HashMap<>();
private PropertyMapCopyBuilder(Class<Target> clazz)
this.clazz = clazz;
/**
* 创建个新的 Builder
*
* @param clazz 类型
* @param <T> 这个类的类型
* @return 返回新建的@link PropertyMapCopyBuilder,这个创建出来的@link PropertyMapCopyBuilder与
* @link PropertyMapCopyBuilder#instance(Class)方式创建出来的不同,这个每次都要设置类映射的属性,然后@link FunctionMap#build()
* 进行构建出来@link PropertyMapCopyBuilder才能正常使用
*/
public static <T> PropertyMapCopyBuilder<T> create(Class<T> clazz)
return new PropertyMapCopyBuilder<>(clazz);
/**
* 实例化一个构建器单例,如果已经创建过这个类的 @link PropertyMapCopyBuilder,则直接返回创建过的 @link PropertyMapCopyBuilder
*
* @param clazz 转换的类
* @param <T> 这个类的类型
*/
public static <T> PropertyMapCopyBuilder<T> instance(Class<T> clazz)
if (BUILDER_MAP.containsKey(clazz))
return BUILDER_MAP.get(clazz);
final PropertyMapCopyBuilder<T> builder = new PropertyMapCopyBuilder<>(clazz);
BUILDER_MAP.put(clazz, builder);
return builder;
/**
* 开始添加这个类的方法映射
*
* @param clazz 类的类型
* @param <Source> 获取数据的对象的类型
*/
public <Source> FunctionMap<Target, Source> map(Class<Source> clazz)
if (classToFunctionMap.containsKey(clazz))
return classToFunctionMap.get(clazz);
else
final FunctionMap<Target, Source> functionMap = new FunctionMap<>(this);
classToFunctionMap.put(clazz, functionMap);
return functionMap;
/**
* 复制属性到这个对象上
*
* @param target 设置属性的目标对象
* @param getters 获取数据的对象
*/
public void copy(Target target, Object... getters)
for (Object getter : getters)
final FunctionMap<Target, Object> functionMap = classToFunctionMap.get(getter.getClass());
functionMap.copy(target, getter);
/**
* 根据这个几个对象创建出来目标类型的对象
*
* @param getters 获取数据的对象列表
*/
public Target create(Object... getters)
Target target = null;
try
target = clazz.getDeclaredConstructor().newInstance();
copy(target, getters);
catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e)
e.printStackTrace();
return target;
//======================================================
// Function 映射方法
//======================================================
/**
* 这个类的 Get(Function) 方法对应的 Set(BiConsumer)方法 的映射
*
* @param <T> 设置属性的目标对象的类型
* @param <S> 获取属性的来源对象的类型
*/
public static class FunctionMap<T, S>
private final PropertyMapCopyBuilder<T> parent;
/**
* Get 方法对应要设置的 Set 方法的映射
*/
private final Map<Function, BiConsumer> functionMap = new HashMap<>();
protected FunctionMap(PropertyMapCopyBuilder<T> parent)
this.parent = parent;
/**
* 添加方法映射
*
* @param consumer Set 方法
* @param function Get 方法
* @return 返回当前对象以便链式调用
*/
public <Result> FunctionMap<T, S> add(BiConsumer<T, Result> consumer, Function<S, Result> function)
functionMap.put(function, consumer);
return this;
/**
* 获取这个类的方法映射
*
* @param clazz 数据来源的类的类型
* @param <S> 获取数据的来源对象的类型
*/
public <S> FunctionMap<T, S> map(Class<S> clazz)
return parent.map(clazz);
/**
* 构建出来 EntityConvertBuilder 对象
*/
public PropertyMapCopyBuilder<T> build()
return parent;
/**
* 对属性进行赋值
*
* @param target 设置属性的目标对象
* @param source 获取属性的来源对象
*/
public void copy(T target, S source)
BiConsumer<T, Object> consumer;
Function<S, Object> function;
for (Map.Entry<Function, BiConsumer> entry : functionMap.entrySet())
function = entry.getKey();
consumer = entry.getValue();
consumer.accept(target, function.apply(source));
创建一个测试类,测试一下功能
CopyPropertyTest
public class CopyPropertyTest
public static void main(String[] args)
// 添加对应的属性映射
final PropertyMapCopyBuilder<UserDTO> builder = PropertyMapCopyBuilder.instance(UserDTO.class)
.map(UserPO.class)
.add(UserDTO::setId, UserPO::getId)
.add(UserDTO::setUsername, UserPO::getUsername)
.map(RolePO.class)
.add(UserDTO::setRolename, RolePO::getName)
.add(UserDTO::setPermission, RolePO::getPermission)
.build();
final UserPO userPO = new UserPO(null, "zhangsan", "123456", "15511112222");
final RolePO rolePO = new RolePO(1, "管理员", "/user,/log");
final UserDTO userDTO = builder.create(userPO, rolePO);
System.out.println(userDTO);
//==================================================
// 实体类
//==================================================
public static class UserPO
private Integer id;
private String username;
private String password;
private String phone;
public UserPO()
public UserPO(Integer id, String username, String password, String phone)
this.id = id;
this.username = username;
this.password = password;
this.phone = phone;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getUsername()
return username;
public void setUsername(String username)
this.username = username;
public String getPassword()
return password;
public void setPassword(String password)
this.password = password;
public String getPhone()
return phone;
public void setPhone(String phone)
this.phone = phone;
@Override
public String toString()
return "UserPO" +
"id=" + id +
", username='" + username + '\\'' +
", password='" + password + '\\'' +
", phone='" + phone + '\\'' +
'';
public static class UserDTO
private Integer id;
private String username;
private String phone;
private String rolename;
private String permission;
public UserDTO()
public UserDTO(Integer id, String username, String phone, String rolename, String permission)
this.id = id;
this.username = username;
this.phone = phone;
this.rolename = rolename;
this.permission = permission;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getUsername()
return username;
public void setUsername(String username)
this.username = username;
public String getPhone()
return phone;
public void setPhone(String phone)
this.phone = phone;
public String getRolename()
return rolename;
public void setRolename(String rolename)
this.rolename = rolename;
public String getPermission()
return permission;
public void setPermission(String permission)
this.permission = permission;
@Override
public String toString()
return "UserDTO" +
"id=" + id +
", username='" + username + '\\'' +
", phone='" + phone + '\\'' +
", rolename='" + rolename + '\\'' +
", permission='" + permission + '\\'' +
'';
public static class RolePO
private Integer id;
private String name;
private String permission;
public RolePO()
public RolePO(Integer id, String name, String permission)
this.id = id;
this.name = name;
this.permission = permission;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getPermission()
return permission;
public void setPermission(String permission)
this.permission = permission;
@Override
public String toString()
return "RolePO" +
"id=" + id +
", name='" + name + '\\'' +
", permission='" + permission + '\\'' +
'';
输出结果
UserDTOid=null, username='zhangsan', phone='null', rolename='管理员', permission='/user,/log'
可以看到,因为 phone 的属性没有设置映射,所以没有被赋值
以上是关于JavaDTOPOVO 类相互转换的工具类的主要内容,如果未能解决你的问题,请参考以下文章