SpringBoot2.x集成Dozer的示例代碼
Dozer是Java Bean到Java Bean的映射器,它以遞歸的方式將數(shù)據(jù)從一個(gè)對(duì)象復(fù)制到另一個(gè)對(duì)象。通常,這些Java Bean將具有不同的復(fù)雜類型。它支持簡(jiǎn)單屬性映射,復(fù)雜類型映射,雙向映射,隱式顯式映射,以及遞歸映射。這包括映射需要在元素層面上進(jìn)行映射的集合屬性??梢詫ozer用作兩個(gè)對(duì)象之間屬性轉(zhuǎn)換的工具,使用它可以很方便地對(duì)項(xiàng)目中的DO、DTO、VO進(jìn)行相互轉(zhuǎn)換。
本文主要對(duì)SpringBoot2.x集成Dozer及其基本使用進(jìn)行簡(jiǎn)單總結(jié),其中SpringBoot使用的2.4.5版本。
一、引入依賴
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-spring-boot-starter</artifactId>
<version>6.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- lombok插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
二、實(shí)體類
User類:
package com.rtxtitanv.model;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author rtxtitanv
* @version 1.0.0
* @name com.rtxtitanv.model.User
* @description User
* @date 2021/8/18 16:45
*/
@Accessors(chain = true)
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String gender;
private String email;
private Date birthday;
}
UserDTO類:
package com.rtxtitanv.model;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author rtxtitanv
* @version 1.0.0
* @name com.rtxtitanv.model.UserDTO
* @description UserDTO
* @date 2021/8/18 16:45
*/
@Accessors(chain = true)
@Data
public class UserDTO {
private Long userId;
private String userName;
private Integer userAge;
private String gender;
private String email;
private String birthday;
}
三、編寫配置文件
resources/dozer/目錄下創(chuàng)建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 HH:mm:ss</date-format>
</configuration>
</mappings>
resources/dozer/目錄下創(chuàng)建Dozer的映射文件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">
<!-- 描述兩個(gè)類中屬性的對(duì)應(yīng)關(guān)系,對(duì)于兩個(gè)類中同名的屬性可以不映射 -->
<mapping date-format="yyyy/MM/dd HH:mm:ss">
<class-a>com.rtxtitanv.model.User</class-a>
<class-b>com.rtxtitanv.model.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>
resources目錄下創(chuàng)建application.yml配置文件:
dozer:
# 指定Dozer的映射配置文件位置
mapping-files:
- classpath:dozer/global-dozer.xml
- classpath:dozer/dozer.xml
四、創(chuàng)建測(cè)試類
創(chuàng)建單元測(cè)試類DozerTest:
package com.rtxtitanv;
import com.github.dozermapper.core.Mapper;
import com.rtxtitanv.model.*;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
/**
* @author rtxtitanv
* @version 1.0.0
* @name com.rtxtitanv.DozerTest
* @description Dozer單元測(cè)試類
* @date 2021/8/18 16:44
*/
@Slf4j
@SpringBootTest
class DozerTest {
@Resource
private Mapper mapper;
@Test
void test1() {
UserDTO userDTO = new UserDTO();
userDTO.setUserId(1L).setUserName("ZhaoYun").setGender("男").setUserAge(20).setEmail("zhaoyun@xxx.com")
.setBirthday("2001/8/18 18:05:32");
User user = mapper.map(userDTO, User.class);
log.info(user.toString());
UserDTO userDTO2 = mapper.map(user, UserDTO.class);
log.info(userDTO2.toString());
}
}
執(zhí)行測(cè)試方法,發(fā)現(xiàn)User和UserDTO相互轉(zhuǎn)換成功:

