spring boot集成Dozer轉換器

Dozer轉換,一個強大的對象屬性轉換器,能夠快速的在實體bean,vo,do之間轉換,在項目中集成Dozer,能夠讓提升我們的開發速率,下面主要是說說在spring boot中的集成,其他框架類似。

1、添加maven依賴

<dependency>
   <groupId>net.sf.dozer</groupId>
   <artifactId>dozer</artifactId>
   <version>5.4.0</version>
   <exclusions>
      <!--目前項目中使用的是apache自帶的log4j-->
      <exclusion>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-log4j12</artifactId>
      </exclusion>
      <!--<exclusion>
         <groupId>log4j</groupId>
         <artifactId>log4j</artifactId>
      </exclusion>-->
   </exclusions>
</dependency>

2、創建Dozer bean,在真正的項目中,我們不能每使用一次就創建一個dozer轉換實例,這樣會大大降低系統的性能,所以一般都是創建單實例,並且交給spring 容器進行管理。

dozer集成官方文檔中主要有三種方式。

A、使用註解方式

創建bean

@Configuration
public class DozerBeanMapperConfigure {

    @Bean
    public DozerBeanMapper mapper() {
        DozerBeanMapper mapper = new DozerBeanMapper();
        return mapper;
    }

}

轉換對象:

public class SourceBean {

    private Long id;

    private String name;

    @Mapping("binaryData")
    private String data;

    @Mapping("pk")
    public Long getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }
} 
public class TargetBean {

    private String pk;

    private String name;

    private String binaryData;

    public void setPk(String pk) {
        this.pk = pk;
    }

    public void setName(String name) {
        this.name = name;
    }
}       

此種方式最簡便,但是官方中只有一個註釋@Mapping,因此只能應對簡便的映射關係,官方提醒如下:

WARNING: Annotation support in Dozer is experimental and does not cover complex use cases yet. However it may be useful to implement that simplest mappings you have had to do in Xml or API before.

意思是如果想要使用更復雜的映射,就只能使用xml配置,或者API方式

B、使用API方式

此種方式在創建的時候需要制定對應的BeanMappingBuilder,

官方例子:

import static org.dozer.loader.api.FieldsMappingOptions.*;
import static org.dozer.loader.api.TypeMappingOptions.*;

...

BeanMappingBuilder builder = new BeanMappingBuilder() {
      protected void configure() {
        mapping(Bean.class, Bean.class,
                TypeMappingOptions.oneWay(),
                mapId("A"),
                mapNull(true)
        )
                .exclude("excluded")
                .fields("src", "dest",
                        copyByReference(),
                        collectionStrategy(true, 
                            RelationshipType.NON_CUMULATIVE),
                        hintA(String.class),
                        hintB(Integer.class),
                        FieldsMappingOptions.oneWay(),
                        useMapId("A"),
                        customConverterId("id")
                )
                .fields("src", "dest",
                    customConverter("org.dozer.CustomConverter")
                );
      }
    };
DozerBeanMapper mapper = new DozerBeanMapper();
mapper.addMapping(builder);

個人例子:

@Configuration
public class DozerBeanMapperConfigure {

    @Bean
    public DozerBeanMapper mapper(){
        DozerBeanMapper mapper = new DozerBeanMapper();
        mapper.addMapping(beanMappingBuilder);
        mapper.addMapping(beanMappingBuilder1);
        return mapper;
    }
    BeanMappingBuilder beanMappingBuilder = new BeanMappingBuilder() {
        @Override
        protected void configure() {            //a-->>b-->>a' ==>>a != a'
            mapping(User.class, UserVo.class, TypeMappingOptions.oneWay())
                    .fields("teacher.name","teacherName" );

        }
    };
    BeanMappingBuilder beanMappingBuilder1 = new BeanMappingBuilder() {
        @Override
        protected void configure() {
            mapping(User.class, UserVo2.class, TypeMappingOptions.oneWay())
                    .fields("teacher.name","teacherName" );
        }
    };
}
或者不想添加多個builder的話,也可以添加多個mapping(),如下:

@Configuration
public class DozerBeanMapperConfigure {

    @Bean
    public DozerBeanMapper mapper(){
        DozerBeanMapper mapper = new DozerBeanMapper();
        mapper.addMapping(beanMappingBuilder);
        return mapper;
    }
    BeanMappingBuilder beanMappingBuilder = new BeanMappingBuilder() {
        @Override
        protected void configure() {            //a-->>b-->>a' ==>>a != a'
            mapping(User.class, UserVo.class, TypeMappingOptions.oneWay())
                    .fields("teacher.name","teacherName" );
            mapping(User.class, UserVo2.class, TypeMappingOptions.oneWay())
                    .fields("teacher.name","teacherName" );

        }
    };
}

此種方式,可以解決較爲複雜的映射關係,基本可以滿足項目的需求,但是官方的解釋說,有些特殊的複雜關係,其實是隻能使用XML配置的,所以官方更傾向於使用xml配置的方式,官方解釋:API mappings are intended to solve all of the mentioned problems. In fact some parts of the configuration (e.g. global configuration block) are only possible to express in Xml format.

C、第三種方式,使用XML配置的方式,Xml配置雖然對異常等信息的提示很不足,但是在配置方面卻很強大,官方極力推薦使用,

創建bean,需要制定需要加載的xmp配置文件的路徑,並且需要制定到具體的文件名

@Configuration
public class DozerBeanMapperConfigure {

    @Bean
    public DozerBeanMapper mapper() {
        DozerBeanMapper mapper = new DozerBeanMapper();
        mapper.setMappingFiles(Arrays.asList("mapping/UserMapping.xml"));
        return mapper;
    }

}
對應的xml配置文件如下
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
          http://dozer.sourceforge.net/schema/beanmapping.xsd">
    <mapping>
        <class-a map-null="false">com.example.springboot.Entity.User</class-a>
        <class-b map-null="false">com.example.springboot.EntityVo.UserVo</class-b>
        <field>
            <a>teacher.name</a>
            <b>teacherName</b>
        </field>
    </mapping>
 </mappings>

此種方式可以解決Dozer轉換的所有問題,當然,上面只是一個小小的例子,更多配置可參考官方文檔:http://dozer.sourceforge.net/documentation/mappings.html,裏面很詳細的講解Xml的各種配置問題










發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章