项目中对象与对象赋值转换使用的频率非常的高,比如数据库表实体对象(Entity)与业务类对象(Model)之间的赋值传递,或者模型对象(Model)与视图对象(ViewModel)之间的赋值传递。如果我们一个一个字段的赋值,将是非常繁琐并且毫无价值的重复工作,此时虽然我们可以自己通过反射提取个公共的方法来处理,但是更高效的方式是查看是否有第三方已经提供了比较成熟稳定的工具包,避免重复造轮子的工作。

在C#中我们一般使用AutoMapper作为对象转换工具(AutoMapper配置使用参考:https://blog.csdn.net/fly_duck/article/details/102605046),Java中也有类似的转换工具,比如:Dozer,Orika,MapStruct,JMapper,ModelMapper以及BeanUtils等,都可以实现对象之间的转换。 本问主要介绍SpringBoot项目中ModelMapper的配置以及使用,使用ModelMapper我们可以快速的解决对象与对象之间的映射转换。官方的介绍如下:

The goal of ModelMapper is to make object mapping easy, by automatically determining how one object model maps to another, based on conventions, in the same way that a human would - while providing a simple, refactoring-safe API for handling specific use cases.

ModelMapper的Github地址: https://github.com/modelmapper/modelmapper,官方地址:http://modelmapper.org/,官方使用文档:http://modelmapper.org/user-manual/。

pom.xml配置

首先在pom.xml引入ModelMapper依赖:

        <!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper --><dependency><groupId>org.modelmapper</groupId><artifactId>modelmapper</artifactId><version>2.3.9</version></dependency>

ModelMapper配置

在SpringBoot项目中将ModelMapper配置好后注册为JavaBean交给Spring来管理,使用的时候直接通过注解获取ModelMapper实例来对对象进行转换。项目中强烈建议将setFullTypeMatchingRequired设置为true使用完全匹配模式,将setMatchingStrategy设置为MatchingStrategies.STRICT使用严格匹配模式,避免字段名缺失被相似字段转换错误的情况。

package com.flyduck.mybatis.config;import com.flyduck.mybatis.entity.User;
import com.flyduck.mybatis.model.UserModel;
import org.modelmapper.AbstractConverter;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.text.SimpleDateFormat;
import java.util.Date;@Configuration
public class ModelMapperConfig {private Converter<Date, String> dateToStringConverter = new AbstractConverter<Date, String>() {@Overrideprotected String convert(Date date) {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return date == null ? null : simpleDateFormat.format(date);}};/*** 将ModelMapper注册到Spring中* 可以添加一些定制化的配置,官方文档:http://modelmapper.org/user-manual/property-mapping/** @author flyduck* @date 2020/11/25 21:35* @param []* @return org.modelmapper.ModelMapper*/@Beanpublic ModelMapper modelMapper() {ModelMapper modelMapper = new ModelMapper();// 官方配置说明: http://modelmapper.org/user-manual/configuration/// 完全匹配modelMapper.getConfiguration().setFullTypeMatchingRequired(true);// 匹配策略使用严格模式modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);modelMapper.addConverter(dateToStringConverter);configureUser(modelMapper);return modelMapper;}private void configureUser(ModelMapper modelMapper) {modelMapper.typeMap(UserModel.class, User.class).addMappings(mapper -> mapper.skip(User::setPassword)).addMappings(mapper -> mapper.skip(User::setCreateTime)).addMappings(mapper -> mapper.skip(User::setUpdateTime)).addMappings(mapper -> mapper.map(UserModel::getName, User::setRealName));modelMapper.typeMap(User.class, UserModel.class).addMappings(mapper -> mapper.skip(UserModel::setPassword)).addMappings(mapper -> mapper.map(User::getRealName, UserModel::setName));
//                .addMappings(mapper -> mapper.using(dateToStringConverter).map(User::getCreateTime, UserModel::setCreateTime))
//                .addMappings(mapper -> mapper.using(dateToStringConverter).map(User::getUpdateTime, UserModel::setUpdateTime));}
}

默认情况下,ModelMapper会通过反射按照字段名自动进行对象转换。但是一些特殊情况,需要我们自定义配置,示例配置中我们单独为User和UserModel类之间的转换做了一些常用的配置。 当某个字段不需要转换可以通过skip来设置,当字段名不一致可以通过map来设置,当字段值需要处理后再转换可以通过Converter结合map来设置。User类的定义:

public class User implements Serializable {private Long id;private String code;private Date createTime;private Date updateTime;private Boolean isDelete;private String userName;private String email;private String phoneNumber;private String password;private String realName;private String nickName;private String avatar;// 省略getter, setter方法
}

UserModel的定义:

public class UserModel {private Long id;private String createTime;private String updateTime;private String userName;private String password;private String email;private String phoneNumber;private String name;private String nickName;private String avatar;// 省略 getter,setter方法
}

对象转换

在Controller控制器中,通过@Autowired注解得到ModelMapper实例,然后直接通过modelMapper.map(user, UserModel.class)转换得到VO层的UserModel对象,然后直接传给前端接口。

@RestController
@RequestMapping("user")
public class UserController {@Autowiredprivate UserMapper userMapper;@Autowiredprivate ModelMapper modelMapper;@GetMapping("{id}")public UserModel get(@PathVariable Long id) {User user  = userMapper.selectByPrimaryKey(id);if (user == null || user.getIsDelete()) {return null;}UserModel userModel = modelMapper.map(user, UserModel.class);return userModel;}
}

总结

以上就是SpringBoot项目中ModelMapper的常规使用,示例源码:https://gitee.com/flyduck128/springboot-demo/tree/master/flyduck-mybatis。使用ModelMapper可以大大提高开发人员对于对象转换的开发效率,特别适用于微服务中对象之间的转换。对于ModelMapper的详细配置以及高级使用可以参考官方文档。就如开篇所说的Java中对象转换的工具很多,ModelMapper常规使用配置简单,上手容易,同时也提供一些高级用法,同时由于使用的反射进行转换所以效率不是很高,对于效率要求不高的项目推荐使用ModelMapper。

拓展

国外朋友专门对Dozer,Orika,MapStruct,JMapper和ModelMapper进行了性能测试,测试地址:https://www.baeldung.com/java-performance-mapping-frameworks。测试结果为JMapper和MapStruct性能表现最好。如下是测试结果的部分截图:

SpringBoot项目中ModelMapper配置以及使用相关推荐

