修复bug,增加用例

This commit is contained in:
linpeilie 2024-03-14 20:25:03 +08:00
parent 767e57df1c
commit 182bc024da
11 changed files with 215 additions and 5 deletions

131
README.md
View File

@ -1,8 +1,135 @@
# mapstruct-plus
## What is MapStruct Plus
MapStruct Plus is an enhancement to the MapStruct framework. It only does the enhancement, does not make the modification, and can automatically generate the transformation operation between two classes through an annotation, omitting the operation of defining the interface of MapStruct, makes Java type conversion easy and elegant.
Goal: To be the simplest and most powerful type conversion tool
**If this project helps you, hope to click a Star to encourage it!**
## Link
- [Document](https://mapstruct.plus)
## Other open source projects
- **EasyRelation**[GitHub](https://github.com/linpeilie/easy-relation) | [Gitee](https://gitee.com/easii/easy-relation) | [Document](https://easy-relation.easii.cn)
## Quick start
The following shows how to convert two objects using MapStructPlus.
Suppose there are two classes, `UserDto` and `User`, representing the data-layer object and business-layer object, respectively:
- `UserDto`
```java
public class UserDto {
private String username;
private int age;
private boolean young;
// getter、setter、toString、equals、hashCode
}
```
- `User`
```java
public class User {
private String username;
private int age;
private boolean young;
// getter、setter、toString、equals、hashCode
}
```
Introducing `mapstruct-plus-spring-boot-starter` dependencies:
```xml
<properties>
<mapstruct-plus.version>latest version</mapstruct-plus.version>
</properties>
<dependencies>
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
<version>${mapstruct-plus.version}</version>
</dependency>
</dependencies>
<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>
<annotationProcessorPaths>
<path>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-processor</artifactId>
<version>${mapstruct-plus.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
```
Test
```java
@SpringBootTest
public class QuickStartTest {
@Autowired
private Converter converter;
@Test
public void test() {
User user = new User();
user.setUsername("jack");
user.setAge(23);
user.setYoung(false);
UserDto userDto = converter.convert(user, UserDto.class);
System.out.println(userDto); // UserDto{username='jack', age=23, young=false}
assert user.getUsername().equals(userDto.getUsername());
assert user.getAge() == userDto.getAge();
assert user.isYoung() == userDto.isYoung();
User newUser = converter.convert(userDto, User.class);
System.out.println(newUser); // User{username='jack', age=23, young=false}
assert user.getUsername().equals(newUser.getUsername());
assert user.getAge() == newUser.getAge();
assert user.isYoung() == newUser.isYoung();
}
}
```
## Summary
With the introduction of dependencies, the steps to using MapStructPlus are very simple.
1. Add an `AutoMapper` annotation to the class you want to convert
2. Get the `Converter` instance and call the convert method.
--------
## 这是什么?
Mapstruct Plus 是对 Mapstruct 框架的一个增强,只做增强,不做修改,可以通过一个注解,自动生成两个类之间的转换操作,省略了 Mapstruct 定义接口的操作,使 Java 类型转换更加便捷、优雅。
MapStruct Plus 是对 MapStruct 框架的一个增强,只做增强,不做修改,可以通过一个注解,自动生成两个类之间的转换操作,省略了 Mapstruct 定义接口的操作,使 Java 类型转换更加便捷、优雅。
目标:做最简单、最强大的类型转换工具
@ -61,7 +188,7 @@ public class User {
```xml
<properties>
<mapstruct-plus.version>1.3.4</mapstruct-plus.version>
<mapstruct-plus.version>1.4.0</mapstruct-plus.version>
</properties>
<dependencies>
<dependency>

View File

@ -18,7 +18,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mapstruct.version>1.5.1.Final</mapstruct.version>
<mapstruct-plus.version>1.3.7-SNAPSHOTS</mapstruct-plus.version>
<mapstruct-plus.version>1.4.0</mapstruct-plus.version>
<lombok.version>1.18.22</lombok.version>
<hutool.version>5.8.26</hutool.version>
</properties>

View File

@ -0,0 +1,19 @@
package io.github.linpeilie.mapper;
import io.github.linpeilie.model.TreeNode;
import java.util.List;
import org.mapstruct.Condition;
import org.mapstruct.Named;
import org.springframework.boot.context.properties.bind.Name;
import org.springframework.stereotype.Component;
@Component
public class TreeNodeAwareMapper {
@Condition
@Named("limitLeastTwo")
public boolean limitLeastTwo(List<TreeNode> treeNodeList) {
return treeNodeList != null && treeNodeList.size() >= 2;
}
}

View File

@ -1,6 +1,7 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMapping;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -0,0 +1,18 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapper;
import io.github.linpeilie.annotations.AutoMapping;
import io.github.linpeilie.mapper.TreeNodeAwareMapper;
import java.util.List;
import lombok.Data;
@Data
@AutoMapper(target = TreeNodeDto.class, cycleAvoiding = true, uses = TreeNodeAwareMapper.class)
public class TreeNode {
private TreeNode parent;
@AutoMapping(conditionQualifiedByName = "limitLeastTwo")
private List<TreeNode> children;
}

View File

@ -0,0 +1,15 @@
package io.github.linpeilie.model;
import io.github.linpeilie.annotations.AutoMapper;
import java.util.List;
import lombok.Data;
@Data
@AutoMapper(target = TreeNode.class, cycleAvoiding = true)
public class TreeNodeDto {
private TreeNodeDto parent;
private List<TreeNodeDto> children;
}

View File

@ -189,7 +189,7 @@ public abstract class AbstractAdapterMapperGenerator {
// default impl
List<MethodSpec> defaultMethods = buildDefaultProxyMethod(adapterMethodMetadata,
ClassName.get("io.github.linpeilie.annotations", "DoIgnore"));
ClassName.get(ContextConstants.DoIgnore.packageName, ContextConstants.DoIgnore.className));
List<MethodSpec> methodSpecs = new ArrayList<>(defaultMethods);
ParameterSpec parameterSpec =

View File

@ -104,4 +104,9 @@ public interface ContextConstants {
String className = "MapObjectConvert";
}
interface DoIgnore {
String packageName = "io.github.linpeilie.annotations";
String className = "DoIgnore";
}
}

View File

@ -11,6 +11,7 @@ import com.squareup.javapoet.TypeSpec;
import io.github.linpeilie.processor.ContextConstants;
import io.github.linpeilie.processor.metadata.AutoMapperMetadata;
import io.github.linpeilie.processor.metadata.AutoMappingMetadata;
import io.github.linpeilie.utils.ArrayUtil;
import io.github.linpeilie.utils.CollectionUtils;
import io.github.linpeilie.utils.StrUtil;
import java.io.IOException;
@ -114,6 +115,7 @@ public class AutoMapperGenerator {
final MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder(methodName)
.addParameters(parameterSpecs)
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
.addAnnotation(ClassName.get(ContextConstants.DoIgnore.packageName, ContextConstants.DoIgnore.className))
.returns(target);
if (CollectionUtils.isNotEmpty(autoMappingMetadataList)) {
methodSpecBuilder.addAnnotations(buildMappingAnnotations(autoMappingMetadataList));

View File

@ -0,0 +1,23 @@
package io.github.linpeilie.utils;
import java.util.Arrays;
import java.util.stream.Collectors;
public class ArrayUtil {
public static <T> boolean isNotEmpty(T[] arr) {
return arr != null && arr.length > 0;
}
public static <T> String join(T[] arr, CharSequence delimiter) {
return join(arr, delimiter, "", "");
}
public static <T> String join(T[] arr, CharSequence delimiter, String prefix, String suffix) {
if (arr == null) {
return null;
}
return Arrays.stream(arr).map(str -> prefix + str + suffix).collect(Collectors.joining(delimiter));
}
}

View File

@ -18,7 +18,7 @@
</modules>
<properties>
<mapstruct-plus.version>1.3.7-SNAPSHOTS</mapstruct-plus.version>
<mapstruct-plus.version>1.4.0</mapstruct-plus.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>