(1) 引入maven
org.modelmapper
modelmapper
1.1.0
(2) 简单操作
//创建 ModelMapper 类
ModelMapper modelMapper = new ModelMapper();
// S 实体相同字段映射到 T 实体
T map = modelMapper.map(S s, T.class);
//集合映射
List map = modelMapper.map(List s, new TypeToken>() {}.getType());
(1) modelMapperAPI
//未有对象映射
BEntity bEntity = modelMapper.map(AEntity aEntity,BEntity.class);
//已有对象映射
modelMapper.map(AEntity aEntity,BEntity bEntity);
//使用泛型
Type type = new TypeToken>() {}.getType();//定义泛型,用于映射list
modelMapper.map(AEntity aEntity,Type type);
//验证映射,目标对象有字段没有映射报错
modelMapper.validate();
//添加转换器
modelMapper.addConverter(Converter converter);
//添加映射规则
modelMapper.addMappings(PropertyMap propertyMap);
//获取配置类,可查看和修改
Configuration configuration = modelMapper.getConfiguration();
//创建映射
TypeMap< AEntity,BEntity> typeMap =modelMapper.createTypeMap(AEntity.class,BEntity.class);
(2) 类型映射
//字段映射
//添加映射字段
typeMap.addMapping(BEntity::getAField,CEntity::setHField);
//添加映射字段
typeMap.addMappings(mapper -> mapper.map(BEntity::getAField,CEntity::setGField));
//忽略映射字段
typeMap.addMappings(mapper -> mapper.skip(CEntity::setEField));
//添加转换器映射
typeMap.addMappings(mapper -> mapper.using(Converter converter).map(BEntity::getAField,CEntity::setFField))
//添加提供者映射
typeMap.addMappings(mapper ->mapper.with(Provider) context).map(BEntity::getAField,CEntity::setFField) )
//添加过滤条件映射
typeMap.addMappings(mapper ->mapper.when(Condition) condition).map(BEntity::getAField,CEntity::setFField));
//深度映射 对象->对象字段->字段 ---> 对象 -> 字段
typeMap.addMappings(mapper -> mapper.map(src -> src.getCEntity().getEField(), BEntity::setAField));
//深度映射 对象->对象字段->字段 ---> 对象->对象字段 -> 字段
typeMap.addMappings(mapper -> mapper.map(src -> src.getCEntity().getFField(), (dest, v) -> dest.getCEntity().setHField(v)));
//设置提供者
//字段提供者,为目标字段提供值,
typeMap.setPropertyProvider(Provider provider)
//对象提供者,在有没目标对象映射时,可自定义提供目标对象
typeMap.setProvider(Provider provider)
//设置映射条件
//对象条件
typeMap.setCondition(Condition, ?> condition);
//字段条件,当对象条件不通过时,不会执行字段条件
typeMap.setPropertyCondition(Condition, ?> condition);
//设置转换器
//对象转换器,可用来 处理映射 ,返回目标对象,有该转换器,其他不生效
typeMap.setConverter(Converter converter);
//没有setConverter时执行,在进行字段映射前执行
typeMap.setPreConverter(Converter converter);
//没有setConverter时执行,在进行字段映射时执行
typeMap.setPropertyConverter(Converter converter);
//没有setConverter时执行,在进行字段映射后执行
typeMap.setPostConverter(Converter converter);
(3) 配置
//控制类配置
configuration .setFullTypeMatchingRequired(true);//需要完整类型匹配
configuration .setFieldMatchingEnabled(true);//字段匹配已启用
configuration .setSkipNullEnabled(true);//跳过空值已启用
configuration .setAmbiguityIgnored(true);//忽略歧义
configuration .setImplicitMappingEnabled(true);//隐式映射已启用
//访问级别配置
configuration .setMethodAccessLevel(Configuration.AccessLevel.PACKAGE_PRIVATE);//方法访问级别
modelMapper.getConfiguration().setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);//字段访问级别
//命名方式
configuration .setSourceNameTokenizer(NameTokenizers.CAMEL_CASE);//来源名称命名方式
configuration .setDestinationNameTokenizer(NameTokenizers.CAMEL_CASE);//目标名称命名方式
//名称转换方式
configuration .setSourceNameTransformer(NameTransformers.JAVABEANS_MUTATOR);//来源名称转换方式
configuration .setDestinationNameTransformer(NameTransformers.JAVABEANS_MUTATOR);//目标名称转换方式
//命名约定
configuration .setDestinationNamingConvention(NamingConventions.JAVABEANS_ACCESSOR);//目标地命名约定
configuration .setSourceNamingConvention(NamingConventions.JAVABEANS_ACCESSOR);//来源命名约定
//匹配策略
configuration .setMatchingStrategy(MatchingStrategies.LOOSE);
//设置提供者
configuration .setProvider((Provider) provider->{
return "";
});
//设置条件
configuration .setPropertyCondition((Condition) condition ->{
return true;
});
可以配置常量:
命名约定( NamingConventions ) |
NamingConventions.NONE | 表示没有命名约定,该约定适用于所有属性名称 |
NamingConventions.JAVABEANS_ACCESSOR | 根据JavaBeans约定查找合格的访问者 | |
NamingConventions.JAVABEANS_MUTATOR | 根据JavaBeans约定查找合格的mutator | |
名称转化器(NameTransformer) | NameTransformers.JAVABEANS_ACCESSOR | 根据JavaBeans约定转换访问者名称 |
NameTransformers.JAVABEANS_MUTATOR | 根据JavaBeans set方法转换变量名称 | |
命名方式 (NameTokenizers) |
NameTokenizers.CAMEL_CASE | 根据[ 驼峰]对属性和类名进行标记 |
NameTokenizers.UNDERSCORE | 用[下划线标记]属性和类的名称 | |
匹配策略(MatchingStrategies) | MatchingStrategies.STANDARD | 智能匹配源和目标属性 |
MatchingStrategies.LOOSE | 松散匹配源属性和目标属性 | |
MatchingStrategies.STRICT | 严格匹配源和目标属性 | |
访问级别(AccessLevel) | Configuration.AccessLevel.PUBLIC | 公开,公共的 |
Configuration.AccessLevel.PROTECTED | 同一包中 | |
Configuration.AccessLevel.PACKAGE_PRIVATE | 同一子包中 | |
Configuration.AccessLevel.PRIVATE | 同一类中 |
(3) 映射器
添加字段映射,及各字段映射处理
//自定义映射
PropertyMap propertyMap = new PropertyMap() {
@Override
protected void configure() {
/**使用自定义转换规则*/
map(source.getAField(), destination.getBField());//主动替换属性
map().setAField(source.getBField());/BField字段赋值给AField
using(toUppercase).map(source.getAField(),destination.getBField());//使用自定义转换规则
with(personProvider).map(source.getBField(),destination.getBField());//使用自定义属性提供覆盖
skip(destination.getAField());//过滤指定属性,非对象
skip().setDtoOnlyProperty(null);//过滤指定属性,对象
when(condition).map().setAField("value");//条件过滤属性,条件符合赋值value
}
};
(4) 转换器
可进行字段数据处理,类型转换等操作.
//定义转换器
Converter toUppercase = new AbstractConverter() {
@Override
protected Dconvert(S source) {
//处理原对象,返回目标对象
return source;
}
};
//lambda表达式方式
Converter converter = ctx -> ctx.getSource() == null ? null : ctx.getSource();
(5) 提供者
可用于设置映射条件,条件满足进行条件映射.可通过 Configuration 和 TypeMap 配置,[typeMap.setProvider]可设置一个目标对象;[typeMap.setPropertyProvider] 可为 源对象 字段 提供值;Configuration 可同时设置对象与字段属性,处理需判断类型
//转换内容提供者
Provider personProvider = new AbstractProvider() {
@Override
public String get() {
//返回要添加的内容
return "自定义提供者";
}
};
//lambda表达式方式
Provider provider = req -> new String();
(6) 条件
可用于设置映射条件,条件满足进行条件映射.可通过 Configuration 和 TypeMap 配置
//创建自定义条件转换 注:以下Condition 可添加两泛值Condition,?>
Condition condition =new Condition() {
@Override
public boolean applies(MappingContext mappingContext) {
//处理字段,返回false不映射
return false;
}
};
//lambda表达式方式
Condition notNull = ctx -> ctx.getSource() != null;
//内置条件
//原对象字段值为空不映射
Condition notNull1 = Conditions.isNotNull();
//原对象字段值为空映射
Condition isNull = Conditions.isNull();
//判断原对象字段类型,符合映射
Condition isType = Conditions.isType(String.class);
//条件取交集
Condition and = Conditions.and(Condition c1,Condition c2);
//条件取反集
Condition not = Conditions.not(Condition c);
//条件取并集
Condition or = Conditions.or(Condition c1,Condition c2);
(1) 引入maven
org.mapstruct
mapstruct-jdk8
1.2.0.Final
org.mapstruct
mapstruct-processor
1.2.0.Final
(2) 定义接口
package com.example.demo.mapstruct;
import com.example.demo.pojo.ABean;
import com.example.demo.pojo.BBean;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface Converter {
Converter INSTANCE = Mappers.getMapper(Converter.class);
@Mappings({
@Mapping(source = "aField", target = "bField"),
})
BBean domain2dto(ABean aBean);
//默认处理方法
default BBean domain2dto1(ABean aBean) {
//hand-written mapping logic
}
}
(3) 简单操作
BBean bBean = PersonConverter.INSTANCE.domain2dto(ABean aBean);
@Mapper 只有在接口加上这个注解, MapStruct 才会去实现该接口
componentModel属性,主要是指定实现类的类型,一般用到两个
default:默认,可以通过Mappers.getMapper(Class)方式获取实例对象
spring:在接口的实现类上自动添加注解@Component,可通过@Autowired方式注入
@Mapping:属性映射,若源对象属性与目标对象名字一致,会自动映射对应属性
source:源属性
target:目标属性
dateFormat:String到Date日期之间相互转换,通过SimpleDateFormat,该值为SimpleDateFormat的日期格式
ignore:忽略这个字段
@Mappings:配置多个@Mapping
@MappingTarget用于更新已有对象
@InheritConfiguration用于继承配置
(1) 添加默认方法
default Bean1 defaultConvert(Bean2 bean2) {
//进行映射处理及其他处理
return bean1;
}
(2) 使用abstract class来代替接口
package com.example.demo.mapstruct;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public abstract class Converter {
Converter INSTANCE = Mappers.getMapper(Converter.class);
@Mappings({
@Mapping(source = "aField", target = "bField"),
})
public abstract BBean domain2dto(ABean aBean);
}
(3) 可以使用多个参数
@Mappings({
@Mapping(source = "bean1.field1", target = "field1"),
@Mapping(source = "bean2.field1", target = "field2")
})
Bean3 toUserRoleDto(Bean1 bean1, Bean2 bean2);
(4) 直接使用参数作为属性值
@Mappings({
@Mapping(source = "field", target = "field")
})
Bean useParameter(String field);
(5) 更新对象属性
@Mappings({
@Mapping(source = "field", target = "field")
})
void update(Bean2 bean2, @MappingTarget Bean1 bean1);//@MappingTarget 指定目标对象
(6) 使用Spring依赖注入
//添加 componentModel 属性
@Mapper(componentModel = "spring")
public interface ConverterMapper {}
// 自动注入
@Autowired
private ConverterMapper mapper;
(7) 自定义类型转换
//@Mapper注解加uses属性
@Mapper( uses = { MyConversion.class})
//自定义转换器,field为对应的转换的字段 MyConversion|conversion自定义
public class MyConversion{
public String conversion(String field) {
return field;
}
}