dozer是Java Bean到Java Bean映射器,它以递归方式将数据从一个对象复制到另一个对象。
dozer是用来对两个对象之间属性转换的工具,有了这个工具之后,我们将一个对象的所有属性值转给另一个对象时,就不需要再去写重复的调用set
和get
方法了。
dozer其实是对我们熟知的beanutils的封装。
dozer-demo
,并配置其pom.xml文件如下
<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.0modelVersion>
<groupId>com.hsgxgroupId>
<artifactId>dozer-demoartifactId>
<version>1.0-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.2.RELEASEversion>
<relativePath/>
parent>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>com.github.dozermappergroupId>
<artifactId>dozer-spring-boot-starterartifactId>
<version>6.5.0version>
dependency>
dependencies>
project>
UserDTO
和UserEntity
,它们的属性只有部分是一致的package com.hsgx.pojo;
import lombok.Data;
@Data
public class UserDTO {
private String userId;
private String userName;
private Integer userAge;
private String address;
private String birthday;
}
package com.hsgx.pojo;
import lombok.Data;
@Data
public class UserEntity {
private String id;
private String name;
private Integer age;
private String address;
private String birthday;
}
resources/dozer/
目录下创建dozer的全局配置文件global.dozer.xml
<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">
<configuration>
<date-format>yyyy-MM-dddate-format>
configuration>
mappings>
resources/dozer/
目录下创建dozer的映射文件biz.dozer.xml
,将不同名的属性的映射关系配置起来
<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.hsgx.pojo.UserEntityclass-a>
<class-b>com.hsgx.pojo.UserDTOclass-b>
<field>
<a>ida>
<b>userIdb>
field>
<field>
<a>namea>
<b>userNameb>
field>
<field>
<a>agea>
<b>userAgeb>
field>
mapping>
<mapping date-format="yyyy-MM-dd" map-id="user">
<class-a>com.hsgx.pojo.UserEntityclass-a>
<class-b>com.hsgx.pojo.UserDTOclass-b>
<field>
<a>ida>
<b>userAgeb>
field>
<field>
<a>namea>
<b>userNameb>
field>
<field>
<a>agea>
<b>userIdb>
field>
mapping>
mappings>
注意,这里故意将id
与userAge
、age
与userId
关联起来,只是为了验证dozer的特性。在实际开发中,要以实际需求为准。
resources/
目录下创建application.yml
配置文件server:
port: 8083
dozer:
mappingFiles:
- classpath:dozer/global.dozer.xml
- classpath:dozer/biz.dozer.xml
DozerDemoApp
package com.hsgx;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DozerDemoApp {
public static void main(String[] args) {
SpringApplication.run(DozerDemoApp.class, args);
}
}
package com.hsgx;
import com.github.dozermapper.core.Mapper;
import com.hsgx.pojo.UserDTO;
import com.hsgx.pojo.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 = DozerDemoApp.class)
public class DozerTest {
@Autowired
private Mapper mapper;
@Test
public void testDozer(){
UserDTO userDTO = new UserDTO();
userDTO.setUserId("100");
userDTO.setUserName("hsgx");
userDTO.setUserAge(20);
userDTO.setAddress("gz");
userDTO.setBirthday("2024-10-14");
// 直接映射
UserEntity userEntity1 = mapper.map(userDTO, UserEntity.class);
System.out.println(userEntity1);
// UserEntity已经初始化且个别属性已有值
UserEntity userEntity2 = new UserEntity();
userEntity2.setId("200");
mapper.map(userDTO, userEntity2);
System.out.println(userEntity2);
// 根据 biz.dozer.xml 文件中配置的 map-id 指定映射关系
UserEntity userEntity3 = new UserEntity();
mapper.map(userDTO, userEntity3, "user");
System.out.println(userEntity3);
}
}
可见,属性从UserDTO
对象复制到了UserEntity
对象,并且会覆盖UserEntity
对象原来的属性。
同时,还可以根据map-id
指定映射关系,如测试中UserDTO
对象的id
属性复制给了UserEntity
对象的age
属性。
需要注意的是,当前创建的UserEntity
和UserDTO
的属性不完全一致,所以需要创建映射文件进行映射,并且还需要在application.yml中配置映射文件的位置。如果两者的属性完全一致,则不需要提供映射文件。
为方便使用,我们可以将dozer的相关特性封装成一个工具类DozerUtils
,后续项目中只需要引入该工具类,就可以直接使用。
package com.hsgx.test;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import com.github.dozermapper.core.Mapper;
/**
* DozerUtils 工具类
*/
public class DozerUtils {
private Mapper mapper;
public DozerUtils(Mapper mapper) {
this.mapper = mapper;
}
public Mapper getMapper() {
return this.mapper;
}
/**
* 对象属性复制
* @param source 源对象
* @param destinationClass 目标对象的Class类
* @return T
*/
public <T> T map(Object source, Class<T> destinationClass) {
if (source == null) {
return null;
}
return mapper.map(source, destinationClass);
}
/**
* 对象属性复制
* @param source 源对象
* @param destination 目标对象
*/
public void map(Object source, Object destination) {
if (source == null) {
return;
}
mapper.map(source, destination);
}
/**
* 指定 map-id 进行对象属性复制
* @param source 源对象
* @param destinationClass 目标对象的Class类
* @param mapId biz.dozer.xml文件中配置的map-id
* @return T
*/
public <T> T map(Object source, Class<T> destinationClass, String mapId) {
if (source == null) {
return null;
}
return mapper.map(source, destinationClass, mapId);
}
/**
* 指定 map-id 进行对象属性复制
* @param source 源对象
* @param destination 目标对象
* @param mapId biz.dozer.xml文件中配置的map-id
*/
public void map(Object source, Object destination, String mapId) {
if (source == null) {
return;
}
mapper.map(source, destination, mapId);
}
/**
* 将List集合转成List集合
* @param sourceList 源集合
* @param destinationClass 待转类型
* @return List
*/
public <T, E> List<T> mapList(Collection<E> sourceList, Class<T> destinationClass) {
if (sourceList == null || sourceList.isEmpty() || destinationClass == null) {
return Collections.emptyList();
}
List<T> destinationList = sourceList.stream()
.filter(item -> item != null)
.map((sourceObject) -> mapper.map(sourceObject, destinationClass))
.collect(Collectors.toList());
return destinationList;
}
/**
* 将Set集合转成Set集合
* @param sourceList 源集合
* @param destinationClass 待转类型
* @return List
*/
public <T, E> Set<T> mapSet(Collection<E> sourceList, Class<T> destinationClass) {
if (sourceList == null || sourceList.isEmpty() || destinationClass == null) {
return Collections.emptySet();
}
return sourceList.stream()
.map((sourceObject) -> mapper.map(sourceObject, destinationClass))
.collect(Collectors.toSet());
}
}
编写单元测试:
@Autowired
private Mapper mapper;
@Test
public void testDozer() {
UserDTO userDTO = new UserDTO();
userDTO.setUserId("100");
userDTO.setUserName("hsgx");
userDTO.setUserAge(20);
userDTO.setAddress("gz");
userDTO.setBirthday("2024-10-14");
DozerUtils dozerUtils = new DozerUtils(mapper);
// 简单对象属性复制
UserEntity userEntity1 = dozerUtils.map(userDTO, UserEntity.class);
System.out.println(userEntity1);
UserEntity userEntity2 = new UserEntity();
dozerUtils.map(userDTO, userEntity2);
System.out.println(userEntity2);
// 根据map-id进行对象属性复制
UserEntity userEntity3 = dozerUtils.map(userDTO, UserEntity.class, "user");
System.out.println(userEntity3);
UserEntity userEntity4 = new UserEntity();
dozerUtils.map(userDTO, userEntity4, "user");
System.out.println(userEntity4);
// List → List
List<UserDTO> userDTOList = new ArrayList<>();
userDTOList.add(userDTO);
UserDTO userDTO2 = new UserDTO();
userDTO2.setUserId("200");
userDTO2.setUserName("zhangsan");
userDTO2.setUserAge(50);
userDTO2.setAddress("sz");
userDTO2.setBirthday("2024-10-27");
userDTOList.add(userDTO2);
List<UserEntity> userEntityList = dozerUtils.mapList(userDTOList, UserEntity.class);
System.out.println(userEntityList);
// Set → Set
Set<UserDTO> userDTOSet = new HashSet<>();
userDTOSet.add(userDTO);
userDTOSet.add(userDTO2);
Set<UserEntity> userEntitySet = dozerUtils.mapSet(userDTOSet, UserEntity.class);
System.out.println(userEntitySet);
}
单元测试结果:
…
本节完,更多内容查阅:后台管理系统的通用权限解决方案
延伸阅读:后台管理系统的通用权限解决方案(三)SpringBoot整合Knife4j生成接口文档