SpringBoot 整合 Dozer 映射框架

简介: SpringBoot 整合 Dozer 映射框架

1. Dozer 介绍

Dozer 是一个 Java Bean 到 Java Bean 的映射器,它递归地将数据从一个对象复制到另一个对象。Dozer 是用来对两个对象之间属性转换的工具,有了这个工具之后,我们将一个对象的所有属性值转给另一个对象时,就不需要再去写重复的调用 set 和 get 方法。


最重要的是,Dozer 可以确保来自数据库的内部域对象不会渗入外部表示层或外部消费者,它还可以将域对象映射到外部 API 调用,反之亦然。

2. 为什么要使用映射框架 Dozer

映射框架在分层架构中作用很大,我们可以通过封装对特定数据对象的更改与将这些对象传播到其他层(即外部服务数据对象、域对象、数据传输对象、内部服务数据对象)来创建抽象层。 映射框架非常适合在负责将数据从一个数据对象映射到另一个数据对象的 Mapper 类型类中使用。

对于分布式系统架构而言,副作用是域对象在不同系统之间的传递。那么,我们不希望内部域对象暴露在外部,也不允许外部域对象渗入我们的系统。


数据对象之间的映射传统上是通过在对象之间复制数据的手动编码值对象组装器(或转换器)来解决的。Dozer 作为一个强大、通用、灵活、可重用和可配置的开源映射框架,节省了开发人员开发某种自定义映射器框架带来的时间成本。

3. Dozer 映射框架的使用

Dozer 的 maven 坐标:

<dependency>
    <groupId>com.github.dozermapper</groupId>
    <artifactId>dozer-core</artifactId>
    <version>6.5.0</version>
</dependency>

为了简化使用方式,Dozer 还提供了 starter,其 maven 坐标为:

<dependency>
    <groupId>com.github.dozermapper</groupId>
    <artifactId>dozer-spring-boot-starter</artifactId>
    <version>6.5.0</version>
</dependency>

下面就开始着手在 springboot 项目中使用 dozer 映射框架。工程的目录结构如下图所示:

2e718f6de6d94987ae2f2182c528d9c8.png

第一步,创建 maven 工程 dozer_demo 并配置 pom.xml 文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hzz</groupId>
    <artifactId>dozer_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/>
    </parent>
    <dependencies>
        <dependency>
            <groupId>com.github.dozermapper</groupId>
            <artifactId>dozer-spring-boot-starter</artifactId>
            <version>6.5.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

第二步,创建 UserDTO 和 UserEntity

UserDTO 类

package com.hzz.dto;
import lombok.Data;
@Data
public class UserDTO {
    private String userId;
    private String userName;
    private int userAge;
    private String address;
    private String birthday;
}

UserEntity 类

package com.hzz.entity;
import lombok.Data;
import java.util.Date;
@Data
public class UserEntity {
    private String id;
    private String name;
    private int age;
    private String address;
    private Date birthday;
}

第三步,在 resources/dozer/ 目录下创建 dozer 的全局配置文件 global.dozer.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns="http://dozermapper.github.io/schema/bean-mapping"
          xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping
                              http://dozermapper.github.io/schema/bean-mapping.xsd">
    <!--全局配置:<date-format>表示日期格式-->
    <configuration>
        <date-format>yyyy-MM-dd</date-format>
    </configuration>
</mappings>

第四步,在 resources/dozer/ 目录下创建 dozer 的映射文件 biz.dozer.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns="http://dozermapper.github.io/schema/bean-mapping"
          xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping
                             http://dozermapper.github.io/schema/bean-mapping.xsd">
    <!--描述两个类中属性的对应关系,对于两个类中同名的属性可以不映射-->
    <mapping date-format="yyyy-MM-dd">
        <class-a>com.hzz.entity.UserEntity</class-a>
        <class-b>com.hzz.dto.UserDTO</class-b>
        <field>
            <a>id</a>
            <b>userId</b>
        </field>
        <field>
            <a>name</a>
            <b>userName</b>
        </field>
        <field>
            <a>age</a>
            <b>userAge</b>
        </field>
    </mapping>
    <!--
    可以使用 map-id 指定映射的标识,在程序中通过此标识来确定使用当前这个映射关系
    -->
    <mapping date-format="yyyy-MM-dd" map-id="user">
        <class-a>com.hzz.entity.UserEntity</class-a>
        <class-b>com.hzz.dto.UserDTO</class-b>
        <field>
            <a>id</a>
            <b>userId</b>
        </field>
        <field>
            <a>name</a>
            <b>userName</b>
        </field>
        <field>
            <a>age</a>
            <b>userAge</b>
        </field>
    </mapping>
</mappings>

第五步,编写 application.yml 文件

dozer:
  mappingFiles:
    - classpath:dozer/global.dozer.xml
    - classpath:dozer/biz.dozer.xml

第六步,创建主启动类 DozerApp

package com.hzz;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DozerApp {
    public static void main(String[] args) {
        SpringApplication.run(DozerApp.class, args);
    }
}

第七步,编写单元测试 DozerTest

