BeanDtoVoUtil tool class (v-1.0.1 version), it turns out that whether it is an entity class object T or List<T> or Page<T> Entity, Dto, Vo can be converted easily, V2 version

Based on the conversion entity class object or T Page List or the Entity, Dto, Vo's also how simple the original either to improve and optimize

1. List of Entity, Dto, Vo conversion methods

method Describe Recommended level (0-5)
1、set/get Original usage 2 (see business)
2 、 cglib Dynamically generate set/get at runtime, avoid frequent create, the best performance with large data volume 5 (recommended)
3、mapstruct The set/get generated at compile time provides field mapping, type conversion function, good performance in large data volume, slightly inferior to cglib, but very close, and its function is stronger than cglib 5 (recommended)
4. CopyProperties of BeanUtils under springframework The copy provided under spring uses reflective copy, the performance is still good, and it is not ideal under a large amount of data 3 (allowed to use)
5. CopyProperties of BeanUtils under apache The copy provided by apache, using reflection copy, has poor performance 0 (Forced to disable)
6, PropertyUtils.copyProperties under apache The copy provided by apache, using reflection copy, has poor performance 0 (Forced to disable)

Two, use cglib conversion tools

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 [email protected]
 * @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 [email protected]
     * @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 [email protected]
     * @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 [email protected]
     * @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());
    }
}

Three, use mapstruct

1. Add dependencies

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>

Compile configuration

 <!-- 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. Add base conversion class

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 [email protected]
 * @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. Corresponding entity class conversion class


@Mapper(componentModel = "spring")
public abstract class AdminAuthorityConverter extends BaseConverter<AdminAuthorityDTO, AdminAuthority, AdminAuthorityVO>  {
    
    

}

Project startup will automatically generate impl compiled code, automatically implement methods in BaseConverter, and use generics to pass objects

Insert picture description here

4. Use


@Autowired
private XxxConverter  xxxConverter ;

// 根据方法自行选择
xxxConverter.toXXX(); 

  • A project written by the pure author (universal back-end management system) –> https://gitee.com/wslxm/spring-boot-plus2 , I hope friends who are interested can take a look, and I hope everyone can put forward some suggestions to fix and optimize together, Thanks for the support

  • This is the end of this article. If you find it useful, please like or pay attention to it. We will continue to update more content from time to time... Thank you for watching!

Guess you like

Origin blog.csdn.net/qq_41463655/article/details/109853416