Project Lombok是一个有助于样板代码的库,使我们能够更加专注于核心应用程序逻辑。
类似地,当我们需要两个 Java bean 之间的映射时,MapStruct是另一个可以帮助提供样板的库。
在本教程中,我们将研究如何有效地结合使用这两个库:
使用@Builder和@Data Lombok 注释。前者允许通过Builder 模式创建对象,而后者通过 setter 提供基于构造函数的对象创建。
设置
我们将mapstruct、lombok和lombok-mapstruct-binding依赖项添加到我们的pom.xml中:
<dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.6.0.Beta2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.32</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok-mapstruct-binding</artifactId> <version>0.2.0</version> </dependency>
|
MapStruct 与 Lombok 集成
我们将在设置中使用@Builder和@Data Lombok 注释。前者允许通过Builder 模式创建对象,而后者通过 setter 提供基于构造函数的对象创建。
1. Java POJO 设置
现在,让我们首先为映射器定义一个简单的源类:
@Data public class SimpleSource { private String name; private String description; }
|
接下来,我们为映射器定义一个简单的目标类:@Data public class SimpleDestination { private String name; private String description; }
|
最后,我们还将定义另一个目标类,但使用@Builder Lombok 注释:@Builder @Getter public class LombokDestination { private String name; private String description; }
|
2. 使用@Mapper注解
当我们使用@Mapper注释时,MapStruct会自动创建映射器实现。
让我们定义映射器接口:
@Mapper public interface LombokMapper { SimpleDestination sourceToDestination(SimpleSource source); LombokDestination sourceToLombokDestination(SimpleSource source); }
|
当我们执行mvn clean install命令时,会在/target/generated-sources/annotations/文件夹下创建mapper实现类。我们来看一下生成的实现类:
public class LombokMapperImpl implements LombokMapper { @Override public SimpleDestination sourceToDestination(SimpleSource source) { if ( source == null ) { return null; } SimpleDestination simpleDestination = new SimpleDestination(); simpleDestination.setName( source.getName() ); simpleDestination.setDescription( source.getDescription() ); return simpleDestination; } @Override public LombokDestination sourceToLombokDestination(SimpleSource source) { if ( source == null ) { return null; } LombokDestination.LombokDestinationBuilder lombokDestination = LombokDestination.builder(); lombokDestination.name( source.getName() ); lombokDestination.description( source.getDescription() ); return lombokDestination.build(); } }
|
正如我们在这里看到的,实现有两种方法可以将源对象映射到不同的目标。然而,主要的区别在于目标对象的构建方式。该实现使用LombokDestination类的builder()方法。另一方面,它使用构造函数创建SimpleDestination对象并使用 setter 映射变量。
3. 测试用例
现在,让我们看一个简单的测试用例来查看映射器的实际实现:
@Test void whenDestinationIsMapped_thenIsSuccessful() { SimpleSource simpleSource = new SimpleSource(); simpleSource.setName("file"); simpleSource.setDescription("A text file."); SimpleDestination simpleDestination = lombokMapper.sourceToDestination(simpleSource); Assertions.assertNotNull(simpleDestination); Assertions.assertEquals(simpleSource.getName(), simpleDestination.getName()); Assertions.assertEquals(simpleSource.getDescription(), simpleDestination.getDescription()); LombokDestination lombokDestination = lombokMapper.sourceToLombokDestination(simpleSource); Assertions.assertNotNull(lombokDestination); Assertions.assertEquals(simpleSource.getName(), lombokDestination.getName()); Assertions.assertEquals(simpleSource.getDescription(), lombokDestination.getDescription()); }
|
正如我们可以在上面的测试用例中验证的那样,映射器实现成功地将源 POJO 映射到两个目标 POJO。结论
在本文中,我们研究了如何结合使用 MapStruct 和 Lombok 来帮助我们减少样板代码的编写,从而增强代码的可读性并提高开发过程的效率。