五、Dozer的基本使用
下面對(duì)Dozer的一些基本使用進(jìn)行總結(jié)。Dozer支持注解、API、XML三種映射配置方式,XML方式比較常用,前面使用的也是XML映射配置方式。XML映射配置中mapping元素的map-id屬性可以設(shè)置該映射的標(biāo)識(shí),通過(guò)此標(biāo)識(shí)來(lái)確定使用該映射關(guān)系。
在dozer.xml中新增以下配置:
<!-- map-id:映射的標(biāo)識(shí),通過(guò)此標(biāo)識(shí)來(lái)確定使用該映射關(guān)系 -->
<mapping date-format="yyyy/MM/dd HH:mm:ss" map-id="user">
<class-a>com.rtxtitanv.model.User</class-a>
<class-b>com.rtxtitanv.model.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>
新增以下測(cè)試方法:
@Test
void test2() {
UserDTO userDTO = new UserDTO();
userDTO.setUserId(2L).setUserName("MaChao").setGender("男").setUserAge(21).setEmail("machao@xxx.com")
.setBirthday("2000/6/15 08:45:20");
User user = mapper.map(userDTO, User.class, "user");
log.info(user.toString());
}
執(zhí)行測(cè)試方法,發(fā)現(xiàn)轉(zhuǎn)換成功:

在調(diào)用map方法時(shí)也可以直接指定要轉(zhuǎn)換的目標(biāo)對(duì)象。新增以下測(cè)試方法:
@Test
void test3() {
UserDTO userDTO = new UserDTO();
userDTO.setUserId(3L).setUserName("LiuBei").setGender("男").setUserAge(30).setEmail("liubei@xxx.com")
.setBirthday("1991/1/20 13:36:55");
User user = new User();
mapper.map(userDTO, user, "user");
log.info(user.toString());
}
執(zhí)行測(cè)試方法,發(fā)現(xiàn)轉(zhuǎn)換成功:

通過(guò)field-exclude標(biāo)簽可以設(shè)置不想進(jìn)行轉(zhuǎn)換的屬性,這些屬性在進(jìn)行轉(zhuǎn)換時(shí)會(huì)被自動(dòng)排除。
在dozer.xml中新增以下配置:
<mapping date-format="yyyy/MM/dd HH:mm:ss" map-id="user-exclude">
<class-a>com.rtxtitanv.model.User</class-a>
<class-b>com.rtxtitanv.model.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>
<field-exclude>
<a>email</a>
<b>email</b>
</field-exclude>
</mapping>
新增以下測(cè)試方法:
@Test
void test4() {
UserDTO userDTO = new UserDTO();
userDTO.setUserId(1L).setUserName("ZhaoYun").setGender("男").setUserAge(20).setEmail("zhaoyun@xxx.com")
.setBirthday("2001/8/18 18:05:32");
User user = mapper.map(userDTO, User.class, "user-exclude");
log.info(user.toString());
}
執(zhí)行測(cè)試方法,發(fā)現(xiàn)email屬性被成功排除:

Dozer中的映射方式默認(rèn)都是雙向映射,如果想讓轉(zhuǎn)換不可逆,即只需要單向轉(zhuǎn)換,可以設(shè)置mapping元素的type屬性為one-way來(lái)開(kāi)啟單向映射。
在dozer.xml中新增以下配置:
<!-- type="one-way"將映射設(shè)置為單向映射 -->
<mapping date-format="yyyy/MM/dd HH:mm:ss" map-id="user-oneway" type="one-way">
<class-a>com.rtxtitanv.model.UserDTO</class-a>
<class-b>com.rtxtitanv.model.User</class-b>
<field>
<a>userId</a>
<b>id</b>
</field>
<field>
<a>userName</a>
<b>name</b>
</field>
<field>
<a>userAge</a>
<b>age</b>
</field>
</mapping>
新增以下測(cè)試方法:
@Test
void test5() {
UserDTO userDTO = new UserDTO();
userDTO.setUserId(1L).setUserName("ZhaoYun").setGender("男").setUserAge(20).setEmail("zhaoyun@xxx.com")
.setBirthday("2001/8/18 18:05:32");
User user = mapper.map(userDTO, User.class, "user-oneway");
log.info(user.toString());
UserDTO userDTO2 = mapper.map(user, UserDTO.class, "user-oneway");
log.info(userDTO2.toString());
}
執(zhí)行測(cè)試方法,發(fā)現(xiàn)只有UserDTO轉(zhuǎn)換為User成功:

