PO与DTO互转

DTO(Data Transfer Object)和 PO(Persistent Object)是两种不同的数据对象,它们在不同的场景下使用。
DTO 用于在不同的应用程序组件之间传输数据。它通常是轻量级的,只包含必要的字段,并且不包含任何业务逻辑。
PO  用于持久化数据到数据库。它通常是重量级的,包含所有必要的字段,并且包含业务逻辑。

1、以下是 DTO 和 PO 的比较


    1.1、用途 

        DTO: 用于在不同的应用程序组件之间传输数据 
        PO:  用于持久化数据到数据库
    

    1.2、重量 

        DTO: 轻量级 
        PO:  重量级
    

     1.3、字段 

        DTO:只包含必要的字段 
        PO: 包含所有必要的字段

    1.4、业务逻辑 

        DTO:不包含任何业务逻辑 
        PO: 包含业务逻辑 

2、分层

    在实际开发中,我们通常会使用 DTO 和 PO 来分离数据层和业务层。

    DTO 位于数据层,用于在不同的应用程序组件之间传输数据。
    PO 位于业务层,用于持久化数据到数据库。

3、PO与DTO互转示例


3.1、UserDTO

是用于在不同的应用程序组件之间传输数据的轻量级对象。

public class UserDTO {

    private String username;
    private String password;
    private String email;
    public UserDTO(){}

    public UserDTO(String username, String password, String email) {
        this.username = username;
        this.password = password;
        this.email = email;
    }

    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 getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

3.2、UserPO  

是用于持久化数据到数据库的重量级对象。

public class UserPO {

    private Long id;
    private String username;
    private String password;
    private String email;
    public UserPO(){}

