Java学习记录--ModelMapper的使用
在项目中很多时候需要把Model和DTO两个模型类来回转换,保证Model对外是隐私的,同时类似密码之类的属性也能很好地避免暴露在外了.
那么ModelMapper就是为了方便转换而实现的一个类库,下面根据使用场景不断增加案例.
1.ModelMapper入口类
ModelMapper这个工具的入口类就是ModelMapper,因此转换就需要从这个类入口.简单看下API
- addConverter() :顾名思义,添加转换器
- addMappings() :添加映射器
- createTypeMap() :创建A-B的转换器关系
- getConfiguration() :获取配置
- map() ;映射处理
2.简单Model-DTO转换

/**
* 简单类-类转换
*/
@Test
public void testModelToDTO() {
User user = new User();
user.setId(1L);
user.setNickname("张三");
user.setEmail("101@qq.com");
user.setHonor("测试荣誉");
ModelMapper modelMapper = new ModelMapper();
UserDTO userDTO = modelMapper.map(user, UserDTO.class);
System.out.println(userDTO);
}
这里转换替换是根据字段名匹配也就是当User和UserDTO中的字段名称一样就会自动转换.
3.自定义转换
自定义有很多转换,比如Provider,Converter,Condition,PropertyMap等,下面是个综合的例子.
/**
* 简单类到类自定义字段
*/
@Test
public void testModelToDTOByDe(){
User user = new User();
user.setId(1L);
user.setNickname("张三");
user.setEmail("101@qq.com");
user.setHonor("测试荣誉");
ModelMapper modelMapper = new ModelMapper();
//转换内容提供者
Provider<String> personProvider = new AbstractProvider<String>() {
public String get() {
return "自定义提供者";
}
};
//创建自定义转换规则
Converter<String, String> toUppercase = new AbstractConverter<String, String>() {
protected String convert(String source) {
System.out.println(source);
return source == null ? null : source.toUpperCase();
}
};
//创建自定义条件转换
Condition<Long,?> gt2 = context -> {
System.out.println(context.getSource());
return context.getSource() > 2;
};
//创建自定义映射规则
PropertyMap<User,UserDTO> propertyMap = new PropertyMap<User, UserDTO>() {
@Override
protected void configure() {
using(toUppercase).map(source.getNickname(),destination.getHonor());//使用自定义转换规则
with(personProvider).map(source.getHonor(),destination.getNickname());//使用自定义属性提供覆盖
map(source.getAvatar()).setAvatar(null);//主动替换属性
skip(destination.getEmail());
when(gt2).map().setId(1L);//过滤属性
}
};
//添加映射器
modelMapper.addMappings(propertyMap);
modelMapper.validate();
//转换
UserDTO userDTO = modelMapper.map(user,UserDTO.class);
System.out.println(userDTO);
}
对应的输出是:
UserDTO{id='null', email='null', avatar='null', nickname='自定义提供者', honor='张三'}
分析下:
Provider,Converter,Condition三个都算是转换前奏,所有的转换规则都是在PropertyMap里面配置.所以分析这个里面的配置即可.
1.using(toUppercase).map(source.getNickname(),destination.getHonor());//使用自定义转换规则
首先toUppercase是一个Converter,也就是sources的nickname会经过这个转换器,然后才设置到destination的honor中.
2.with(personProvider).map(source.getHonor(),destination.getNickname());//使用自定义属性提供覆盖
personProvider类似一个Bean工厂,当使用这个的时候,对于sources调用getHonor()的时候实际上是调用personProvider的get方法.所以结果nickname='自定义提供者'
3.map(source.getAvatar()).setAvatar(null);//主动替换属性
可以主动重设某些属性
4.skip(destination.getEmail());
过滤指定属性
5.when(gt2).map().setId(1L);//条件过滤属性
条件过滤属性,当满足gt2的时候才会调用setId方法.
4.对于集合的映射
对于集合的映射,因为泛型擦除的存在,所以需要告诉ModelMapper要转换的类型,所以就有了TypeToken这个类.
@Test
public void testListToListDto() {
User user1 = new User();
user1.setId(1L);
user1.setNickname("张三");
user1.setEmail("101@qq.com");
user1.setHonor("测试荣誉");
User user2 = new User();
user2.setId(1L);
user2.setNickname("李四");
user2.setEmail("101@qq.com");
user2.setHonor("测试荣誉");
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
ModelMapper modelMapper = new ModelMapper();
List<UserDTO> userDTOS = modelMapper.map(users,new TypeToken<List<UserDTO>>() {}.getType());
System.out.println(userDTOS);
}
5.针对集合作为属性的映射
这个是最近做项目遇到的一个问题.
比如PageInfo里面包含了一些分页信息,和一个结果集,其中结果集是集合,我想把左边转换为右边.找了些资料,没发现特别好的办法,现在是额外定义转换器,专门对内部的List进行转换.

ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STANDARD);
//针对内部list的转换
Converter<ArrayList<ArticlePC>,ArrayList<ArticleListDTO>> converter = new AbstractConverter<ArrayList<ArticlePC>, ArrayList<ArticleListDTO>>() {
@Override
protected ArrayList<ArticleListDTO> convert(ArrayList<ArticlePC> source) {
return modelMapper.map(source,new TypeToken<ArrayList<ArticleListDTO>>(){}.getType());
}
};
PropertyMap<PageInfo<ArticlePC>,PageInfo<ArticleListDTO>> propertyMap = new PropertyMap<PageInfo<ArticlePC>, PageInfo<ArticleListDTO>>() {
@Override
protected void configure() {
using(converter).map(source.getList(),destination.getList());
}
};
modelMapper.addMappings(propertyMap);
modelMapper.createTypeMap(ArticlePC.class,ArticleListDTO.class);
return modelMapper.map(articlePCS, new TypeToken<PageInfo<ArticleListDTO>>() {
}.getType());
目前就使用到了这些,用到其他功能再去研究下,官网有不少地方写的不是很明确,导致看的稀里糊涂的,主要是例子太少了,等用的多了再更新.
作者:此博废弃_更新在个人博客
链接:https://www.jianshu.com/p/454ab6abea3f
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
Java学习记录--ModelMapper的使用的更多相关文章
- Java 学习记录
•Eclipse相关 Eclipse常用设置 解决 Eclipse 项目中有红色感叹号的详细方法(图文) JRE System Library [JavaSE-1.8](unbound) •Java ...
- Java学习记录第一章
学习Java第一章的记录,这一章主要记录的是Java的最基础部分的了解知识,了解Java的特性和开发环境还有Java语言的优缺点. 计算机语言的发展大概过程:机器语言--->汇编语言---> ...
- Java学习记录 : 画板的实现
接触java不满一个月,看厚厚的java入门简直要醉,故利用实例来巩固所学知识. 画板的实现其实从原理来说超级简单,可能一会儿就完成了. 但作为一名强迫症患者,要实现和win下面的画板一样的功能还是需 ...
- JAVA学习记录(一)————JAVA中的集合类
这个图是总体的框架图,主要是两个接口Collection和Map都继承接口Iterator(Iterable),为了实现可以使用迭代器.Collection和Map类似平级关系. 1.这里我先学习下A ...
- JAVA学习记录<一>
一: JAVA初体验: 1.JAVA简介: 2.环境搭建: 3:MyEclipse的使用简介: 4:程序的移植:项目的导入,导出. 5:学习JAVA的经验: 多写,多问,总结和复习!!!
- Java学习记录-Jdk包简单介绍
java.applet Java语言编写的一些小应用程序 java.awt AWT 是Abstract Window ToolKit (抽象窗口工具包)的缩写,这个工具包提供了一套与本地图形界面进行交 ...
- Java学习记录-注解
注解 一.org.springframework.web.bind.annotation ControllerAdviceCookieValue : 可以把Request header中关于cooki ...
- java学习记录
1,接口(不实现任何方法)——>抽象类(实现部分公共方法)——>简单实现类——>具体实现类 2,抽象类不能被直接实例化,只能实现抽象方法,以匿名内部类的方式表现. 3,如果stati ...
- Java学习记录:降低耦合度
耦合度定义 耦合度(Coupling)是对模块间关联程度的度量.耦合的强弱取决与模块间接口的复杂性.调用模块的方式以及通过界面传送数据的多少. 模块间的耦合度是指模块之间的依赖关系,包括控制关系.调用 ...
随机推荐
- Mybatis笔记 - 原始Dao开发方法
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.原始Dao的开发方式是基于入门程序的基础上,对 控制程序 进行分层开发,程序员需要 编写 Dao接口 和 ...
- <scrapy爬虫>scrapy命令行操作
1.mysql数据库 2.mongoDB数据库 3.redis数据库 1.创建项目 scrapy startproject myproject cd myproject 2.创建爬虫 scrapy g ...
- 「APIO 2019」桥梁
题目 三天终于把\(APIO\)做完了 这题还是比较厉害的,如果不知道这是个分块应该就自闭了 考虑一个非常妙的操作,按照操作分块 我们设一个闸值\(S\),把\(S\)个边权修改操作分成一块,把所有的 ...
- 面试系列 30 如何自己设计一个类似dubbo的rpc框架
其实一般问到你这问题,你起码不能认怂,因为既然咱们这个课程是短期的面试突击训练课程,那我不可能给你深入讲解什么kafka源码剖析,dubbo源码剖析,何况我就算讲了,你要真的消化理解和吸收,起码个把月 ...
- 大半宿,封装了一个MP3播放器的类,写了个简陋的播放器
用 winmm.lib 写的 封装不是很好,而且没有优化,效率可能有问题,但是现在几乎没有什么大问题 我用我封装的类,写了一个小播放器,界面上的所有功能都实现了,包括双击列表中的文件名,直接播放文件 ...
- Slim模型部署多GPU
1 多GPU原理 单GPU时,思路很简单,前向.后向都在一个GPU上进行,模型参数更新时只涉及一个GPU. 多GPU时,有模型并行和数据并行两种情况. 模型并行指模型的不同部分在不同GPU上运行. 数 ...
- mac brew nginx php php-fpm xdebug
/usr/local/opt/nginx/bin/nginx -v brew services restart nginx sudo /usr/local/sbin/php-fpm --fpm-con ...
- [NOIP2019模拟赛]序列(Sequence)
题目大意 有一个序列$A_i$ • 对于 i ≥ 1,如果有$ A_i > 0.A_{i+1}> 0$ 且存在 $A_{i+2}$,那么法老可以令$ Ai$ 和 $A_{i+1}$ 减一, ...
- rem适配手机
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- thinkphp 子查询
从3.0版本开始新增了子查询支持,有两种使用方式: 大理石平台检验标准 1.使用select方法 当select方法的参数为false的时候,表示不进行查询只是返回构建SQL,例如: // 首先构造子 ...