當(dāng)兩個(gè)實(shí)體類中都嵌套有能夠互相轉(zhuǎn)換的實(shí)體類型屬性時(shí),也可以進(jìn)行相互轉(zhuǎn)換。
創(chuàng)建Order類:
package com.rtxtitanv.model;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author rtxtitanv
* @version 1.0.0
* @name com.rtxtitanv.model.Order
* @description Order
* @date 2021/8/18 16:45
*/
@Accessors(chain = true)
@Data
public class Order {
private Long id;
private String number;
private String description;
private User user;
}
創(chuàng)建OrderDTO類:
package com.rtxtitanv.model;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author rtxtitanv
* @version 1.0.0
* @name com.rtxtitanv.model.OrderDTO
* @description OrderDTO
* @date 2021/8/18 16:45
*/
@Accessors(chain = true)
@Data
public class OrderDTO {
private Long orderId;
private String orderNumber;
private String orderDescription;
private UserDTO userDTO;
}
在dozer.xml中新增以下配置:
<mapping date-format="yyyy/MM/dd HH:mm:ss" map-id="order">
<class-a>com.rtxtitanv.model.Order</class-a>
<class-b>com.rtxtitanv.model.OrderDTO</class-b>
<field>
<a>id</a>
<b>orderId</b>
</field>
<field>
<a>number</a>
<b>orderNumber</b>
</field>
<field>
<a>description</a>
<b>orderDescription</b>
</field>
<field>
<a>user</a>
<b>userDTO</b>
</field>
</mapping>
新增以下測(cè)試方法:
@Test
void test6() {
OrderDTO orderDTO = new OrderDTO();
UserDTO userDTO = new UserDTO().setUserId(6L).setUserName("DiaoChan").setGender("女").setUserAge(18)
.setEmail("diaochan@xxx.com").setBirthday("2003/12/27 23:10:36");
orderDTO.setOrderId(1L).setOrderNumber("78956328").setOrderDescription("二兩麻辣牛肉面").setUserDTO(userDTO);
Order order = mapper.map(orderDTO, Order.class, "order");
log.info(order.toString());
OrderDTO orderDTO2 = mapper.map(order, OrderDTO.class, "order");
log.info(orderDTO2.toString());
}
執(zhí)行測(cè)試方法,發(fā)現(xiàn)Order和OrderDTO相互轉(zhuǎn)換成功:

Dozer還可以對(duì)深層屬性進(jìn)行映射,即深度映射。例如一個(gè)對(duì)象中的String類型屬性可以與另一個(gè)對(duì)象中嵌套的對(duì)象的屬性進(jìn)行映射。
創(chuàng)建UserInfo類:
package com.rtxtitanv.model;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author rtxtitanv
* @version 1.0.0
* @name com.rtxtitanv.model.UserInfo
* @description UserInfo
* @date 2021/8/18 16:45
*/
@Accessors(chain = true)
@Data
public class UserInfo {
private String gender;
private String email;
private String birthday;
}
創(chuàng)建UserInfoDTO類:
package com.rtxtitanv.model;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author rtxtitanv
* @version 1.0.0
* @name com.rtxtitanv.model.UserInfoDTO
* @description UserInfoDTO
* @date 2021/8/18 16:45
*/
@Accessors(chain = true)
@Data
public class UserInfoDTO {
private Long userId;
private String userName;
private Integer userAge;
private UserInfo userInfo;
}
在dozer.xml中新增以下配置:
<mapping date-format="yyyy/MM/dd HH:mm:ss" map-id="user-deep-mapping">
<class-a>com.rtxtitanv.model.UserInfoDTO</class-a>
<class-b>com.rtxtitanv.model.User</class-b>
<field>
<a>userId</a>
<b>id</b>
</field>
<field>
<a>userName</a>
<b>name</b>
</field>
<field>
<a>userAge</a>
<b>age</b>
</field>
<field>
<a>userInfo.gender</a>
<b>gender</b>
</field>
<field>
<a>userInfo.email</a>
<b>email</b>
</field>
<field>
<a>userInfo.birthday</a>
<b>birthday</b>
</field>
</mapping>
新增以下測(cè)試方法:
@Test
void test7() {
UserInfo userInfo = new UserInfo();
userInfo.setGender("男").setEmail("zhaoyun@xxx.com").setBirthday("2001/8/18 18:05:32");
UserInfoDTO userInfoDTO = new UserInfoDTO();
userInfoDTO.setUserId(1L).setUserName("ZhaoYun").setUserAge(20).setUserInfo(userInfo);
User user = mapper.map(userInfoDTO, User.class, "user-deep-mapping");
log.info(user.toString());
}
執(zhí)行測(cè)試方法,發(fā)現(xiàn)UserInfoDTO成功轉(zhuǎn)換為User:

