Dozer玩转数据对象之间的映射

1,718 阅读2分钟

传统痛点在哪里?

对于分布式系统,需要在不同系统之间传递与转换域对象。因为我们不希望外部公开内部域对象,也不允许外部域对象渗入系统。
传统上,数据对象之间的映射通过手工编码(getter/setter)的方式实现,或对象组装器(或转换器)来解决,代码繁琐。

Dozer 是什么?

Dozer 是 Java Bean 到 Java Bean 映射器,它以递归方式将数据从一个对象复制到另一个对象。

通常,这些 Java Bean 将具有不同的复杂类型。Dozer 支持简单属性映射,复杂类型映射,双向映射,隐式和显式映射以及递归映射。

Dozer还不仅支持属性名称之间的映射,还支持在类型之间自动转换(大多数转换方案都是开箱即用的),且 Dozer 还允许您通过 XML / API 的方式指定自定义转换。

Dozer通常可以插入到架构中的边界(进入/退出)

Dozer 怎样集成?

一、环境配置

1、Maven工程中pom.xml增加依赖
<dependency>
    <groupId>com.github.dozermapper</groupId>
    <artifactId>dozer-core</artifactId>
    <version>6.4.0</version>
</dependency>
1、使用SpringBoot 需引入dozer-spring-boot-starter依赖
<dependency>
    <groupId>com.github.dozermapper</groupId>
    <artifactId>dozer-spring-boot-starter</artifactId>
    <version>6.2.0</version>
</dependency>

二、默认使用

1、dozer-spring-boot-starter默认为我们注入了 Dozer Mapper,可以直接使用。注意导包
    import org.dozer.Mapper;
    
    @Autowired
	private Mapper dozerMapper;
2、通过dozerMapper.map方法实现对象到对象之间属性名称一致的映射(默认支持同名 field 的双向映射,即隐式映射)
	XxxVo studentVo = dozerMapper.map(XxxDomain, XxxVo.class);

三、自定义Mapper使用

1、新建 DozerConfig.java 类
@Configuration
public class DozerConfig {

    @Bean
    public Mapper dozerMapper(){
        Mapper mapper = DozerBeanMapperBuilder.create()
                //指定 dozer mapping 的配置文件(放到 resources 类路径下即可),可添加多个 xml 文件,用逗号隔开
                .withMappingFiles("dozerBeanMapping.xml")
                .withMappingBuilder(beanMappingBuilder())
                .build();
        return mapper;
    }

    @Bean
    public BeanMappingBuilder beanMappingBuilder() {
        return new BeanMappingBuilder() {
            @Override
            protected void configure() {
                // 个性化配置添加在此
               	//默认是隐式匹配,增加参数TypeMappingOptions.wildcard(false)表示关闭
                mapping(XxxDomain.class, XxxVo.class)
                		//排除xfield2字段
                		.exclude("xfield2")
                		//为不同名的field手动配置映射关系
                        //.fields("xxxfield1", "xfield1")
                        .fields("xxxdx[0].xxxdxfield", "xfield");
            }
        };
    }
}
注意:隐式递归匹配所有 field(包括对象),甚至集合
 	通过深度匹配指定字段,匹配方式以 "." 号进行分割,集合属性可以指定索引
 	Dozer 开箱即用的功能之一就是类型转换,多数类型我们不需要手动转换类型,完全交给 Dozer即可。
    部分不可以类型转换。比如:DateString 不可以,我们需要指定 date-formate 格式。
    设置了全局/类/Field 级别的 date-format,按照优先级最高的进行格式化:Field > 类 > 全局
    	全局设置,修改 dozerBeanMapping.xml
    	mapper()方法增加参数 TypeMappingOptions.dateFormat("yyyy-MM-dd")
    当有些字段需要特殊处理的时候,我们需要实现自定义转换,也就是需要自定义 Converter,继承 DozerConverter<A, B>, 并实现其方法
    Dozer 可以通过实现 DozerEventListener 接口实现 mapping 的事件监听,在 mapping 的时候做全局业务