前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >映射器-Dozer

映射器-Dozer

作者头像
码农王同学
发布2020-03-25 11:00:31
8160
发布2020-03-25 11:00:31
举报
文章被收录于专栏:后端Coder

今天要分享的是映射器-dozer,以往我们在编写代码时总会有对象之间互相转换,比较常规使用的方式是使用工具类进行字段之间的映射或者定义新的类使用get/set方法进行转换,一堆代码看着确实别扭了很多。

代码语言:javascript
复制
DTO:数据传输对象

那么,什么是dozer呢?

代码语言:javascript
复制
Dozer是java Bean到Java Bean的映射器,它以递归的方式将数据从一个对象复制到另外一个对象。
Dozer支持简单属性映射,双向映射,隐形映射以及递归映射。使用dozer映射器可以很方便的在我们的项目中进行
对象之间的转换。

我这里采用springBoot进行整合dozer的方式进行编写和配置dozer,首先我们先看下我们的pom文件吧。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.wpw</groupId>
    <artifactId>springboot-dozer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-dozer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>net.sf.dozer</groupId>
            <artifactId>dozer</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.dozer</groupId>
            <artifactId>dozer</artifactId>
            <version>5.5.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

上面的pom文件仅仅是将项目作为一个web应用程序,引入dozer需要的jar包依赖。

下面,我们先定义一个dozer配置,让其装载入spring容器。

代码语言:javascript
复制
package com.wpw.springbootdozer;

import org.dozer.DozerBeanMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * @author pc
 */
@Configuration
@Scope("singleton")
public class DozerConfig {
    @Bean
    public DozerBeanMapper mapper(){
        DozerBeanMapper mapper=new DozerBeanMapper();
        return mapper;
    }
}
代码语言:javascript
复制
@Configuration注解,表示这是一个配置类,里面包含了@Component注解,标注这是一个可以用spring管理的对象示例。
@Scope注解,表示实例的作用域,这里使用了singleton表示这是一个单例,想使用多例的可以用prototype。

下面,我们继续看下我们使用dozer需要定义的方法和实现类。

代码语言:javascript
复制
package com.wpw.springbootdozer;

import java.util.List;
import java.util.Set;

/**
 * @author pc
 */
public  interface DozerInterface {

    /**
     * 单个对象的深度复制及类型转换
     * @param source 数据对象
     * @param clazz 复制目标类型
     * @param <T>
     * @param <S>
     */
    <T, S> T convert(S  source, Class<T> clazz) ;

    /**
     * list深度复制
     * @param sourceList 数据对象列表
     * @param clazz 复制目标类型
     * @param <T>
     * @param <S>
     */
    <T,S> List<T> convert(List<S> sourceList, Class<T> clazz);

    /**
     * set列表深度复制
     * @param sourceSet 数据set集合列表
     * @param clazz 复制目标类型
     * @param <T>
     * @param <S>
     * @return
     */
    <T,S> Set<T> convert(Set<S> sourceSet, Class<T> clazz);

    /**
     * 数组深度复制
     * @param s 数据对象
     * @param clazz 复制目标类型
     * @param <T>
     * @param <S>
     * @return
     */
    <T,S> T[] convert(S[] s,Class<T> clazz);
}

上面定义了接口的基本方法,为下面要分享的dozer工具类做下铺垫。

代码语言:javascript
复制
package com.wpw.springbootdozer;

import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.lang.reflect.Array;
import java.util.*;

@Component
@Lazy(value = true)
public class DozerUtil implements DozerInterface {
    @Autowired
    private Mapper mapper;

    @Override
    public <T, S> T convert(S source, Class<T> clazz) {
        if (Objects.isNull(source)) {
            return null;
        }
        return this.mapper.map(source, clazz);
    }

    @Override
    public <T, S> List<T> convert(List<S> sourceList, Class<T> clazz) {
        if (Objects.isNull(sourceList)) {
            return null;
        }
        List<T> list = new ArrayList<>(sourceList.size());
        for (S s : sourceList) {
            list.add(this.mapper.map(s, clazz));
        }
        return list;
    }

    @Override
    public <T, S> Set<T> convert(Set<S> sourceSet, Class<T> clazz) {
        if (sourceSet==null){
            return null;
        }
        Set<T> set=new HashSet<>(sourceSet.size());
        for (S s:sourceSet){
            set.add(this.mapper.map(s,clazz));
        }
        return set;
    }

    @Override
    public <T, S> T[] convert(S[] s, Class<T> clazz) {
        if (Objects.isNull(s)){
            return null;
        }
        T[] arr= (T[]) Array.newInstance(clazz,s.length);
        for (int i = 0; i <s.length ; i++) {
            arr[i]=this.mapper.map(s[i],clazz);
        }
        return arr;
    }
}

基于dozer需要的配置类信息就到这里结束了,我们这里为了演示dozer定义了两个基本类。

代码语言:javascript
复制
package com.wpw.springbootdozer;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * @author pc
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Accessors(chain = true)
public class UserDto implements Serializable {
    private String userCode;
    private String loginName;
    private String loginPassword;
    private String  deviceCode;
    private String systemCode;
}
代码语言:javascript
复制
package com.wpw.springbootdozer;

import lombok.Data;

import java.io.Serializable;

@Data
public class UserVo  implements Serializable {
    private String userCode;
    private String loginName;
    private String loginPassword;
}

这里自己使用了单元测试的方法进行dozer映射器的测试,实际中也仅仅在业务逻辑层进行对象信息的转换。

代码语言:javascript
复制
package com.wpw.springbootdozer;

import jdk.nashorn.internal.ir.annotations.Ignore;
import org.dozer.Mapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashSet;
import java.util.Set;

@SpringBootTest
class SpringbootDozerApplicationTests {
    @Autowired
    private DozerUtil dozerUtil;
    @Autowired
    private Mapper mapper;
    @Test
    @Ignore
    void contextLoads() {
        UserDto userDto = UserDto.builder().build().setUserCode("0001").setSystemCode("systemCode").setLoginName("WwpwW").setLoginPassword("123456").setDeviceCode("0001");
        UserVo userVo = mapper.map(userDto, UserVo.class);
        System.out.println("userVo = " + userVo);
    }
    @Test
    public void test(){
        Set<UserDto> dtoSet=new HashSet<>();
        UserDto userDto = UserDto.builder().build().setUserCode("0002");
        dtoSet.add(userDto);
        Set<UserVo> userVoSet = dozerUtil.convert(dtoSet, UserVo.class);
        userVoSet.stream().forEach(System.out::println);
    }
}

我们可以看下控制台打印的数据信息,UserDto对象的数据是不是已经映射到UserVo对象里面。

代码语言:javascript
复制
UserVo(userCode=0002, loginName=null, loginPassword=null)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农王同学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档