在项目中很多时候需要把Model和DTO两个模型类来回转换,保证Model对外是隐私的,同时类似密码之类的属性也能很好地避免暴露在外了.
那么ModelMapper就是为了方便转换而实现的一个类库,下面根据使用场景不断增加案例.


1.ModelMapper入口类

ModelMapper这个工具的入口类就是ModelMapper,因此转换就需要从这个类入口.简单看下API

  1. addConverter() :顾名思义,添加转换器
  2. addMappings() :添加映射器
  3. createTypeMap() :创建A-B的转换器关系
  4. getConfiguration() :获取配置
  5. map() ;映射处理

2.简单Model-DTO转换

 
Paste_Image.png
    /**
* 简单类-类转换
*/
@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进行转换.

 
Paste_Image.png
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的使用的更多相关文章

  1. Java 学习记录

    •Eclipse相关 Eclipse常用设置 解决 Eclipse 项目中有红色感叹号的详细方法(图文) JRE System Library [JavaSE-1.8](unbound) •Java ...

  2. Java学习记录第一章

    学习Java第一章的记录,这一章主要记录的是Java的最基础部分的了解知识,了解Java的特性和开发环境还有Java语言的优缺点. 计算机语言的发展大概过程:机器语言--->汇编语言---> ...

  3. Java学习记录 : 画板的实现

    接触java不满一个月,看厚厚的java入门简直要醉,故利用实例来巩固所学知识. 画板的实现其实从原理来说超级简单,可能一会儿就完成了. 但作为一名强迫症患者,要实现和win下面的画板一样的功能还是需 ...

  4. JAVA学习记录(一)————JAVA中的集合类

    这个图是总体的框架图,主要是两个接口Collection和Map都继承接口Iterator(Iterable),为了实现可以使用迭代器.Collection和Map类似平级关系. 1.这里我先学习下A ...

  5. JAVA学习记录<一>

    一: JAVA初体验: 1.JAVA简介: 2.环境搭建: 3:MyEclipse的使用简介: 4:程序的移植:项目的导入,导出. 5:学习JAVA的经验: 多写,多问,总结和复习!!!

  6. Java学习记录-Jdk包简单介绍

    java.applet Java语言编写的一些小应用程序 java.awt AWT 是Abstract Window ToolKit (抽象窗口工具包)的缩写,这个工具包提供了一套与本地图形界面进行交 ...

  7. Java学习记录-注解

    注解 一.org.springframework.web.bind.annotation ControllerAdviceCookieValue : 可以把Request header中关于cooki ...

  8. java学习记录

    1,接口(不实现任何方法)——>抽象类(实现部分公共方法)——>简单实现类——>具体实现类 2,抽象类不能被直接实例化,只能实现抽象方法,以匿名内部类的方式表现. 3,如果stati ...

  9. Java学习记录:降低耦合度

    耦合度定义 耦合度(Coupling)是对模块间关联程度的度量.耦合的强弱取决与模块间接口的复杂性.调用模块的方式以及通过界面传送数据的多少. 模块间的耦合度是指模块之间的依赖关系,包括控制关系.调用 ...

随机推荐

  1. 使用OxyPlot在WPF中创建图表

    目录(?)[+] Using Nuget 包括OxyPlot在你的应用程序的最简单方法是使用NuGet包管理器在Visual Studio 运行 Visual Studio并开始创建一个新的WPF项目 ...

  2. 国内外自然语言处理(NLP)研究组

     国内外自然语言处理(NLP)研究组 *博客地址 http://blog.csdn.net/wangxinginnlp/article/details/44890553 *排名不分先后.收集不全,欢迎 ...

  3. work-record:20190618

    ylbtech-work-record:20190618 1.返回顶部 1.1. -- formId记录表 -- select * from record_form_id; -- drop table ...

  4. CSS 继承和优先级

    CSS继承性 CSS属性继承:外层元素的样式,会被内层元素进行继承. 多个外层元素的样式,最终都会“叠加”到内层元素上. 什么样的CSS属性能被继承呢? CSS文本属性都会被继承的: color. f ...

  5. WPF实现Drag/Drop操作

    原文:WPF实现Drag/Drop操作 有时候我们方便用户操作,总会把一下Copy/Paste 或者 input操作转换为Drag/Drop, WPF 跟之前WinForm 一样提供了一些实现方式方便 ...

  6. 【学术篇】NOIP2016 D1T3 luogu1850换教室

    题目链接:点击这里献出你宝贵的时间(是用来做题不是捐赠Emmmm).. Emmmm我太弱了= = 做完这题我觉得我应该去打星际..这题怎么就有重边了呢.. 这题就是一道期望= =当时考场上好像完全不会 ...

  7. [转]async & await 的前世今生(Updated)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...

  8. [JZOJ4769]【GDOI2017模拟9.9】graph

    题目 描述 题目大意很明确了,所以不说-- 思考历程 一看见这题,咦,这就是传说中的动态图吗? 普通的动态图是维护连通性,这题是维护它是否是二分图,换言之就是维护它是否有奇环. 好像很复杂的样子. 想 ...

  9. Spring_数据校验和自定义检验规则和分组校验

    @Validated  :绑定需要校验的数据. 数据校验规则:为数据绑定校验的规则 private Long booId;@NotNull(message = "不能为空")pri ...

  10. thinkphp 子查询

    从3.0版本开始新增了子查询支持,有两种使用方式: 大理石平台检验标准 1.使用select方法 当select方法的参数为false的时候,表示不进行查询只是返回构建SQL,例如: // 首先构造子 ...