ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

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

2026/9/14 4:57:36 拓冰建站 浏览量
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本身是使用递归的方式去做的。
也就是说如果你要转换的对象内嵌套了其他对象,也是可以复制的。