DozerMapper工具类

Web 开发的时候,我们往往需要构建 VO 进行返回数据给前端,那么如何给 VO 赋值呢?如果是一个对象的话,我们可以使用 SpringBoot 提供的 BeanUtils.copyProperties(source, target) 这种方式,但是如果我们需要给一个数组或者是 List 进行批量赋值的话,BeanUtils 是不能满足的,这种情况下可以使用  DozerBeanMapper 进行属性拷贝。

dozer是一个能把实体和实体之间进行转换的工具.只要建立好映射关系.就像是ORM的数据库和实体映射一样。dozer的功能比BeanUtils功能更强大,但是BeanUtils的性能更好。所以简单的同名同类型属性赋值转换使用BeanUtils,复杂的级联结构的属性赋值转换使用Dozer

  • Dozer可以实现Integer、Long等基础类型与String数据类型的属性之间的转换(只要名字相同就可以了,数据类型可以不同),BeanUtils只能做到同数据类型同名的属性之间赋值。
  • Dozer可以实现递归级联结构的对象赋值,BeanUtils(Spring包下面的)也可以
  • Dozer可以实现复杂的数据转换关系,通过xml配置的方式,BeanUtils做不到

dozer是用来两个对象之间属性转换的工具,有了这个工具之后,我们将一个对象的所有属性值转给另一个对象时,就不需要再去写重复的set和get方法了。DozerMapper相比较其他的对象转换工具,性能适中,配置比较简单便捷。看看DozerMapper的使用过程

1.引入相关的maven依赖

   <dependency>
                <groupId>com.github.dozermapper</groupId>
                <artifactId>dozer-spring-boot-starter</artifactId>
                <version>6.5.2</version>
            </dependency>
            <dependency>
                <groupId>org.osgi</groupId>
                <artifactId>osgi.core</artifactId>
                <version>6.0.0</version>
            </dependency>

2.配置相关的xml文件

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping
          http://dozermapper.github.io/schema/bean-mapping.xsd">

    <configuration>
        <stop-on-errors>false</stop-on-errors>
        <date-format>yyyy-MM-dd HH:mm:ss</date-format>
        <wildcard>true</wildcard>
        <trim-strings>true</trim-strings>

        <!-- LocalDateTime和String转换  -->
          <custom-converters>
              <converter type="com.test.ft.common.dozer.StringDateConvert">
                  <class-a>java.time.LocalDateTime</class-a>
                  <class-b>java.lang.String</class-b>
              </converter>
              <converter type="com.test.ft.common.dozer.DateToLocalDateConvert">
                  <class-a>java.util.Date</class-a>
                  <class-b>java.time.LocalDateTime</class-b>
              </converter>
          </custom-converters>
        <copy-by-references>
            <copy-by-reference>java.time.*</copy-by-reference>
        </copy-by-references>
    </configuration>
</mappings>

3.编写相关的配置类,读取xml的配置

import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import com.github.dozermapper.spring.DozerBeanMapperFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author aaa
 * @date 2023-10-24 16:59
 * @description Dozer Mapper 配置类
 */
@Configuration
public class DozerConfig {

    @Bean
    public Mapper getMapper(@Value("classpath*:/mapping/*.xml") Resource[] resources) {
        List<String> list = Arrays.stream(resources).map(r -> "mapping/" + r.getFilename()).collect(Collectors.toList());
        return DozerBeanMapperBuilder.create().withMappingFiles(list).build();

    }

    @Bean
    public DozerBeanMapperFactoryBean dozerBeanMapperFactoryBean(@Value("classpath*:/mapping/*.xml") Resource[] resources) throws IOException {
        final DozerBeanMapperFactoryBean dozerBeanMapperFactoryBean = new DozerBeanMapperFactoryBean();
        dozerBeanMapperFactoryBean.setMappingFiles(resources);
        return dozerBeanMapperFactoryBean;
    }

}

4.相关工具类代码

package com.test.ft.common.dozer;

import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import com.github.dozermapper.core.MapperModelContext;
import com.github.dozermapper.core.metadata.MappingMetadata;
import com.test.ft.common.assrt.MyAssert;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author tencent wb
 * @date 2023-10-24 17:18
 * @description
 */
public class DozerUtil {
    private static final Mapper MAPPER = DozerBeanMapperBuilder.buildDefault();


    private DozerUtil() {
    }
    public static <T, S> T convert(S source, Class<T> target) {
        Assert.notNull(source, "source can not be null");
        Assert.notNull(target, "target can not be null");
        return MAPPER.map(source, target);

    }

    private static <T, S> Collection<T> collectionConvert(Collection<S> sourceList, Class<T> target) {
        Assert.notEmpty(sourceList, "source can not be null");
        MyAssert.notNull(target,"target can not be null");
        Stream<S> stream = Optional.of(sourceList).orElse(Collections.emptyList()).stream().filter(Objects::nonNull);
        if (sourceList instanceof Set) {
            return stream.map(e -> MAPPER.map(e, target)).collect(Collectors.toSet());
        }
        return stream.map(e -> MAPPER.map(e, target)).collect(Collectors.toList());
    }

    public static <T, S> Set<T> setConvert(Set<S> sourceList, Class<T> target) {
        return (Set<T>)collectionConvert(sourceList, target);
    }

    public static <T, S> List<T> listConvert(List<S> sourceList, Class<T> target) {
        return (List<T>)collectionConvert(sourceList, target);
    }



}

 String和LocalDateTime转换,编写一个StringDateConvert.java,这个路径要配置在dozer-mapping.xml 中,代码如下:

package com.test.ft.common.dozer;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.github.dozermapper.core.DozerConverter;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author aaa
 * @description Dozer 时间类型和字符串类型转换
 */
public class StringDateConvert extends DozerConverter<String, LocalDateTime> {


    public StringDateConvert(Class<String> prototypeA, Class<LocalDateTime> prototypeB) {
        super(prototypeA, prototypeB);
    }

    @Override
    public LocalDateTime convertTo(String s, LocalDateTime localDateTime) {
        // 使用Hutool的时间工具类来转换
        return LocalDateTimeUtil.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    @Override
    public String convertFrom(LocalDateTime localDateTime, String s) {
        // 使用Hutool的时间工具类来转换
        s = LocalDateTimeUtil.format(localDateTime, "yyyy-MM-dd HH:mm:ss");
        return s;
    }
}

其他的类型转换可以参照时间转换,继承DozerConverter后重写对应的方法即可

5.测试结果

编写测试类:

测试结果:

附录,项目基本结构:

需要注意的是:Java8 的LocalDateTime可以convert成String,但是String数据不能convert成LocalDateTime

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值