  1. springboot项目中利用@WebFilter注解和@Bean配置类两种方式实现Filter过滤器

    过滤器(Filter) 过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理.通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理 ...

  2. Spring-Boot:写出来的网站访问不到静态资源?怎样通过url访问SpringBoot项目中的静态资源?localhost:8989/favicon.ico访问不了工程中的图标资源?

    Spring-Boot:Spring-Boot写出来的网站访问不到静态资源?怎样通过url访问SpringBoot项目中的静态资源?localhost:8989/favicon.ico访问不了工程中的 ...

  3. 使用IDEA在SpringBoot项目中连接数据库

    使用IDEA在SpringBoot项目中连接数据库 文章目录 使用IDEA在SpringBoot项目中连接数据库 前言 连接数据库 正常操作数据库 移除数据库连接 前言 每次我在 IDEA 中用 Sp ...

  4. springboot项目中使用shiro 自定义过滤器和token的方式___shiro使用token登录流程

    springboot项目中使用shiro 自定义过滤器和token的方式 实现步骤主要是以下几步: 1. 在项目中导入maven依赖 <dependency><groupId> ...

  5. springboot项目中mybatis实现数据的基本查询

    SpringBoot项目中mybatis实现数据的基本查询 本章内容概述: mapper 查询 xml 文件基本使用 通过 mybatis 实现一条数据的查询 1 用户数据表 2 用户信息对应的实体类 ...

  6. SpringBoot项目中遇到的BUG

    1.启动项目的时候报错 1.Error starting ApplicationContext. To display the auto-configuration report re-run you ...

  7. 第六章:如何在SpringBoot项目中使用拦截器

    拦截器对使用SpringMvc.Struts的开发人员来说特别熟悉,因为你只要想去做好一个项目必然会用到它.拦截器在我们平时的项目中用处有很多,如:日志记录(我们后续章节会讲到).用户登录状态拦截.安 ...

  8. pycharm项目中如何安装包_如何将Thymeleaf技术集成到SpringBoot项目中

    给天气预报一个"面子" 截至目前,不仅有了天气预报的API接口,也有了数据的缓存方案.现在,就要进行天气预报服务的实现,也就是说,这里需要一个面向用户的应用.这个应用应该拥有友好的 ...

  9. springboot项目中favicon.ico的异常处理

    我在第一个springboot项目中没有设置项目名和拦截器以及spring.resources.static-locations,一切都是默认的配置,然后我将favicon.ico放在static目录 ...

最新文章

  1. 彻底弄懂 HTTP 缓存机制 —— 基于缓存策略三要素分解法
  2. html input 传值 request接到值为null,解决jsp向servlet传值为null的问题
  3. 高性能流媒体服务器EasyDSS前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间...
  4. (数据科学学习手札30)朴素贝叶斯分类器的原理详解Python与R实现
  5. 突发奇想:flash+.Net+数据库的一种构思
  6. Hat’s Words(HDU-1247)
  7. Signal 通过区块链慈善组织 The Giving Block 接受加密货币货币捐赠
  8. CLR_via_C#.3rd 翻译[25.9 线程调度和优先权]
  9. jaxb-xjc.jar_jaxb2-maven-plugin XJC示例,用于从XSD生成Java类
  10. 【面经】字节AI Lab-NLP算法热乎面经
  11. oracle数据库怎么查实例名,查询oracle数据库实例的名字
  12. 自然语言处理 朴素贝叶斯文本分类
  13. vue仿163musicPC端
  14. Linux上安装SAPGUI(附安装包)
  15. 2021年西式面点师(初级)考试平台及西式面点师(初级)模拟考试
  16. Streamset数据同步报错问题
  17. mencoder MPlayer 参数详细
  18. 当我们谈论Unidbg时我们在谈什么
  19. 文博界最早利用计算机技术的,现代计算机技术博物馆中的应用
  20. 博客搭建(基于hexo)

热门文章

  1. javascript设计模式-单体singleton模式(2)
  2. 线程进程计算之多任务同步进行
  3. 边缘设备、系统及计算杂谈(12)——k8s学习之二
  4. 场景文字检测之CTPN
  5. UVa-11212编辑书稿
  6. SAR ADC系列11:分段式CDAC
  7. 同指数幂相减公式_同底指数加减运算法则
  8. PowerBI-日期和时间函数-WEEKDAY\WEEKNUM
  9. 全平台EPUB阅读器-Neat Reader
  10. js实现小球抛物线运动