diff --git a/.dumirc.ts b/.dumirc.ts index 5473f2c..a34fea9 100644 --- a/.dumirc.ts +++ b/.dumirc.ts @@ -4,7 +4,7 @@ export default defineConfig({ themeConfig: { name: 'mapstruct-plus', logo: false, - nav: [{ title: '指南', link: '/guide' }], + autoAlias: false, prefersColor: { default: 'auto' }, github: 'https://github.com/linpeilie', footer: false diff --git a/docs/guide.md b/docs/guide.md deleted file mode 100644 index 5504ddf..0000000 --- a/docs/guide.md +++ /dev/null @@ -1 +0,0 @@ -This is a guide example. diff --git a/docs/guide/index.md b/docs/guide/index.md new file mode 100644 index 0000000..110894c --- /dev/null +++ b/docs/guide/index.md @@ -0,0 +1,7 @@ +--- +nav: 指南 +--- + +# 介绍 + +这里是 MapStruct Plus 的介绍 diff --git a/docs/guide/quick-start.md b/docs/guide/quick-start.md new file mode 100644 index 0000000..e4bf675 --- /dev/null +++ b/docs/guide/quick-start.md @@ -0,0 +1,203 @@ +# 快速开始 + +下面演示如何使用 MapStruct Plus 来映射两个对象。 + +假设有两个类 `UserDto` 和 `User`,分别表示数据层对象和业务层对象: + +- `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 +} +``` + +## 非 Spring 环境 + +### 添加依赖 + +引入 `mapstruct-plus` 依赖: + +```xml + + 最新版本 + + + + io.github.linpeilie + mapstruct-plus + {mapstruct-plus.version} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + io.github.linpeilie + mapstruct-plus-processor + ${mapstruct-plus.version} + + + + + + +``` + +### 添加配置类 + +在 Bean 对象所在模块包中,任意类上增加注解:`@ComponentModelConfig(componentModel = "default")` + +例如: + +```java +@ComponentModelConfig(componentModel = "default") +public class MapperConfiguration { +} +``` + +### 指定对象映射关系 + +在 `User` 或者 `UserDto` 上面增加注解 —— `@AutoMapper`,并设置 `targetType` 为对方类。 + +例如: + +```java +@AutoMapper(target = UserDto.class) +public class User { + // ... +} +``` + +### 测试 + +```java +public class QuickStart { + + private static Converter converter = new Converter(); + + public static void main(String[] args) { + 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(); + } + +} +``` + +## SpringBoot 环境 + +### 添加依赖 + +引入 `mapstruct-plus-spring-boot-starter` 依赖: + +```xml + + 最新版本 + + + + io.github.linpeilie + mapstruct-plus + {mapstruct-plus.version} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + io.github.linpeilie + mapstruct-plus-processor + ${mapstruct-plus.version} + + + + + + +``` + +### 指定对象映射关系 + +同非 Spring 环境 + +### 测试 + +```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(); + } + +} +``` diff --git a/example/pom.xml b/example/pom.xml index 47cb37d..e44f061 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -59,11 +59,6 @@ 1.8 1.8 - - org.mapstruct - mapstruct-processor - ${mapstruct.version} - io.github.linpeilie mapstruct-plus-processor diff --git a/example/quick-start/src/main/java/io/github/linpeilie/QuickStart.java b/example/quick-start/src/main/java/io/github/linpeilie/QuickStart.java index 117efe9..946424b 100644 --- a/example/quick-start/src/main/java/io/github/linpeilie/QuickStart.java +++ b/example/quick-start/src/main/java/io/github/linpeilie/QuickStart.java @@ -1,20 +1,32 @@ package io.github.linpeilie; -import io.github.linpeilie.model.Car; -import io.github.linpeilie.model.CarDto; -import io.github.linpeilie.model.CarType; +import io.github.linpeilie.model.User; +import io.github.linpeilie.model.UserDto; public class QuickStart { private static Converter converter = new Converter(); public static void main(String[] args) { + User user = new User(); + user.setUsername("jack"); + user.setAge(23); + user.setYoung(false); - final Car car = new Car(); - car.setType(CarType.OTHER); + UserDto userDto = converter.convert(user, UserDto.class); + System.out.println(userDto); // UserDto{username='jack', age=23, young=false} - final CarDto carDto = converter.convert(car, CarDto.class); - System.out.println(carDto); + 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(); } } \ No newline at end of file diff --git a/example/quick-start/src/main/java/io/github/linpeilie/model/User.java b/example/quick-start/src/main/java/io/github/linpeilie/model/User.java new file mode 100644 index 0000000..6430977 --- /dev/null +++ b/example/quick-start/src/main/java/io/github/linpeilie/model/User.java @@ -0,0 +1,63 @@ +package io.github.linpeilie.model; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.Objects; + +@AutoMapper(target = UserDto.class) +public class User { + + private String username; + private int age; + private boolean young; + + public String getUsername() { + return username; + } + + public void setUsername(final String username) { + this.username = username; + } + + public int getAge() { + return age; + } + + public void setAge(final int age) { + this.age = age; + } + + public boolean isYoung() { + return young; + } + + public void setYoung(final boolean young) { + this.young = young; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final User user = (User) o; + return getAge() == user.getAge() && isYoung() == user.isYoung() && + Objects.equals(getUsername(), user.getUsername()); + } + + @Override + public int hashCode() { + return Objects.hash(getUsername(), getAge(), isYoung()); + } + + @Override + public String toString() { + return "User{" + + "username='" + username + '\'' + + ", age=" + age + + ", young=" + young + + '}'; + } +} diff --git a/example/quick-start/src/main/java/io/github/linpeilie/model/UserDto.java b/example/quick-start/src/main/java/io/github/linpeilie/model/UserDto.java new file mode 100644 index 0000000..8731e18 --- /dev/null +++ b/example/quick-start/src/main/java/io/github/linpeilie/model/UserDto.java @@ -0,0 +1,62 @@ +package io.github.linpeilie.model; + +import java.util.Objects; + +public class UserDto { + + private String username; + private int age; + private boolean young; + + public String getUsername() { + return username; + } + + public void setUsername(final String username) { + this.username = username; + } + + public int getAge() { + return age; + } + + public void setAge(final int age) { + this.age = age; + } + + public boolean isYoung() { + return young; + } + + public void setYoung(final boolean young) { + this.young = young; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final UserDto user = (UserDto) o; + return getAge() == user.getAge() && isYoung() == user.isYoung() && + Objects.equals(getUsername(), user.getUsername()); + } + + @Override + public int hashCode() { + return Objects.hash(getUsername(), getAge(), isYoung()); + } + + @Override + public String toString() { + return "UserDto{" + + "username='" + username + '\'' + + ", age=" + age + + ", young=" + young + + '}'; + } + +} diff --git a/example/spring-boot/pom.xml b/example/spring-boot/pom.xml index 55ec3a2..7a24341 100644 --- a/example/spring-boot/pom.xml +++ b/example/spring-boot/pom.xml @@ -22,6 +22,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-test + io.github.linpeilie mapstruct-plus-spring-boot-starter diff --git a/example/spring-boot/src/main/java/io/github/linpeilie/model/User.java b/example/spring-boot/src/main/java/io/github/linpeilie/model/User.java new file mode 100644 index 0000000..6430977 --- /dev/null +++ b/example/spring-boot/src/main/java/io/github/linpeilie/model/User.java @@ -0,0 +1,63 @@ +package io.github.linpeilie.model; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.Objects; + +@AutoMapper(target = UserDto.class) +public class User { + + private String username; + private int age; + private boolean young; + + public String getUsername() { + return username; + } + + public void setUsername(final String username) { + this.username = username; + } + + public int getAge() { + return age; + } + + public void setAge(final int age) { + this.age = age; + } + + public boolean isYoung() { + return young; + } + + public void setYoung(final boolean young) { + this.young = young; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final User user = (User) o; + return getAge() == user.getAge() && isYoung() == user.isYoung() && + Objects.equals(getUsername(), user.getUsername()); + } + + @Override + public int hashCode() { + return Objects.hash(getUsername(), getAge(), isYoung()); + } + + @Override + public String toString() { + return "User{" + + "username='" + username + '\'' + + ", age=" + age + + ", young=" + young + + '}'; + } +} diff --git a/example/spring-boot/src/main/java/io/github/linpeilie/model/UserDto.java b/example/spring-boot/src/main/java/io/github/linpeilie/model/UserDto.java new file mode 100644 index 0000000..8731e18 --- /dev/null +++ b/example/spring-boot/src/main/java/io/github/linpeilie/model/UserDto.java @@ -0,0 +1,62 @@ +package io.github.linpeilie.model; + +import java.util.Objects; + +public class UserDto { + + private String username; + private int age; + private boolean young; + + public String getUsername() { + return username; + } + + public void setUsername(final String username) { + this.username = username; + } + + public int getAge() { + return age; + } + + public void setAge(final int age) { + this.age = age; + } + + public boolean isYoung() { + return young; + } + + public void setYoung(final boolean young) { + this.young = young; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final UserDto user = (UserDto) o; + return getAge() == user.getAge() && isYoung() == user.isYoung() && + Objects.equals(getUsername(), user.getUsername()); + } + + @Override + public int hashCode() { + return Objects.hash(getUsername(), getAge(), isYoung()); + } + + @Override + public String toString() { + return "UserDto{" + + "username='" + username + '\'' + + ", age=" + age + + ", young=" + young + + '}'; + } + +} diff --git a/example/spring-boot/src/test/java/io/github/linpeilie/QuickStartTest.java b/example/spring-boot/src/test/java/io/github/linpeilie/QuickStartTest.java new file mode 100644 index 0000000..10dd5f0 --- /dev/null +++ b/example/spring-boot/src/test/java/io/github/linpeilie/QuickStartTest.java @@ -0,0 +1,38 @@ +package io.github.linpeilie; + +import io.github.linpeilie.model.User; +import io.github.linpeilie.model.UserDto; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@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(); + } + +} diff --git a/mapstruct-plus-processor/pom.xml b/mapstruct-plus-processor/pom.xml index 6813fbc..bc5f195 100644 --- a/mapstruct-plus-processor/pom.xml +++ b/mapstruct-plus-processor/pom.xml @@ -31,6 +31,10 @@ org.apache.commons commons-lang3 + + org.mapstruct + mapstruct-processor + diff --git a/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor index b709847..78ca476 100644 --- a/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ b/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -1 +1,2 @@ -io.github.linpeilie.processor.AutoMapperProcessor \ No newline at end of file +io.github.linpeilie.processor.AutoMapperProcessor +org.mapstruct.ap.MappingProcessor \ No newline at end of file diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java b/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java index 77fbd57..ea5417c 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java @@ -7,6 +7,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; +import java.util.regex.Matcher; import org.mapstruct.factory.Mappers; public class DefaultConverterFactory extends AbstractCachedConverterFactory { @@ -61,7 +62,8 @@ public class DefaultConverterFactory extends AbstractCachedConverterFactory { } try { String classPath = file.getPath(); - String className = classPath.substring(root.length() + 1, classPath.length() - 6).replaceAll("/", "."); + String className = classPath.substring(root.length() + 1, classPath.length() - 6) + .replaceAll(Matcher.quoteReplacement(File.separator), "."); classes.add(classLoader.loadClass(className)); } catch (Exception e) { e.printStackTrace(); @@ -83,7 +85,7 @@ public class DefaultConverterFactory extends AbstractCachedConverterFactory { private String getMapperPackage(Class sourceType) { return basePackage != null && !basePackage.isEmpty() ? basePackage - : sourceType.getPackage().getName(); + : sourceType.getPackage().getName(); } @Override diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/ComponentModelConfig.java b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/ComponentModelConfig.java index 643023d..d63c97c 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/ComponentModelConfig.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/ComponentModelConfig.java @@ -9,6 +9,6 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.SOURCE) public @interface ComponentModelConfig { - String componentModel() default "default"; + String componentModel() default "spring"; } diff --git a/pom.xml b/pom.xml index 8c839d6..da7b770 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ 8 8 UTF-8 + 1.5.1.Final @@ -46,7 +47,12 @@ org.mapstruct mapstruct - 1.5.1.Final + ${mapstruct.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} org.springframework