一、什么是Dozer?
Dozer是一种Java Bean到Java Bean的映射器,递归地将数据从一个对象复制到另一个对象,它是一个强大的,通用的,灵活的,可重用的和可配置的开源映射框架。
说白点就是dozer是一个能把实体和实体之间进行转换的工具.只要建立好映射关系.就像是ORM的数据库和实体映射一样。
比如:代码层与层之间javabean转换, 如dao层PO转前端VO,一个持久实体 包含 密码 字段,不好频繁的把实体的密码去掉再给到 前端. 需要 po -> vo。
(但是以上操作需要很多的set,所以这时就需要用到Dozer了。)
Dozer做对象转换有什么特点
默认属性Mapping,即如果属性名称一样, 就不需要显示配置,Dozer会自动处理。
自动做类型转换,即如果两个属性名称一样,即使类型不一样,在Dozer可理解范围内,帮你处理得妥妥的。Dozer可理解的类型范围非常广,这会极大的提升程序员的生产力
不必担心中间的null property,遇到null property,Dozer会把对应的所有属性全部设置为null,而不会抛NullPointerExeception。
二、SpringBoot整合Dozer
如何不会创建SpringBoot项目请参考SpringBoot整合
1、首先引入依赖
<!--dozer -->
<dependency>
<groupId></groupId>
<artifactId>dozer-spring</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>dozer</artifactId>
<version>5.5.1</version>
</dependency>
2、在resource下创建
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns:xsi="http:///2001/XMLSchema-instance" xmlns=""
xsi:schemaLocation="
/schema/">
<mapping>
<!--对应的实体和要转换成的VO-->
<class-a></class-a>
<class-b></class-b>
<!--对应要转换的属性名.<a>和<class-a>对应,其它同理-->
<field>
<a>userId</a>
<b>Id</b>
</field>
</mapping>
</mappings>
也可以在实体中使用@Mapping注解。
下面列出我的实体和VO例子:
import lombok.Data;
import org.dozer.Mapping;
@Data
public class Users {
@Mapping("Id")
private BigDecimal userId;
private String userName;
private String password;
private String firstName;
private String lastName;
}
@Mapping(“Id”) 对应的以下UsersVO的Id
import lombok.Data;
import java.math.BigDecimal;
@Data
public class UsersVO {
private BigDecimal Id;
private String userName;
private String password;
3、创建
import org.dozer.Mapper;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
/**
* dozer 转换器
*/
@Component
public class GeneralConvertor {
@Resource
Mapper mapper;
/**
* List 实体类 转换器
*
* @param source 原数据
* @param clz 转换类型
* @param <T>
* @param <S>
* @return
*/
public <T, S> List<T> convertor(List<S> source, Class<T> clz) {
if (source == null) return null;
List<T> map = new ArrayList<>();
for (S s : source) {
map.add(mapper.map(s, clz));
}
return map;
}
/**
* Set 实体类 深度转换器
*
* @param source 原数据
* @param clz 目标对象
* @param <T>
* @param <S>
* @return
*/
public <T, S> Set<T> convertor(Set<S> source, Class<T> clz) {
if (source == null) return null;
Set<T> set = new TreeSet<>();
for (S s : source) {
set.add(mapper.map(s, clz));
}
return set;
}
/**
* 实体类 深度转换器
*
* @param source
* @param clz
* @param <T>
* @param <S>
* @return
*/
public <T, S> T convertor(S source, Class<T> clz) {
if (source == null) return null;
return mapper.map(source, clz);
}
public void convertor(Object source, Object object) {
mapper.map(source, object);
}
public <T> void copyConvertor(T source, Object object) {
mapper.map(source, object);
}
}
(注意:该类需要添加@Component,让它能被扫描到)
4、测试
@Service
public class UsersService{
@Resource
GeneralConvertor convertor;
@Override
public List<UsersVO> findAll() {
List<Users> list = usersMapper.findAll();
//关键代码
List<UsersVO> usersVO =convertor.convertor(list,UsersVO.class);
return usersVO ;
}
}