    public UserPO(Long id, String username, String password, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.email = email;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long 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 getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

4、使用ModelMapper

4.1、在pom.xml文件中,引入ModelMapper依赖


	org.modelmapper
	modelmapper
	3.1.1

    4.2、示例

    import org.modelmapper.ModelMapper;
    public UserPO testModelMapper(){
        // 创建一个 ModelMapper 对象
        ModelMapper modelMapper = new ModelMapper();

        // 创建一个 DTO 对象
        UserDTO userDTO = new UserDTO();
        userDTO.setUsername("张三");
        userDTO.setPassword("123456");
        userDTO.setEmail("[email protected]");

        // 将 DTO 对象转换为 PO 对象
        UserPO userPO = modelMapper.map(userDTO, UserPO.class);

        return userPO;
    }

5、使用orika

5.1、在pom.xml文件中,引入orika依赖

		
        	ma.glasnost.orika
         	orika-core
        	1.5.4
     	 

5.2、 示例

5.2.1、OrikaUtil 工具类
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.metadata.ClassMapBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author zhongyushi
 * https://www.cnblogs.com/zys2019/p/17005798.html#_label1_2
 */
@Component
public class OrikaUtil {
    @Resource
    private MapperFactory mapperFactory;

    /**
     * 字段映射
     *
     * @param aType  源对象类型
     * @param bType  目标对象类型
     * @param fields 不同字段映射值
     * @param 
     * @param 
     */
    private  void filedMap(Class aType, Class bType, Map fields) {
        ClassMapBuilder mapBuilder = mapperFactory.classMap(aType, bType);
        if (fields != null && fields.size() > 0) {
            Set> entries = fields.entrySet();
            for (Map.Entry entry : entries) {
                mapBuilder.field(entry.getKey(), entry.getValue());
            }
        }
        mapBuilder.byDefault().register();
    }

    /**
     * 对象的复制
     *
     * @param aType  源对象类型
     * @param bType  目标对象类型
     * @param fields 不同字段映射值
     * @param source 要复制的对象
     * @param 
     * @param 
     * @return
     */
    public  B beanCopy(Class aType, Class bType, Map fields, A source) {
        filedMap(aType, bType, fields);
        B target = mapperFactory.getMapperFacade().map(source, bType);
        return target;
    }

    /**
     * 对象的复制
     *
     * @param aType  源对象类型
     * @param bType  目标对象类型
     * @param source 要复制的对象
     * @param 
     * @param 
     * @return
     */
    public  B beanCopy(Class aType, Class bType, A source) {
        return beanCopy(aType, bType, null, source);
    }

    /**
     * 集合的复制
     *
     * @param aType  源对象类型
     * @param bType  目标对象类型
     * @param fields 不同字段映射值
     * @param source 要复制的对象
     * @param 
     * @param 
     * @return
     */
    public  List beanListCopy(Class aType, Class bType, Map fields, Iterable source) {
        filedMap(aType, bType, fields);
        List bList = mapperFactory.getMapperFacade().mapAsList(source, bType);
        return bList;
    }

    /**
     * 集合的复制
     *
     * @param aType  源对象类型
     * @param bType  目标对象类型
     * @param source 要复制的对象
     * @param 
     * @param 
     * @return
     */
    public  List beanListCopy(Class aType, Class bType, Iterable source) {
        return beanListCopy(aType, bType, null, source);
    }
}
5.2.2、配置类
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * orika
 */
@Configuration
public class MapperFactoryAutoConfig {

    @Bean
    public MapperFactory getFactory(){
        return new DefaultMapperFactory.Builder().build();
    }

}
5.2.3、测试示例
import cn.example.demo.dto.UserDTO;
import cn.example.demo.dto.UserPO;
import cn.example.demo.utils.OrikaUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Autowired
private OrikaUtil orikaUtil;

/**
* 单个对象
* @return
*/
public UserPO orika0() {
        UserDTO userDto = new UserDTO("orika0", "123", "[email protected]");
        Map map = new HashMap<>();
        //map.put("password", "password1");//有差异的属性名称
        UserPO userPo = orikaUtil.beanCopy(UserDTO.class, UserPO.class, map, userDto);
        System.out.println(userPo);
        return userPo;
}


/**
* 对象列表转换
* 10万条耗时 583 ms
*/
public List orika1() {
        Integer t = 100000;
        List list = new ArrayList<>();
        for (int i = 0; i < t; i++) {
            UserDTO userDto = new UserDTO("orika" + i, "111"+ i, "orika"+ i+"@qq.com");
            list.add(userDto);
        }

        Map map = new HashMap<>();
        //map.put("age", "userAge"); //名称不同的属性之间映射
        StopWatch watch = new StopWatch();
        watch.start("orika");
        List poList = orikaUtil.beanListCopy(UserDTO.class, UserPO.class, map, list);
        System.out.println(poList);
        watch.stop();
        System.out.println("orika 复制用时:" + watch.getLastTaskTimeMillis());

        return poList;
}

6、使用 dozer

6.1、在pom.xml文件中,引入dozer依赖


  com.github.dozermapper
  dozer-core
  6.5.0

6.2、示例

import cn.example.demo.dto.UserDTO;
import cn.example.demo.dto.UserPO;
import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//参考地址:
//https://dozermapper.github.io/user-guide.pdf
//https://www.jb51.net/article/239801.htm
//https://blog.csdn.net/weixin_33786077/article/details/94759020

public List dozer() {
        List list = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            UserDTO userDto = new UserDTO("dozer" + i, "111"+ i, "dozer"+ i+"@qq.com");
            list.add(userDto);
        }


        List poList = new ArrayList<>();
        Mapper mapper = DozerBeanMapperBuilder.buildDefault();
        StopWatch watch = new StopWatch();
        watch.start("dozer");
        list.stream().forEach(item -> {
            UserPO userPo = mapper.map(item, UserPO.class);
            poList.add(userPo);
            System.out.println("userPo:" + item.hashCode());
        });
        watch.stop();
        System.out.println("dozer复制用时:" + watch.getLastTaskTimeMillis());
   return poList;
}

7、MapStruct

参考地址:https://mapstruct.org/

8、JMapper

参考地址:https://github.com/jmapper-framework/jmapper-core

你可能感兴趣的:(第三方工具,java,笔记)