BeanDtoVoUtil 工具类( v-1.0.1 版本) , 原来不管是实体类对象T 还是List<T> 还是Page<T> 的Entity、Dto、Vo的相互转换还能怎么简单,V2版本
程序员文章站
2022-07-10 17:53:57
package com.ws.ldy.common.utils;import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import net.sf.cglib.beans.BeanCopier;import java.util.ArrayList;import java.util.List;import java....
本文基于 原来不管是实体类对象T 还是List 还是Page 的Entity、Dto、Vo的相互转换还能怎么简单 改进并优化
一、Entity、Dto、Vo 转换方式一览
方法 | 描叙 | 推荐级别(0-5) |
---|---|---|
1、set/get | 原始使用方法 | 2 (看业务) |
2、cglib | 运行时动态生成 set/get ,需避免频繁create,大数据量性能最佳, | 5 (推荐使用) |
3、mapstruct | 编译时生成的set/get, 提供字段映射,类型转换功能, 大数据量性能佳,略逊与cglib, 不过很接近, 功能比cglib 强 | 5 (推荐使用) |
4、springframework下的 BeanUtils 的 copyProperties | spring 下提供的拷贝,使用反射拷贝,性能尚佳, 大量数据下不太理想 | 3 (允许使用) |
5、apache 下的 BeanUtils 的 copyProperties | apache 提供的拷贝,使用反射拷贝, 性能差 | 0 (强制禁用) |
6、apache 下的 PropertyUtils.copyProperties | apache 提供的拷贝,使用反射拷贝,性能差 | 0 (强制禁用) |
二、使用cglib 转换工具类
package com.ws.ldy.common.utils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.sf.cglib.beans.BeanCopier;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* Dto,Vo,entity 转换工具类
*
* @param1 oldClass 原数据--Dto,Vo,entity
* @param1 newClass 转换为--Dto,Vo,entity
* @author wangsong
* @mail 1720696548@qq.com
* @date 2020/11/20 0020 16:22
* @version 1.0.1 (与版本0.0.7更新)
*/
public class BeanDtoVoUtil<V, E> {
/**
* BeanCopier的缓存
*/
static final ConcurrentHashMap<String, BeanCopier> BEAN_COPIER_CACHE = new ConcurrentHashMap<>();
/**
* dot ,do ,entity 相互转换(使用cglib)
* <P>
* 1、使用 cglib, 几乎无性能损耗, 和 mapstruct 和 get/set 性能不相上下,甚至更快
* ---- mapstruct 在 编译时生成class文件的set,get方法,功能更全,支持属性key不一致,属性类型不一致的配置替换
* ---- cglib 在 BeanCopier.create动态生成set/get方法,功能单一,但性能可观,注意避免频繁 BeanCopier.create, 会重复动态生成get/set,将达不到预期的性能效果
*
* 2、使用 springboot的
* ---- BeanUtils.copyProperties(oldClass, newInstance);
*
* 3、使用 mapstruct
* ---- 参考 AdminAuthorityConverter 转换类,启动项目会动态生成 AdminAuthorityConverterImpl的calss类,并生成转换方法
* </P>
*
* @param oldClass 原数据--Dto,Vo,entity
* @param newClass 转换为--Dto,Vo,entity
* @return
*/
public static <E> E convert(Object oldClass, Class<E> newClass) {
if (oldClass == null) {
return null;
}
if (newClass == null) {
return null;
}
E newInstance = null;
try {
newInstance = newClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
String key = oldClass.getClass().getName() + ":" + newClass.getName();
BeanCopier copier = null;
if (BEAN_COPIER_CACHE.containsKey(key)) {
copier = BEAN_COPIER_CACHE.get(key);
} else {
copier = BeanCopier.create(oldClass.getClass(), newInstance.getClass(), false);
BEAN_COPIER_CACHE.put(key, copier);
}
copier.copy(oldClass, newInstance, null);
return newInstance;
}
/**
* Page<Entity> 分页对象转 Page<Vo>
*
* @param page
* @param v
* @return com.baomidou.mybatisplus.core.metadata.IPage<V>
* @author ws
* @mail 1720696548@qq.com
* @date 2020/4/23 0023 11:26
*/
public static <T, V> IPage<V> pageVo(Page<T> page, Class<V> v) {
if (page == null) {
return null;
}
return page.convert(item -> BeanDtoVoUtil.convert(item, v));
}
/**
* list<Entity> 集合对象转list<Vo> ( list 循环)
*
* @param oldList
* @param v
* @return com.baomidou.mybatisplus.core.metadata.IPage<V>
* @author ws
* @mail 1720696548@qq.com
* @date 2020/4/23 0023 11:26
*/
public static <T, V> List<V> listVo(List<T> oldList, Class<V> v) {
if (oldList == null) {
return null;
}
List<V> voList = new ArrayList<>();
oldList.forEach(i -> voList.add(BeanDtoVoUtil.convert(i, v)));
return voList;
}
/**
* list<Entity> 集合对象转list<Vo> (Stream 方式)
*
* @param oldList
* @param v
* @return com.baomidou.mybatisplus.core.metadata.IPage<V>
* @author ws
* @mail 1720696548@qq.com
* @date 2020/4/23 0023 11:26
*/
public static <T, V> List<V> listVoStream(List<T> oldList, Class<V> v) {
if (oldList == null || oldList.size() == 0) {
return null;
}
return oldList.stream().map(item -> (V) BeanDtoVoUtil.convert(item, v)).collect(Collectors.toList());
}
}
三、使用 mapstruct
1、添加依赖
jar
<org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
<!-- mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
编译配置
<!-- mapstruct 插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<!-- 编译时使用 mapstruct + lombok -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
2、添加 base 转换类
package com.ws.ldy.others.base.converter;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
/**
* 实体类转换工具, mapstruct ,子类自动生成 class代码
* <P>
* D dto -- 请求参数
* E entity -- 实体类,对应DB
* V vo -- 响应参数
* </P>
* @author wangsong
* @mail 1720696548@qq.com
* @date 2020/11/20 0020 12:02
* @version 1.0.0
*/
public abstract class BaseConverter<D, E, V> {
public abstract D toDTO(E e);
public abstract List<D> toDTO(List<E> e);
public abstract E toEntity(D d);
public abstract List<E> toEntity(List<D> d);
public abstract V toVO(E e);
public abstract List<V> toVO(List<E> e);
/**
* mybatis-plus Page 装换 , 需要连接数据库和依赖包,不做演示
* @param page
* @return
*/
public IPage<V> toPage(IPage<E> page) {
if (page == null) {
return null;
}
return page.convert(this::toVO);
}
}
3、对应实体类转换类
@Mapper(componentModel = "spring")
public abstract class AdminAuthorityConverter extends BaseConverter<AdminAuthorityDTO, AdminAuthority, AdminAuthorityVO> {
}
项目启动会自动生成 impl 的编译后的代码, 自动实现 BaseConverter 中的方法, 使用泛型传递对象
4、使用
@Autowired
private XxxConverter xxxConverter ;
// 根据方法自行选择
xxxConverter.toXXX();
-
纯作者个人编写的项目(通用后台管理系统)–> https://gitee.com/wslxm/spring-boot-plus2 , 希望感兴趣的朋友可以看看,也希望大家提出一些建议来一起修正优化, 感谢支持
-
本文到此结束,如果觉得有用,动动小手点赞或关注一下呗,将不定时持续更新更多的内容…,感谢大家的观看!
本文地址:https://blog.csdn.net/qq_41463655/article/details/109853416
上一篇: H5页面基于接口实现数据交互