Dozer還支持注解方式配置映射,使用@Mapping注解可以進(jìn)行一些簡(jiǎn)單的映射處理。
創(chuàng)建UserEntity類:
package com.rtxtitanv.model;
import com.github.dozermapper.core.Mapping;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author rtxtitanv
* @version 1.0.0
* @name com.rtxtitanv.model.UserEntity
* @description UserEntity
* @date 2021/8/18 16:45
*/
@Accessors(chain = true)
@Data
public class UserEntity {
@Mapping(value = "userId")
private Long id;
@Mapping(value = "userName")
private String name;
@Mapping(value = "userAge")
private Integer age;
private String gender;
private String email;
private String birthday;
}
@Mapping只需要在源類中指定目標(biāo)類中對(duì)應(yīng)的屬性即可。
創(chuàng)建UserVO類:
package com.rtxtitanv.model;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author rtxtitanv
* @version 1.0.0
* @name com.rtxtitanv.model.UserVO
* @description UserVO
* @date 2021/8/18 16:45
*/
@Accessors(chain = true)
@Data
public class UserVO {
private Long userId;
private String userName;
private Integer userAge;
private String gender;
private String email;
private Date birthday;
}
新增以下測(cè)試方法:
@Test
void test8() {
UserEntity userEntity = new UserEntity();
userEntity.setId(1L).setName("ZhaoYun").setGender("男").setAge(20).setEmail("zhaoyun@xxx.com")
.setBirthday("2001/8/18 18:05:32");
UserVO userVO = mapper.map(userEntity, UserVO.class);
log.info(userVO.toString());
}
執(zhí)行測(cè)試方法,發(fā)現(xiàn)轉(zhuǎn)換成功:

代碼示例
Github:https://github.com/RtxTitanV/springboot-learning/tree/master/springboot2.x-learning/springboot-dozer
Gitee:https://gitee.com/RtxTitanV/springboot-learning/tree/master/springboot2.x-learning/springboot-dozer
到此這篇關(guān)于SpringBoot2.x 集成 Dozer的文章就介紹到這了,更多相關(guān)SpringBoot2.x 集成 Dozer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis-plus多數(shù)據(jù)源配置的兩種方式總結(jié)
這篇文章主要為大家詳細(xì)介紹了Mybatis-plus中多數(shù)據(jù)源配置的兩種方式,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起了解一下2022-10-10
Elasticsearch開(kāi)發(fā)AtomicArray使用示例探究
這篇文章主要為大家介紹了Elasticsearch AtomicArray使用示例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
基于FeignException$InternalServerError的解決方案
這篇文章主要介紹了FeignException$InternalServerError的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
web.xml?SpringBoot打包可執(zhí)行Jar運(yùn)行SpringMVC加載流程
這篇文章主要為大家介紹了web.xml?SpringBoot打包可執(zhí)行Jar運(yùn)行SpringMVC加載流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
SpringBoot中使用Jsoup爬取網(wǎng)站數(shù)據(jù)的方法
這篇文章主要介紹了SpringBoot中使用Jsoup爬取網(wǎng)站數(shù)據(jù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
SpringBoot整合jasypt實(shí)現(xiàn)敏感信息的加密詳解
一般公司的核心業(yè)務(wù)代碼中,都會(huì)存在與數(shù)據(jù)庫(kù)、第三方通信的secret key等敏感信息,如果以明文的方式存儲(chǔ),一旦泄露,那將會(huì)給公司帶來(lái)巨大的損失。本篇文章通過(guò)講解:Springboot集成Jasypt對(duì)項(xiàng)目敏感信息進(jìn)行加密,提高系統(tǒng)的安全性2022-09-09
Java使用flyway實(shí)現(xiàn)腳本自動(dòng)化的方法詳解
Flyway是一個(gè)開(kāi)源的數(shù)據(jù)庫(kù)版本控制工具,主要用于管理數(shù)據(jù)庫(kù)的版本和變更,它可以自動(dòng)化地將數(shù)據(jù)庫(kù)遷移到不同的版本,同時(shí)支持多種數(shù)據(jù)庫(kù)類型,本文給大家介紹了如何使用flyway實(shí)現(xiàn)腳本自動(dòng)化,需要的朋友可以參考下2023-10-10

