Orika MapperFacade 对象属性复制在SpringBoot项目中的使用

文章目录

  • 前言
  • 正文
    • 一、项目代码
      • 1.1 maven依赖
      • 1.2 核心配置文件
      • 1.3 时间工具类
      • 1.4 实体类
      • 1.5 转换对象的调用
    • 二、MapperFacade API

前言

众所周知,在Java项目中经常会有用到各种对象属性复制的情况,以及从一个对象转换为另一个对象。

之前我们可能会使用以下工具:

  • BeanUtils.copyProperties(A, B);
  • MapStruct 对象映射

今天我们来一起看看另一种功能同样强大,性能也很高的工具!就是Orika MapperFacade

正文

在SpringBoot项目中,我们使用Orika MapperFacade时也是非常方便的。以下会用代码举例。

一、项目代码

项目环境是java1.8,使用了Springboot的2.x版本。

1.1 maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.feng</groupId><artifactId>mapper-facade-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>mapper-facade-demo</name><description>mapper-facade-demo</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.7.6</spring-boot.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.gitlab.haynes</groupId><artifactId>orika-spring-boot-starter</artifactId><version>1.26.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>org.feng.MapperFacadeDemoApplication</mainClass><skip>true</skip></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

1.2 核心配置文件

因为在转换java8的时间类(诸如LocalDateTime等)时,会有格式问题,所以增加了类转换器。

package org.feng.config;import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.converter.BidirectionalConverter;
import ma.glasnost.orika.converter.ConverterFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.Type;
import org.feng.util.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.time.LocalDateTime;/*** mapperFacade配置** @author feng*/
@Configuration
public class MapperFacadeConfig {@Beanpublic MapperFactory mapperFactory() {DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder()// 忽略映射空字段.mapNulls(false).build();ConverterFactory converterFactory = mapperFactory.getConverterFactory();// 注册时间转换器converterFactory.registerConverter(new LocalDateTimeStrConverter());return mapperFactory;}@Beanpublic MapperFacade mapperFacade(@Autowired MapperFactory mapperFactory) {return mapperFactory.getMapperFacade();}private static class LocalDateTimeStrConverter extends BidirectionalConverter<LocalDateTime, String> {@Overridepublic String convertTo(LocalDateTime localDateTime, Type<String> type, MappingContext mappingContext) {return TimeUtil.parse(localDateTime);}@Overridepublic LocalDateTime convertFrom(String str, Type<LocalDateTime> type, MappingContext mappingContext) {return TimeUtil.format(str);}}
}

1.3 时间工具类

package org.feng.util;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;/*** 时间工具类** @version v1.0* @author: fengjinsong* @date: 2024年01月18日 22时40分*/
public class TimeUtil {private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");public static String parse(LocalDateTime localDateTime) {if (localDateTime == null) {return "";}return DATE_TIME_FORMATTER.format(localDateTime);}public static LocalDateTime format(String dateTime) {if (dateTime == null) {return null;}return LocalDateTime.parse(dateTime, DATE_TIME_FORMATTER);}
}

1.4 实体类

为了简化文章篇幅,这里将用到的实体类放在了一起。

@Data
public class Order {private Long id;private String code;private String type;private String desc;private LocalDateTime createDateTime;
}@Data
public class User {private Long id;private String userName;private String email;private LocalDateTime birthday;private LocalDate registerDay;private List<Order> orders;
}@Data
public class OrderVO {private Long id;private String code;private String type;private String desc;private String createDateTime;
}@Data
public class UserVO {private Long id;private String name;private String email;private String birthday;private LocalDate registerDay;private List<OrderVO> orders;
}

1.5 转换对象的调用

为了方便,直接在启动类中进行操作。在springboot项目启动后,会执行对应的转换代码。

package org.feng;import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.BoundMapperFacade;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import org.feng.entity.Order;
import org.feng.entity.User;
import org.feng.vo.UserVO;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;@Slf4j
@SpringBootApplication
public class MapperFacadeDemoApplication implements CommandLineRunner {@Resourceprivate MapperFactory mapperFactory;public static void main(String[] args) {SpringApplication.run(MapperFacadeDemoApplication.class, args);}@Overridepublic void run(String... args) throws Exception {// 存在不同字段名映射,需要增加映射规则;字段名完全相同时,可以直接获取mapperFacade实例进行转换mapperFactory.classMap(User.class, UserVO.class).field("userName", "name").byDefault().register();BoundMapperFacade<User, UserVO> mapperFacade = mapperFactory.getMapperFacade(User.class, UserVO.class);User user = new User();user.setUserName("玑而");user.setId(2L);user.setBirthday(LocalDateTime.now());user.setRegisterDay(LocalDate.of(2023,12,21));List<Order> orders = new ArrayList<>();Order order = new Order();order.setCreateDateTime(LocalDateTime.now());order.setId(21L);order.setCode("323d2");orders.add(order);user.setOrders(orders);UserVO userVO = mapperFacade.map(user);log.info(userVO.toString());}
}

控制台输出:

UserVO(id=2, name=玑而, email=null, birthday=2024-01-31 11:47:50, registerDay=2023-12-21, orders=[OrderVO(id=21, code=323d2, type=null, desc=null, createDateTime=2024-01-31 11:47:50)])

二、MapperFacade API