package com.hzz;
import com.github.dozermapper.core.Mapper;
import com.hzz.dto.UserDTO;
import com.hzz.entity.UserEntity;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DozerApp.class)
public class DozerTest {
    @Autowired
    private Mapper mapper;
    @Test
    public void testDozer() {
        UserDTO userDTO = new UserDTO();
        userDTO.setUserId("100");
        userDTO.setUserName("ls");
        userDTO.setUserAge(2);
        userDTO.setAddress("bj");
        userDTO.setBirthday("2020-07-04");
        UserEntity user = mapper.map(userDTO, UserEntity.class);
        System.out.println(user);
    }
    @Test
    public void testDozer2(){
        UserDTO userDTO = new UserDTO();
        userDTO.setUserId("100");
        userDTO.setUserName("ls");
        userDTO.setUserAge(5);
        userDTO.setAddress("bj");
        userDTO.setBirthday("2017-07-04");
        UserEntity user = new UserEntity();
        user.setId("200");
        System.out.println(user);
        mapper.map(userDTO, user);
        System.out.println(user); //被 userDTO 覆盖了
    }
    @Test
    public void testDozer3(){
        UserDTO userDTO = new UserDTO();
        userDTO.setUserId("100");
        userDTO.setUserName("zs");
        userDTO.setUserAge(3);
        userDTO.setAddress("bj");
        UserEntity user = new UserEntity();
        System.out.println(user);
        mapper.map(userDTO,user,"user"); //指定映射ID为user
        System.out.println(user);
    }
}
相关文章
|
1天前
|
缓存 Java Maven
深入解析Google Guava库与Spring Retry重试框架
深入解析Google Guava库与Spring Retry重试框架
5 0
|
1天前
|
Java 数据处理 数据库
深入解析Spring Batch:企业级批处理框架的技术之旅
深入解析Spring Batch:企业级批处理框架的技术之旅
7 0
|
1天前
|
前端开发 Java 开发工具
如何在Spring Boot框架下实现高效的Excel服务端导入导出?
ArtifactId:是项目的唯一标识符,在实际开发中一般对应项目的名称,就是项目根目录的名称。 Group Id,Artfact Id是保证项目唯一性的标识,一般来说如果项目打包上传至maven这样的包管理仓库中。在搜索你的项目时,Group Id,Artfact Id是必要的条件。 Version:版本号,默认0.0.1-SNAPSHOT。SNAPSHOT代表不稳定的版本,与之相对的有RELEASE。 Project type:工程的类型,maven工程还是gradle工程。 Language:语言(Java,Kotlin,Groovy)。
|
1天前
|
缓存 Java 数据库连接
spring中注解驱动事务框架的源码
spring中注解驱动事务框架的源码
4 0
|
2天前
|
Java 开发者 Spring
Spring 框架:Java 企业应用开发的“瑞士军刀”,一网打尽所有需求!
【6月更文挑战第25天】Spring框架是Java开发的“瑞士军刀”,以其DI(依赖注入)减少手动管理,提高效率。AOP(面向切面编程)实现非侵入式关注点分离,如日志和事务管理。@Transactional注解简化事务处理,Web支持使Web应用开发更便捷。通过这些工具,Spring解决了复杂需求,增强了代码的可维护性和性能。
|
2天前
|
Java 数据库 Spring
解锁 Spring 框架新姿势,让你的 Java 代码更加优雅!
【6月更文挑战第25天】在Spring框架中优化依赖注入、应用AOP和事务管理能提升代码优雅性。例如,使用构造函数注入降低耦合,如将手动创建改为容器管理;通过AOP实现横切关注点,如统一日志记录,避免重复代码;利用`@Transactional`注解简化事务处理,确保数据一致性。这些技巧让代码更简洁、可维护。
|
2天前
|
前端开发 Java 开发者
那些年,我们与 Spring 框架一起走过的路……
【6月更文挑战第25天】Spring框架简化了Java开发,通过依赖注入降低了耦合,如`@Autowired`自动装配bean。AOP允许横切关注点(如日志和事务)模块化,如`@Before`和`@AfterReturning`定义切面。`@Transactional`注解轻松实现事务管理,保证数据一致性。Spring MVC在Web开发中提供注解驱动和简洁路由,提升效率。它伴随开发者成长,不断优化解决方案。
|
2天前
|
前端开发 Java 开发者
Spring 框架:Java 企业应用开发领域的“隐形冠军”!
【6月更文挑战第25天】Spring框架在Java开发中扮演重要角色,提倡依赖注入、事务管理及面向切面编程的最佳实践。例如,通过`@Autowired`实现接口注入,保持代码松耦合;使用`@Transactional`确保数据一致性;借助`@Aspect`定义AOP切面,分离关注点;使用Java配置增强可维护性;以及在Spring MVC中利用注解驱动提升Web应用效率。遵循这些最佳实践,开发者能打造高效、可扩展的应用。
|
2天前
|
Java 开发者 Spring
从入门到精通,Spring 框架带你玩转 Java 企业应用开发!
【6月更文挑战第25天】Spring框架简化了Java企业开发,通过依赖注入降低耦合,如使用构造函数注入`UserService`中的`UserDao`。它还提供声明式事务管理,如`@Transactional`注解自动处理事务,减少手动错误。此外,Spring的AOP支持允许在不侵入业务逻辑的情况下实现横切关注点,如`LoggingAspect`所示。无论是新手还是资深开发者,Spring以其全面的功能和灵活性成为企业应用开发的强大工具。
|
2天前
|
缓存 Java 测试技术
Spring 框架,不只是依赖注入和面向切面那么简单!
【6月更文挑战第25天】Spring框架超越DI和AOP,涵盖事务管理、数据访问抽象如`JdbcTemplate`、消息驱动支持如`@JmsListener`、缓存管理和测试工具。示例代码展示了其简化复杂性的能力,如自动事务处理、数据库操作及消息队列监听。Spring是构建高效企业级应用的全面解决方案。