  • map(…) 普通对象转换
  • mapAsArray(…) 数组转换为数组
  • mapAsCollection(…) 集合转换为集合
  • mapAsList(…) 转换list
  • mapAsSet(…) 转换set
  • mapAsMap(…) 转换map
  • newObject(…) 创建一个新对象

另外需要注意一下,MapperFacade本身是使用递归的方式去做的。
也就是说如果你要转换的对象内嵌套了其他对象,也是可以复制的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/661079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rust 泛型、多态

一&#xff0c;泛型 1&#xff0c;泛型函数 下面是一个手动实现vec翻转的例子&#xff1a; fn vector_reverse<T:Clone> (v:&Vec<T>)->Vec<T>{let mut ans Vec::new();let mut i v.len();loop {if i0{break;}i-1;ans.push(v[i].clone());}return…

没有外网Nginx如何配置如何开启https

判断是否支持open-ssl 在服务器执行如下命令 openssl version没有则安装open-ssl&#xff0c;由于服务器没有外网&#xff0c;可以离线安装openssl-3.0.1.tar.gz&#xff0c;我是在有网的服务器直接下载的&#xff0c;然后再上传到这台无网的服务器上 wget https://www.open…

C++内存管理与模板

C内存管理与模板 文章目录 C内存管理与模板前言&#xff1a;一.new和delete基本用法二.底层实现三.定位new四.模板4.1函数模板4.2调用选择4.3类模板4.4声明定义分离 前言&#xff1a; C的内存管理和C语言中动态内存分配是相似的&#xff0c;在这一篇我们会学到更符合面向对象的…

如何快速写出高效的软件测试用例

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 前言 编写测试用例的目的就是确保测试过程全面高效、有据可查。但要编写出高效的测试用例&#…

【Django-ninja】django-ninja的hello world

django-ninja简介 Django Ninja是一个用于使用Django和Python 3.6类型提示构建API的Web框架。 主要特点&#xff1a; 易用性&#xff1a;旨在易于使用和直观。 高性能执行&#xff1a;由于Pydantic和异步支持&#xff0c;具有非常高的性能。 编码效率高&#xff1a;类型提…

鸿蒙harmony--TypeScript基础语法

把青春献给身后那座辉煌的都市&#xff0c;为了这个美梦我们付出着代价 目录 一&#xff0c;基础类型 二&#xff0c;数组 三&#xff0c;any 四&#xff0c;变量的类型注释 五&#xff0c;函数 5.1 参数类型注解 5.2 返回类型注解 5.3 匿名函数 六&#xff0c;对象类型 可选属…

APP攻防-资产收集篇反证书检验XP框架反代理VPN数据转发反模拟器

知识点 1、APP资产-抓包突破&反模拟器 2、APP资产-抓包突破&反证书检验 3、APP资产-抓包突破&反代理VPN 章节点&#xff1a; 1、APP资产-内在提取&外在抓包 2、APP逆向-反编译&删验证&重打包 3、APP安全-存储&服务&组件&注册等 专题点&…

HDFS HA 之 HA 原理

1 ZKFC解析 HA(High Availability)是HDFS支持的一个重要特性,可以有效解决Active Namenode遇到故障时,将可用的Standby节点变成新的Active状态的问题,使集群能够正常工作。目前支持冷切换和热切换两种方式。冷切换通过手动触发,缺点是不能够及时恢复集群。实际生产中以应用…

2024年【危险化学品经营单位主要负责人】报名考试及危险化学品经营单位主要负责人免费试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位主要负责人报名考试参考答案及危险化学品经营单位主要负责人考试试题解析是安全生产模拟考试一点通题库老师及危险化学品经营单位主要负责人操作证已考过的学员汇总&#xff0c;相对有效帮助危险化…

LeetCode:49. 字母异位词分组

49. 字母异位词分组 1&#xff09;题目2&#xff09;代码3&#xff09;结果 1&#xff09;题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs…

tkMapper 通用mapper的批量更新 批量新增 官方实现 springboot项目 依赖引入

文章目录 场景官方插件源码解析项目细节小结 场景 在许多业务场景下&#xff0c;需要对tkMapper的功能进行增强&#xff0c;需要用到批量新增和批量更新&#xff08;这里是唯一主键去更新的&#xff09;&#xff0c;许多论文博客自己写的看起来并不行&#xff0c;我们这里就采…

python爬虫3

1.异常处理&#xff0c;使代码更加健壮 静态cookie可视绕过登录的限制 快代理是一个代理平台 # https://movie.douban.com/j/chart/top_list?type5&interval_id100%3A90&action& # start0&limit20# https://movie.douban.com/j/chart/top_list?type5&int…

【LNMP】RHEL8.3安装LNMP并配置freetds连接MSSQL

【RHEL8.3安装LNMP并配置freetds连接MSSQL】 1.1.安装MYSQL(安装LNMP前置条件): rpm -ivh mysql-community-client-8.3.0-1.el8.x86_64.rpm rpm -ivh mysql-community-common-8.3.0-1.el8.x86_64.rpm rpm -ivh mysql-community-icu-data-files-8.3.0-1.el8.x86_64.rpm rpm -…

352. 闇の連鎖(树上差分,LCA)

352. 闇の連鎖 - AcWing题库 传说中的暗之连锁被人们称为 Dark。 Dark 是人类内心的黑暗的产物&#xff0c;古今中外的勇者们都试图打倒它。 经过研究&#xff0c;你发现 Dark 呈现无向图的结构&#xff0c;图中有 N 个节点和两类边&#xff0c;一类边被称为主要边&#xff…

聊聊PowerJob的ServerDeployContainerRequest

序 本文主要研究一下PowerJob的ServerDeployContainerRequest ServerDeployContainerRequest tech/powerjob/common/request/ServerDeployContainerRequest.java Data NoArgsConstructor AllArgsConstructor public class ServerDeployContainerRequest implements PowerSe…

【数据结构】 归并排序超详解

1.基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。 将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;即先使每个子序列有序…

Vue3的Props

Vue 3中的props是用于接收父组件传递的数据的属性。在Vue 3中&#xff0c;props的声明发生了一些改变&#xff1a; 使用props选项来声明props。之前的版本中使用props属性来声明&#xff0c;但在Vue 3中改为使用props选项。通过TypeScript或Flow来静态类型检查props。Vue 3允许…

关于智能指针

实现自己的智能指针 //智能指针 保证能做到资源的自动释放 //利用栈上的对象出作用域自动析构的特征&#xff0c;来做到资源的自动释放的 template<typename T> class CSmartPtr { public:CSmartPtr(T *ptr nullptr):mptr(ptr) {}~CSmartPtr() { delete mptr; } privat…

Spring实现事务(一)

Spring事务 .什么是事务事务的操作Spring中事务的实现准备工作创建表创建项目,引入Spring Web, Mybatis, mysql等依赖配置文件实体类 编程式事务(手动写代码操作事务)声明式事务(利用注解自动开启和提交事务) . 什么是事务 事务是⼀组操作的集合, 是⼀个不可分割的操作 在我们…

国产校准件

国产校准件 Ceyear系列校准件是矢量网络分析仪的测试附件&#xff0c;可大幅提高矢量网络分析仪的测试精度。规格品种丰富&#xff0c;涵盖多种同轴、波导校准件&#xff0c;校准精度高&#xff0c;重复性好 功能特点 校准件 校准模块可实现更精准的测量&#xff0c;满足您的测…