Merge branch 'main' into 1.3.6
@ -1,13 +0,0 @@
|
||||
import { defineClientConfig } from '@vuepress/client'
|
||||
|
||||
export default defineClientConfig({
|
||||
enhance({ router }) {
|
||||
router.beforeEach((to) => {
|
||||
if (typeof _hmt !== "undefined") {
|
||||
if (to.path) {
|
||||
_hmt.push(["_trackPageview", to.fullPath]);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
@ -1,76 +1,28 @@
|
||||
import {defineUserConfig} from "vuepress";
|
||||
import {shikiPlugin} from "@vuepress/plugin-shiki";
|
||||
import {searchPlugin} from "@vuepress/plugin-search";
|
||||
import {googleAnalyticsPlugin} from "@vuepress/plugin-google-analytics"
|
||||
import { componentsPlugin } from "vuepress-plugin-components"
|
||||
|
||||
import theme from "./theme.js";
|
||||
import { defineUserConfig } from "vuepress";
|
||||
import type { DefaultThemeOptions } from "vuepress";
|
||||
import recoTheme from "vuepress-theme-reco";
|
||||
import { themeConfig } from './config/index'
|
||||
|
||||
export default defineUserConfig({
|
||||
base: "/",
|
||||
|
||||
head: [
|
||||
['script', {}, `
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?fab881821b3db8a7c460db1c91ea0f3a";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
`],
|
||||
['meta', {name: 'baidu-site-verification', content: 'codeva-OceTRzMGJ2'}],
|
||||
['meta', {name: 'bytedance-verification-code', content: 'fXSJ80ILSanHaf/RIZGQ'}],
|
||||
],
|
||||
|
||||
locales: {
|
||||
"/": {
|
||||
lang: "zh-CN",
|
||||
title: "MapstructPlus",
|
||||
description: "MapstructPlus指南",
|
||||
},
|
||||
locales: {
|
||||
'/': {
|
||||
lang: '中文',
|
||||
title: 'MapStructPlus',
|
||||
description: '',
|
||||
},
|
||||
'/en/': {
|
||||
lang: 'English',
|
||||
title: 'MapStructPlus',
|
||||
description: ''
|
||||
}
|
||||
},
|
||||
theme: recoTheme(themeConfig),
|
||||
markdown: {
|
||||
anchor: {
|
||||
permalink: false,
|
||||
permalinkBefore: false
|
||||
}
|
||||
}
|
||||
|
||||
theme,
|
||||
|
||||
plugins: [
|
||||
shikiPlugin({
|
||||
theme: 'one-dark-pro'
|
||||
}),
|
||||
searchPlugin({
|
||||
isSearchable: (page) => page.path !== '/'
|
||||
}),
|
||||
googleAnalyticsPlugin({
|
||||
id: 'G-SXEZVNR8FZ'
|
||||
}),
|
||||
// componentsPlugin({
|
||||
// rootComponents: {
|
||||
// notice: [
|
||||
// {
|
||||
// path: "/",
|
||||
// title: "推荐最新开源项目 EasyRelation",
|
||||
// content: "EasyRelation 是一个简单、高效的自动关联数据框架,可以通过一行代码,自动关联查询并填充需要的数据,对于性能影响极小,且省略了大量冗余代码。",
|
||||
// actions: [
|
||||
// {
|
||||
// text: "GitHub",
|
||||
// link: "https://github.com/linpeilie/easy-relation",
|
||||
// type: "default",
|
||||
// },
|
||||
// {
|
||||
// text: "Gitee",
|
||||
// link: "https://gitee.com/easii/easy-relation",
|
||||
// "type": "default"
|
||||
// },
|
||||
// {
|
||||
// text: "Document",
|
||||
// link: "https://easy-relation.easii.cn",
|
||||
// "type": "primary"
|
||||
// },
|
||||
// ],
|
||||
// fullscreen: false,
|
||||
// }
|
||||
// ],
|
||||
// },
|
||||
// }),
|
||||
]
|
||||
// debug: true,
|
||||
});
|
||||
|
||||
2
docs/.vuepress/config/en/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './navbar'
|
||||
export * from './series'
|
||||
4
docs/.vuepress/config/en/navbar.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export const navbar = [
|
||||
{ text: 'Home', link: '/en/', icon: 'Home' },
|
||||
{ text: 'Guide', link: '/en/guide/class-convert', icon: 'Api' },
|
||||
]
|
||||
30
docs/.vuepress/config/en/series.ts
Normal file
@ -0,0 +1,30 @@
|
||||
export const series = {
|
||||
"/en": [
|
||||
{
|
||||
text: 'Introduction',
|
||||
children: [
|
||||
{ text: 'About', link: '/en/introduction/about' },
|
||||
{ text: 'Quick Start', link: '/en/introduction/quick-start' },
|
||||
{ text: 'Install', link: '/en/introduction/install' },
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Guide',
|
||||
children: [
|
||||
{ text: 'Conversion between two classes', link: '/en/guide/class-convert' },
|
||||
{ text: 'Map to object', link: '/en/guide/map-to-class' },
|
||||
{ text: 'Conversion for enum', link: '/en/guide/enum-convert' },
|
||||
{ text: 'Class converted with multiple class', link: '/en/guide/multiple-class-convert' },
|
||||
{ text: 'Api', link: '/en/guide/converter-api' },
|
||||
{ text: 'Configuration', link: '/en/guide/configuration' },
|
||||
{ text: 'Faq', link: '/en/guide/faq' },
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Release Log',
|
||||
children: [
|
||||
{ text: 'Release Log', link: '/en/release/log' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
26
docs/.vuepress/config/index.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import * as zhConfig from './zh'
|
||||
import * as enConfig from './en'
|
||||
|
||||
export const themeConfig = {
|
||||
locales: {
|
||||
'/': {
|
||||
selectLanguageText: 'Languages',
|
||||
selectLanguageName: '简体中文',
|
||||
lastUpdateText: '最后更新时间',
|
||||
navbar: zhConfig.navbar,
|
||||
series: zhConfig.series
|
||||
},
|
||||
'/en/': {
|
||||
selectLanguageText: 'Languages',
|
||||
selectLanguageName: 'English',
|
||||
navbar: enConfig.navbar,
|
||||
series: enConfig.series
|
||||
}
|
||||
},
|
||||
logo: '/logo.svg',
|
||||
author: 'linpeilie',
|
||||
docsRepo: "https://github.com/linpeilie/mapstruct-plus",
|
||||
docsBranch: "main",
|
||||
docsDir: "/docs",
|
||||
|
||||
}
|
||||
2
docs/.vuepress/config/zh/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './navbar'
|
||||
export * from './series'
|
||||
5
docs/.vuepress/config/zh/navbar.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export const navbar = [
|
||||
{ text: '首页', link: '/', icon: 'Home' },
|
||||
{ text: '指南', link: '/guide/class-convert', icon: 'Api' },
|
||||
{ text: 'MapStruct 中文文档', link: '/mapstruct/1-5-5-Final' }
|
||||
]
|
||||
38
docs/.vuepress/config/zh/series.ts
Normal file
@ -0,0 +1,38 @@
|
||||
export const series = {
|
||||
"/mapstruct": [
|
||||
{
|
||||
text: '中文文档',
|
||||
children: [
|
||||
{ text: 'v1.5.5-Final', link: '/mapstruct/1-5-5-Final' }
|
||||
]
|
||||
}
|
||||
],
|
||||
"/": [
|
||||
{
|
||||
text: '介绍',
|
||||
children: [
|
||||
{ text: '介绍', link: '/introduction/about' },
|
||||
{ text: '快速开始', link: '/introduction/quick-start' },
|
||||
{ text: '安装', link: '/introduction/install' },
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '指南',
|
||||
children: [
|
||||
{ text: '两个类之间的转换', link: '/guide/class-convert' },
|
||||
{ text: 'Map 转对象', link: '/guide/map-to-class' },
|
||||
{ text: '枚举转换', link: '/guide/enum-convert' },
|
||||
{ text: '一个类与多个类之间转换', link: '/guide/multiple-class-convert' },
|
||||
{ text: '类转换API', link: '/guide/converter-api' },
|
||||
{ text: '配置项', link: '/guide/configuration' },
|
||||
{ text: '常见问题', link: '/guide/faq' },
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '更新日志',
|
||||
children: [
|
||||
{ text: '更新日志', link: '/release/log' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
export * from "./zh.js";
|
||||
@ -1,9 +0,0 @@
|
||||
import { navbar } from "vuepress-theme-hope";
|
||||
|
||||
export const zhNavbar = navbar([
|
||||
"/",
|
||||
{ text: "指南", icon: "api", link: "/guide/class-convert" },
|
||||
{ text: "更新日志", icon: "blog", link: "/release/log" },
|
||||
{ text: "MapStruct中文文档", icon: 'read', link: "/mapstruct/1-5-5-Final"}
|
||||
]);
|
||||
|
||||
|
Before Width: | Height: | Size: 229 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
39
docs/.vuepress/public/bg.svg
Normal file
@ -0,0 +1,39 @@
|
||||
<svg
|
||||
version="1.1"
|
||||
baseProfile="full"
|
||||
width="100%" height="100%"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1400 800"
|
||||
>
|
||||
|
||||
<rect x="1300" y="400" rx="40" ry="40" width="300" height="300" stroke="#4954e6" fill="#4954e6">
|
||||
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="35s" type="rotate" from="0 1450 550" to="360 1450 550" repeatCount="indefinite" />
|
||||
</rect>
|
||||
|
||||
<path d="M 100 350 A 150 150 0 1 1 400 350 Q400 370 380 370 L 250 370 L 120 370 Q100 370 100 350" stroke="rgb(253, 214, 99)" fill="rgb(253, 214, 99)">
|
||||
<animateMotion path="M 800 -200 L 800 -300 L 800 -200" dur="20s" begin="0s" repeatCount="indefinite" />
|
||||
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="30s" type="rotate" values="0 210 530 ; -30 210 530 ; 0 210 530" keyTimes="0 ; 0.5 ; 1" repeatCount="indefinite" />
|
||||
</path>
|
||||
|
||||
<circle cx="200" cy="150" r="20" stroke="#4954e6" fill="#4954e6">
|
||||
<animateMotion path="M 0 0 L 40 20 Z" dur="5s" repeatCount="indefinite" />
|
||||
</circle>
|
||||
|
||||
<!-- 三角形 -->
|
||||
<path d="M 165 580 L 270 580 Q275 578 270 570 L 223 483 Q220 480 217 483 L 165 570 Q160 578 165 580" stroke="rgb(238, 103, 92)" fill="rgb(238, 103, 92)">
|
||||
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="35s" type="rotate" from="0 210 530" to="360 210 530" repeatCount="indefinite" />
|
||||
</path>
|
||||
|
||||
<circle cx="1200" cy="600" r="30" stroke="rgb(241, 243, 244)" fill="rgb(241, 243, 244)">
|
||||
<animateMotion path="M 0 0 L -20 40 Z" dur="9s" repeatCount="indefinite" />
|
||||
</circle>
|
||||
|
||||
<path d="M 100 350 A 40 40 0 1 1 180 350 L 180 430 A 40 40 0 1 1 100 430 Z" stroke="rgb(241, 243, 244)" fill="rgb(241, 243, 244)">
|
||||
<animateMotion path="M 140 390 L 180 360 L 140 390" dur="20s" begin="0s" repeatCount="indefinite" />
|
||||
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="30s" type="rotate" values="0 140 390; -60 140 390; 0 140 390" keyTimes="0 ; 0.5 ; 1" repeatCount="indefinite" />
|
||||
</path>
|
||||
|
||||
<rect x="400" y="600" rx="40" ry="40" width="100" height="100" stroke="rgb(129, 201, 149)" fill="rgb(129, 201, 149)">
|
||||
<animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="35s" type="rotate" from="-30 550 750" to="330 550 750" repeatCount="indefinite" />
|
||||
</rect>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
BIN
docs/.vuepress/public/head.png
Normal file
|
After Width: | Height: | Size: 159 KiB |
@ -1 +0,0 @@
|
||||
export * from "./zh.js";
|
||||
@ -1,19 +0,0 @@
|
||||
import {sidebar} from "vuepress-theme-hope";
|
||||
|
||||
export const zhSidebar = sidebar({
|
||||
"/mapstruct/": 'structure',
|
||||
"/release": 'structure',
|
||||
"/": [
|
||||
{
|
||||
text: '介绍',
|
||||
prefix: 'introduction/',
|
||||
link: 'introduction/',
|
||||
children: 'structure'
|
||||
},
|
||||
{
|
||||
text: "指南",
|
||||
prefix: "guide/",
|
||||
children: "structure",
|
||||
}
|
||||
],
|
||||
});
|
||||
@ -1,3 +0,0 @@
|
||||
// you can change config here
|
||||
$colors: #c0392b, #d35400, #f39c12, #27ae60, #16a085, #2980b9, #8e44ad, #2c3e50,
|
||||
#7f8c8d !default;
|
||||
0
docs/.vuepress/styles/index.css
Normal file
@ -1,8 +0,0 @@
|
||||
// place your custom styles here
|
||||
@media (min-width: 1440px) {
|
||||
.feature-item {
|
||||
flex-basis: calc(33% - 3rem);
|
||||
padding-top: 1.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
}
|
||||
@ -1,2 +0,0 @@
|
||||
// you can change colors here
|
||||
$theme-color: #096dd9;
|
||||
@ -1,100 +0,0 @@
|
||||
import { hopeTheme } from "vuepress-theme-hope";
|
||||
import { zhNavbar } from "./navbar";
|
||||
import { zhSidebar } from "./sidebar";
|
||||
|
||||
export default hopeTheme({
|
||||
hostname: "https://mapstruct.plus",
|
||||
// 是否显示打印按钮
|
||||
print: false,
|
||||
|
||||
author: {
|
||||
name: "linpeilie",
|
||||
url: "https://github.com/linpeilie",
|
||||
},
|
||||
|
||||
iconAssets: "iconfont",
|
||||
|
||||
logo: "/logo.svg",
|
||||
|
||||
footer: "备案号:<a href=\"https://beian.miit.gov.cn\">苏ICP备2023020373号-1</a>",
|
||||
|
||||
repo: "linpeilie/mapstruct-plus",
|
||||
docsDir: 'docs',
|
||||
docsBranch: 'main',
|
||||
|
||||
locales: {
|
||||
"/": {
|
||||
// navbar
|
||||
navbar: zhNavbar,
|
||||
|
||||
// sidebar
|
||||
sidebar: zhSidebar,
|
||||
|
||||
// footer: "默认页脚",
|
||||
|
||||
displayFooter: true,
|
||||
|
||||
// page meta
|
||||
metaLocales: {
|
||||
editLink: "在 GitHub 上编辑此页",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
plugins: {
|
||||
comment: {
|
||||
provider: 'Giscus',
|
||||
repo: 'linpeilie/mapstruct-plus',
|
||||
repoId: 'R_kgDOJA3-jg',
|
||||
category: 'Announcements',
|
||||
categoryId: 'DIC_kwDOJA3-js4CU8EO'
|
||||
},
|
||||
copyCode: {
|
||||
showInMobile: false
|
||||
},
|
||||
// all features are enabled for demo, only preserve features you need here
|
||||
mdEnhance: {
|
||||
align: true,
|
||||
attrs: true,
|
||||
chart: true,
|
||||
codetabs: true,
|
||||
container: true,
|
||||
demo: true,
|
||||
echarts: false,
|
||||
figure: true,
|
||||
flowchart: false,
|
||||
gfm: true,
|
||||
imgLazyload: true,
|
||||
imgMark: true,
|
||||
imgSize: true,
|
||||
include: true,
|
||||
katex: true,
|
||||
mark: true,
|
||||
mermaid: true,
|
||||
playground: {
|
||||
presets: ["ts", "vue"],
|
||||
},
|
||||
presentation: {
|
||||
plugins: ["highlight", "math", "search", "notes", "zoom"],
|
||||
},
|
||||
stylize: [
|
||||
{
|
||||
matcher: "Recommended",
|
||||
replacer: ({ tag }) => {
|
||||
if (tag === "em")
|
||||
return {
|
||||
tag: "Badge",
|
||||
attrs: { type: "tip" },
|
||||
content: "Recommended",
|
||||
};
|
||||
},
|
||||
},
|
||||
],
|
||||
sub: true,
|
||||
sup: true,
|
||||
tabs: true,
|
||||
vPre: true,
|
||||
vuePlayground: true,
|
||||
}
|
||||
},
|
||||
});
|
||||
@ -1,17 +1,23 @@
|
||||
---
|
||||
home: true
|
||||
icon: home
|
||||
title: 主页
|
||||
description: MapStructPlus MapStruct Home 首页
|
||||
heroText: MapstructPlus
|
||||
tagline: 可能是最简单最强大的Java Bean转换工具
|
||||
actions:
|
||||
- text: 快速开始 💡
|
||||
link: /introduction/quick-start/
|
||||
type: primary
|
||||
- text: 常见问题
|
||||
link: /guide/faq
|
||||
|
||||
modules:
|
||||
- BannerBrand
|
||||
- Features
|
||||
- MdContent
|
||||
- Footer
|
||||
bannerBrand:
|
||||
bgImage: '/bg.svg'
|
||||
title: MapStructPlus
|
||||
description: 可能是最简单最强大的Java Bean转换工具
|
||||
tagline: Mapstruct Plus 是 Mapstruct 的增强工具,在 Mapstruct 的基础上,实现了自动生成 Mapper 接口的功能,并强化了部分功能,使 Java 类型转换更加便捷、优雅。
|
||||
buttons:
|
||||
- { text: 快速开始, link: '/introduction/quick-start' }
|
||||
- { text: '常见问题', link: '/guide/faq', type: 'plain' }
|
||||
socialLinks:
|
||||
- { icon: 'LogoGithub', link: 'https://github.com/vuepress-reco/vuepress-theme-reco' }
|
||||
isShowTitleInHome: true
|
||||
actionText: About
|
||||
actionLink: /views/other/about
|
||||
features:
|
||||
- title: 快速
|
||||
icon: launch
|
||||
@ -36,8 +42,8 @@ features:
|
||||
- title: Map转对象
|
||||
icon: type
|
||||
details: 更强大的Map转对象功能
|
||||
|
||||
copyright: false
|
||||
footer:
|
||||
startYear: 2023
|
||||
---
|
||||
|
||||
## 国内站点
|
||||
@ -56,18 +62,23 @@ copyright: false
|
||||
<dependency>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
|
||||
<version>1.3.4</version>
|
||||
<version>1.3.5</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
- gradle
|
||||
|
||||
```groovy
|
||||
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.3.4'
|
||||
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.3.5'
|
||||
```
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 1.3.5
|
||||
|
||||
- AutoMapping、ReverseAutoMapping 支持配置在方法上面;
|
||||
- AutoMapping、ReverseAutoMapping 支持 defaultExpression 和 conditionExpression 属性
|
||||
|
||||
### 1.3.4
|
||||
|
||||
……什么都没更新,腾讯云maven源同步的jar有问题,只能重新发个新包
|
||||
|
||||
102
docs/en/README.md
Normal file
@ -0,0 +1,102 @@
|
||||
---
|
||||
home: true
|
||||
modules:
|
||||
- BannerBrand
|
||||
- Features
|
||||
- MdContent
|
||||
- Footer
|
||||
bannerBrand:
|
||||
bgImage: '/bg.svg'
|
||||
title: MapStructPlus
|
||||
description: Probably the simplest and most powerful Java Bean transformation tool
|
||||
tagline: MapStructPlus is an enhancement tool of MapStruct. On the basis of MapStruct, it realizes the function of automatically generating Mapper interface, and strengthens some functions, making Java type conversion more convenient and elegant.
|
||||
buttons:
|
||||
- { text: Quick Start, link: '/en/introduction/quick-start' }
|
||||
- { text: 'FAQ', link: '/en/guide/faq', type: 'plain' }
|
||||
socialLinks:
|
||||
- { icon: 'LogoGithub', link: 'https://github.com/vuepress-reco/vuepress-theme-reco' }
|
||||
isShowTitleInHome: true
|
||||
actionText: About
|
||||
actionLink: /views/other/about
|
||||
features:
|
||||
- title: Quick
|
||||
icon: launch
|
||||
details: The conversion between Java classes requires only additional annotation, reducing the tedious and error-prone development task
|
||||
|
||||
- title: Efficiency
|
||||
icon: light
|
||||
details: Based on the annotation processors, all of the generation is done at compile time
|
||||
|
||||
- title: Conversion
|
||||
icon: change
|
||||
details: Property conversions are based on getter/setter methods in the class
|
||||
|
||||
- title: Compatibility
|
||||
icon: any
|
||||
details: Support JDK8~17、SpringBoot2~3
|
||||
|
||||
- title: Multi-class conversion
|
||||
icon: structure
|
||||
details: Support for a single class to configure multiple type conversions
|
||||
|
||||
- title: Conversion between Map and Object
|
||||
icon: type
|
||||
details: More powerful map-to-object functionality
|
||||
fotter:
|
||||
startYear: 2023
|
||||
---
|
||||
|
||||
## Other Open Source Project
|
||||
|
||||
- **EasyRelation**:[GitHub](https://github.com/linpeilie/easy-relation) | [Gitee](https://gitee.com/easii/easy-relation) | [Document](https://easy-relation.easii.cn)
|
||||
|
||||
## Latest Version
|
||||
|
||||
- maven
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
|
||||
<version>1.3.5</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
- gradle
|
||||
|
||||
```groovy
|
||||
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.3.5'
|
||||
```
|
||||
|
||||
## Change Log
|
||||
|
||||
### 1.3.5
|
||||
|
||||
- `@AutoMapping`、`@ReversedAutoMapping` support is configured on top of methods.
|
||||
- `@AutoMapping`、`@ReverseAutoMapping` support the defaultExpression and conditionExpression properties
|
||||
|
||||
### 1.3.3
|
||||
|
||||
- fixbug: fixed compilation error on win jdk8
|
||||
|
||||
### 1.3.2
|
||||
|
||||
- Support Immutable object, you can use the `@Immutable` annotation type under any package as an immutable class
|
||||
- fully adapt the IDEA part of the compilation problem, use more smooth silky
|
||||
|
||||
……
|
||||
|
||||
## Code Warehouse
|
||||
|
||||
- [Github](https://github.com/linpeilie/mapstruct-plus)
|
||||
- [Gitee](https://gitee.com/linpeilie/mapstruct-plus)
|
||||
|
||||
## Participate and contribute
|
||||
|
||||
- Contribution Code: You are welcome to submit an issue or pull requests
|
||||
- Maintain Documents: Docs directory under the project directory, welcome to participate in the translation and revision
|
||||
|
||||
## Links
|
||||
|
||||
- [RuoYi-Vue-Plus](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages)
|
||||
- [RuoYi-Cloud-Plus](https://gitee.com/JavaLionLi/RuoYi-Cloud-Plus/wikis/pages)
|
||||
528
docs/en/guide/class-convert.md
Normal file
@ -0,0 +1,528 @@
|
||||
---
|
||||
title: Conversion between two classes
|
||||
order: 1
|
||||
category:
|
||||
- Guide
|
||||
description: MapStructPlus 两个类之间的转换及配置 class convert Conversion between two classes
|
||||
---
|
||||
|
||||
## Simple Conversion
|
||||
|
||||
**To convert between two classes, simply add the annotation `@AutoMapper` to one of the classes, configure the `target` attribute, and specify the target class.**
|
||||
|
||||
eg:
|
||||
|
||||
```java
|
||||
@AutoMapper(target = CarDto.class)
|
||||
public class Car {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
This example shows that an interface `CarToCarDtoMapper` and implementation class `CarToCarDtoMapperImpl` will be generated for `Car` to `CarDto`.
|
||||
In the generated conversion code, all readable attributes of the source type(`Car`) are copied to the corresponding attribute of the target attribute type(`CarDto`).
|
||||
|
||||
When an attribute has the same name as its target entity counterpart, it is implicitly mapped.
|
||||
|
||||
In addition, MapStructPlus generates the `CarDto` to `Car` interface `CarDtoToCarMapper` and the implementation class `CarDtoToCarMapperImpl` according to the current default rules.
|
||||
If you do not want to generate the transformation logic, you can configure it by using the `reverseConvertGenerate` property of the annotation.
|
||||
|
||||
## The properties of a custom object are automatically converted
|
||||
|
||||
When property by custom class exists in the class to be converted, the conversion method for that type is automatically found.
|
||||
|
||||
For example, there are two sets of object module: `Car` and `SeatConfiguration`, `Car` depends on `SeatConfiguration`
|
||||
|
||||
The corresponding objects are as follows:
|
||||
|
||||
- car
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Car
|
||||
```java
|
||||
@AutoMapper(target = CarDto.class)
|
||||
@Data
|
||||
public class Car {
|
||||
private SeatConfiguration seatConfiguration;
|
||||
}
|
||||
```
|
||||
:::
|
||||
::: code-group-item CarDto
|
||||
```java
|
||||
@Data
|
||||
public class CarDto {
|
||||
private SeatConfigurationDto seatConfiguration;
|
||||
}
|
||||
```
|
||||
:::
|
||||
::::
|
||||
|
||||
- seat configuration
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item SeatConfiguration
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = SeatConfigurationDto.class)
|
||||
public class SeatConfiguration {
|
||||
// fields
|
||||
}
|
||||
```
|
||||
:::
|
||||
::: code-group-item SeatConfigurationDto
|
||||
```java
|
||||
@Data
|
||||
public class SeatConfigurationDto {
|
||||
// fields
|
||||
}
|
||||
```
|
||||
:::
|
||||
::::
|
||||
|
||||
In the above example, the `CarToCarDtoMapper` and `SeatConfigurationToSeatConfigurationDtoMapper` conversion interfaces are generated,
|
||||
and `SeatConfigurationToSeatConfigurationDtoMapper` is automatically used to convert the seat properties in the `Car` conversion.
|
||||
|
||||
## Introduces custom type converter
|
||||
|
||||
When different types of properties want to be converted according to custom rules, there are two ways:
|
||||
|
||||
1. Configuration through the `expression` configured in `@AutoMapping`
|
||||
2. Customize a type converter, introduced through the 'uses' attribute of `@AutoMapping`
|
||||
|
||||
For mode one, refer to the section[expresions](#expresions) below.
|
||||
|
||||
This is based on mode two, where the implementation converts a `String` type attribute, separated by commas, to a `List<String>` type attribute:
|
||||
|
||||
First, define a type converter --- `StringToListString`:
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class StringToListString {
|
||||
public List<String> stringToListString(String str) {
|
||||
return StrUtil.split(str);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
::: warning
|
||||
- Type converter provides type conversion methods thas can be defined as `static` or `nonstatic`.
|
||||
- If you are using the framework based on the `SpringBoot` approach, the type converter need to be defined as a Spring Bean.
|
||||
:::
|
||||
|
||||
Next, use is:
|
||||
|
||||
```java
|
||||
@AutoMapper(target = User.class, uses = StringToListStringConverter.class)
|
||||
public class UserDto {
|
||||
|
||||
private String username;
|
||||
private int age;
|
||||
private boolean young;
|
||||
@AutoMapping(target = "educationList")
|
||||
private String educations;
|
||||
// ......
|
||||
}
|
||||
```
|
||||
|
||||
Test:
|
||||
|
||||
```java
|
||||
@SpringBootTest
|
||||
public class QuickStartTest {
|
||||
|
||||
@Autowired
|
||||
private Converter converter;
|
||||
|
||||
@Test
|
||||
public void ueseTest() {
|
||||
UserDto userDto = new UserDto();
|
||||
userDto.setEducations("1,2,3");
|
||||
|
||||
final User user = converter.convert(userDto, User.class);
|
||||
System.out.println(user.getEducationList()); // [1, 2, 3]
|
||||
|
||||
assert user.getEducationList().size() == 3;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Custom Property conversions
|
||||
|
||||
When there are inconsistent scenarios for attributes in the two classes, such as name, type, and so on,
|
||||
you can used to configure the mapping rules by add `@AutoMapping` to the attributes.
|
||||
|
||||
### Different attribute name mappings
|
||||
|
||||
In the `@AutoMapping` annotation, the `target` attribute is provided to configure the mapping between the current attribute and the `target` attribute in the target class.
|
||||
|
||||
For example, when `Car` is converted to `CarDto`, the `seatConfiguration` attribute corresponds to the `seat` attribute:
|
||||
|
||||
```java
|
||||
@AutoMapper(target = CarDto.class)
|
||||
@Data
|
||||
public class Car {
|
||||
@AutoMapping(target = "seat")
|
||||
private SeatConfiguration seatConfiguration;
|
||||
}
|
||||
```
|
||||
|
||||
The `@AutoMapping` annotation also provides the `source` attribute, which by default takes the name of the current property
|
||||
and can be configured to fit a scenario there a property of the current class, its internal property, to a property field in the target,
|
||||
you can configure it with the current property.
|
||||
|
||||
eg:
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Goods
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = GoodsVo.class, reverseConvertGenerate = false)
|
||||
public class Goods {
|
||||
|
||||
@AutoMapping(source = "sku.price", target = "price")
|
||||
private Sku sku;
|
||||
|
||||
}
|
||||
```
|
||||
:::
|
||||
::: code-group-item GoodsVo
|
||||
```java
|
||||
@Data
|
||||
public class GoodsVo {
|
||||
|
||||
private Integer price;
|
||||
|
||||
}
|
||||
```
|
||||
:::
|
||||
::::
|
||||
|
||||
### Specifies the time format
|
||||
|
||||
When the time type(for example `Date`、`LocalDateTime`、`LocalDate`...) needs to be converted with `String` by specifying the time format,
|
||||
you can configure it with `dateFormat` in `@AutoMapping`
|
||||
|
||||
eg:
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Order
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = OrderEntity.class)
|
||||
public class Order {
|
||||
|
||||
@AutoMapping(dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime orderTime;
|
||||
|
||||
@AutoMapping(dateFormat = "yyyy_MM_dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
@AutoMapping(target = "orderDate", dateFormat = "yyyy-MM-dd")
|
||||
private String date;
|
||||
|
||||
}
|
||||
```
|
||||
:::
|
||||
::: code-group-item OrderEntity
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = Order.class)
|
||||
public class OrderEntity {
|
||||
|
||||
@AutoMapping(dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private String orderTime;
|
||||
|
||||
@AutoMapping(dateFormat = "yyyy_MM_dd HH:mm:ss")
|
||||
private String createTime;
|
||||
|
||||
@AutoMapping(target = "date", dateFormat = "yyyy-MM-dd")
|
||||
private LocalDate orderDate;
|
||||
|
||||
}
|
||||
```
|
||||
:::
|
||||
::::
|
||||
|
||||
### Specifies a numeric format
|
||||
|
||||
When the conversion between a numeric type(for example `int`/`Integer` and the wrapper class、`BigDecimal`) and `String` requires a numeric format,
|
||||
it can be configured with `numberFormat` in `@AutoMapping`
|
||||
|
||||
> This format need to be supported by `java.text.DecimalFormat`
|
||||
|
||||
eg:
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Order
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = OrderEntity.class)
|
||||
public class Order {
|
||||
|
||||
@AutoMapping(numberFormat = "$0.00")
|
||||
private BigDecimal orderPrice;
|
||||
|
||||
@AutoMapping(numberFormat = "$0.00")
|
||||
private Integer goodsNum;
|
||||
|
||||
}
|
||||
```
|
||||
:::
|
||||
::: code-group-item OrderEntity
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = Order.class)
|
||||
public class OrderEntity {
|
||||
|
||||
@AutoMapping(numberFormat = "$0.00")
|
||||
private String orderPrice;
|
||||
|
||||
@AutoMapping(numberFormat = "$0.00")
|
||||
private String goodsNum;
|
||||
|
||||
}
|
||||
```
|
||||
:::
|
||||
::::
|
||||
|
||||
### Ignore the specifies property
|
||||
|
||||
When the transformation is performed, the transformation of the specified property
|
||||
needs to be ignored, which can be configured using the `ignore` of `@AutoMapping`
|
||||
|
||||
es:
|
||||
|
||||
```java
|
||||
@AutoMapper(target = CarDto.class)
|
||||
@Data
|
||||
public class Car {
|
||||
|
||||
@AutoMapping(target = "wheels", ignore = true)
|
||||
private Wheels wheels;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### default value
|
||||
|
||||
`defaultValue` in `@AutoMapping` can specify the default value to convert to the target class when the property value is null.
|
||||
|
||||
eg:
|
||||
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = DefaultVo.class)
|
||||
public class DefaultDto {
|
||||
|
||||
@AutoMapping(defaultValue = "18")
|
||||
private Integer i;
|
||||
|
||||
@AutoMapping(defaultValue = "1.32")
|
||||
private Double d;
|
||||
|
||||
@AutoMapping(defaultValue = "true")
|
||||
private Boolean b;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### expression
|
||||
|
||||
When you perform a property conversion, you can perform the conversion operation by specifying that a piece of Java code be executed, for example, to return after converting a property in a source object.
|
||||
|
||||
Note that at compile time, the expression is inserted directly into the transformation logic and its synatax is not validated.
|
||||
|
||||
For example, the `List<String>` attribute in the source object is concatenated into a string by ',':
|
||||
|
||||
```java
|
||||
@AutoMapper(target = UserDto.class)
|
||||
public class User {
|
||||
|
||||
@AutoMapping(target = "educations", expression = "java(java.lang.String.join(\",\", source.getEducationList()))")
|
||||
private List<String> educationList;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Automatically access the custom converter interface
|
||||
|
||||
::: info
|
||||
since `1.2.3`
|
||||
:::
|
||||
|
||||
When some type conversion logic is more complex, you can use define converter interface to achive,
|
||||
that is, using MapStruct native way.
|
||||
|
||||
When used this way, the default generated type conversion is automatically referenced if there is previously provided type conversion.
|
||||
|
||||
例如:
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Car
|
||||
```java
|
||||
@AutoMapper(target = CarDto.class)
|
||||
@Data
|
||||
public class Car {
|
||||
private Tyre tyre;
|
||||
}
|
||||
```
|
||||
:::
|
||||
::: code-group-item CarDto
|
||||
```java
|
||||
@Data
|
||||
public class CarDto {
|
||||
private TyreDTO tyre;
|
||||
}
|
||||
```
|
||||
:::
|
||||
::::
|
||||
|
||||
Converter interface between `Tyre` and `TyreDTO` is defined here.
|
||||
|
||||
```java
|
||||
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
|
||||
public interface TyreMapper {
|
||||
|
||||
TyreDTO tyreToTyreDTO(Tyre tyre);
|
||||
|
||||
Tyre tyreDtoToTyre(TyreDTO tyreDTO);
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
The generated implementation classes for the `Car` and `CarDto` converter interfaces are as follows:
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item CarToCarDtoMapperImpl
|
||||
```java
|
||||
@Generated(
|
||||
value = "org.mapstruct.ap.MappingProcessor",
|
||||
date = "2023-04-24T15:38:48+0800",
|
||||
comments = "version: 1.5.5.Final, compiler: javac, environment: Java 1.8.0_202 (Oracle Corporation)"
|
||||
)
|
||||
@Component
|
||||
public class CarToCarDtoMapperImpl implements CarToCarDtoMapper {
|
||||
|
||||
@Autowired
|
||||
private TyreMapper tyreMapper;
|
||||
|
||||
@Override
|
||||
public CarDto convert(Car source) {
|
||||
if ( source == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CarDto carDto = new CarDto();
|
||||
|
||||
carDto.setTyre( tyreMapper.tyreToTyreDTO( source.getTyre() ) );
|
||||
|
||||
return carDto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarDto convert(Car source, CarDto target) {
|
||||
if ( source == null ) {
|
||||
return target;
|
||||
}
|
||||
|
||||
target.setTyre( tyreMapper.tyreToTyreDTO( source.getTyre() ) );
|
||||
|
||||
return target;
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
::: code-group-item CarDtoToCarMapperImpl
|
||||
```java
|
||||
@Generated(
|
||||
value = "org.mapstruct.ap.MappingProcessor",
|
||||
date = "2023-04-24T15:38:49+0800",
|
||||
comments = "version: 1.5.5.Final, compiler: javac, environment: Java 1.8.0_202 (Oracle Corporation)"
|
||||
)
|
||||
@Component
|
||||
public class CarDtoToCarMapperImpl implements CarDtoToCarMapper {
|
||||
|
||||
@Autowired
|
||||
private TyreMapper tyreMapper;
|
||||
|
||||
@Override
|
||||
public Car convert(CarDto source) {
|
||||
if ( source == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Car car = new Car();
|
||||
|
||||
car.setTyre( tyreMapper.tyreDtoToTyre( source.getTyre() ) );
|
||||
|
||||
return car;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Car convert(CarDto source, Car target) {
|
||||
if ( source == null ) {
|
||||
return target;
|
||||
}
|
||||
|
||||
target.setTyre( tyreMapper.tyreDtoToTyre( source.getTyre() ) );
|
||||
|
||||
return target;
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
::::
|
||||
|
||||
## Configuration for reverse property mapping
|
||||
|
||||
::: info
|
||||
**In this article, all the mentioned source classes refer to classes annotated by `@AutoMapper`;
|
||||
the target classes refer to the type specified by the `target` attribute in `@AutoMapper`.**
|
||||
:::
|
||||
|
||||
As mentioned earlier, when you add the `@AutoMapper` annotation to a class,
|
||||
by default, generate not only the source-to-target converter interface, but also the target-to-source converter interface and implementation class,
|
||||
note here that the converter interface generated by default does not any custom configuration,
|
||||
even if the `@AutoMapping` annotation is configured in the source class.
|
||||
|
||||
There are two ways to implement a custom converter configuration from the target class to the source class:
|
||||
|
||||
1. Add the `@AutoMapper` annotation above the target class. This is the most recommended approach, when both sides add this annotation, the default converter interface for target-to-source is not generated, that is, it is generated according to custom rules.
|
||||
2. When the target class does not have access to the source class, or the project specification does not allow such annotations to be added to the target class, you can add the custom configuration entirelyto the source class. This is the **reverse attribute mapping configuration** described below.
|
||||
|
||||
The `@ReverseAutoMapping` annotation is provided in the framework to configure custom conversion rules from the target class to the source class.
|
||||
|
||||
::: warning
|
||||
Note here that to prevent configuration conflicts, once you add the `@ReverseAutoMapping` annotation,
|
||||
you can not add any custom conversion annotations to the target class.
|
||||
:::
|
||||
|
||||
**The meaning of the `@ReverseAutoMapping` annotation is that when the target class is converted to the source class,
|
||||
the custom rules need to be specified, where the attributes can be configured, consistent with the `@AutoMapping` annotation.**
|
||||
|
||||
There are two attributes to note here, `source` and `target`.
|
||||
|
||||
**Here the `source` refers to the attributes in the target class, and the `target` refers to the attributes in the source class.**
|
||||
|
||||
One might wonder why the configuration here seems to be reversed? If not, you can skip it.
|
||||
|
||||
When the framework is designed, all the attribute transformation configurations are based on the type to be converted,
|
||||
with the ultimate effect of converting the class to the target class.
|
||||
So The `source` here should also be an attribute in the source class.
|
||||
|
||||
|
||||
If you sill don't understand it, you can assume that the annotation is the `@AutoMapping` annotation that should have been applied to the target class. Just copy it to the current class and change the annotation name.
|
||||
|
||||
## Immutable type
|
||||
|
||||
> since 1.3.2
|
||||
|
||||
When source type is immutable, the `T convert(S source, @MappingTarget T target)` method generated by the previous default rule may have problems.
|
||||
|
||||
So, you can use the `Immutable` annotation under any package to identify a class as an Immutable type, When an immutable type is used, the `@MappingTarget` makes no sense, and the above method eventually generates the following:
|
||||
|
||||
```java
|
||||
public T convert(S source, @MappingTarget T target) {
|
||||
return target;
|
||||
}
|
||||
```
|
||||
166
docs/en/guide/configuration.md
Normal file
@ -0,0 +1,166 @@
|
||||
---
|
||||
title: configuration
|
||||
order: 6
|
||||
category:
|
||||
- Guide
|
||||
description: MapStructPlus MapStructPlus配置项 configuration
|
||||
---
|
||||
|
||||
MapStructPlus provides multiple configuration items to specify some behavior when the conversion interface is generated.
|
||||
|
||||
## How to use it
|
||||
|
||||
In the module that needs to be configured, create a new configuration class an annotate it with `@MapperConfig` annotation.
|
||||
|
||||
In a module, there can noly be one class with this annotation.
|
||||
|
||||
Also, note that **the configuration classes must be placed in the module to be effective**.
|
||||
|
||||
eg:
|
||||
|
||||
```java
|
||||
@MapperConfig(adapterClassName = "DemoConvertMapperAdapter",
|
||||
adapterPackage = "io.github.linpeilie.adapter",
|
||||
mapAdapterClassName = "DemoMapConvertMapperAdapter")
|
||||
public class MapStructPlusConfiguration {
|
||||
}
|
||||
```
|
||||
|
||||
In addition, the configuration property supports **adding compilation parameters** to the compiler in the form of `-Akey=value`.
|
||||
|
||||
For example, when using Maven, you can use the `compilerArgs` property in the `maven-compiler-plugin` plugin configuration to configure delivery, for example:
|
||||
|
||||
**And configuration in this way takes precedence**, that is, when the mode and configuration class exist together, the property configured in this way takes precedence. This feature is supported from `1.3.0`.
|
||||
|
||||
eg:
|
||||
|
||||
```xml
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-processor</artifactId>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok-mapstruct-binding</artifactId>
|
||||
<version>0.2.0</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs>
|
||||
<arg>-Amapstruct.plus.adapterClassName=DemoConvertMapperAdapter</arg>
|
||||
<arg>-Amapstruct.plus.adapterPackage=io.github.linpeilie.adapter</arg>
|
||||
<arg>-Amapstruct.plus.mapAdapterClassName=DemoMapConvertMapperAdapter</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
## Configuration Item
|
||||
|
||||
### mapperPackage
|
||||
|
||||
- **Description**:The package name of the generated Mapper transformation interfaces
|
||||
- **Type**:`String`
|
||||
- **Default**:The default is under the same package as the class to be converted.
|
||||
- **Compile Parameter**:`-Amapstruct.plus.mapperPackage`
|
||||
|
||||
### unmappedSourcePolicy
|
||||
|
||||
- **Description**:Policy when there is no corresponding attribute in the source class
|
||||
- **Type**:`ReportingPolicy`
|
||||
- **Optional**:
|
||||
- `IGNORE`:ignore
|
||||
- `WARN`:print warning log
|
||||
- `ERROR`:throw exception
|
||||
- **Default**:`IGNORE`
|
||||
- **Compile Parameter**:`-Amapstruct.plus.unmappedSourcePolicy`
|
||||
|
||||
### unmappedTargetPolicy
|
||||
|
||||
- **Description**:Policy when there is no corresponding attribute in the target class
|
||||
- **Type**:`ReportingPolicy`
|
||||
- **Optional**:
|
||||
- `IGNORE`:ignore
|
||||
- `WARN`:print warning log
|
||||
- `ERROR`:throw exception
|
||||
- **Default**:`IGNORE`
|
||||
- **Compile Parameter**:`-Amapstruct.plus.unmappedTargetPolicy`
|
||||
|
||||
### nullValueMappingStrategy
|
||||
|
||||
- **Description**:Null object handing policy
|
||||
- **Type**:`NullValueMappingStrategy`
|
||||
- **Optional**:
|
||||
- `RETURN_NULL`:return null
|
||||
- `RETURN_DEFAULT`:return default value
|
||||
- **Default**:`RETURN_NULL`
|
||||
- **Compile Parameter**:`-Amapstruct.plus.nullValueMappingStrategy`
|
||||
|
||||
### nullValuePropertyMappingStrategy
|
||||
|
||||
- **Description**:Policy to deal with when the property value is `null`
|
||||
- **Type**:`NullValuePropertyMappingStrategy`
|
||||
- **Optional**:
|
||||
- `SET_TO_NULL`:setting is null
|
||||
- `SET_TO_DEFAULT`:setting is default value
|
||||
- `IGNORE`:ignore
|
||||
- **Default**:`SET_TO_NULL`
|
||||
- **Compile Parameter**:`-Amapstruct.plus.nullValuePropertyMappingStrategy`
|
||||
|
||||
### builder
|
||||
|
||||
- **Description**:Constructor mode configuration, MapStruct loses the parent class property when used with Lombok's builder, so the default constructor mode is turned off.
|
||||
- **Type**:`Builder`
|
||||
- **Optional**:
|
||||
- `buildMethod`:The constructor creates the constructor when the type is to be build
|
||||
- `disableBuilder`:Open/Close the constructor, and if closed, use only regular getters/setters
|
||||
- **Default**:
|
||||
- `buildMethod`:`build`
|
||||
- `disableBuilder`:`true`
|
||||
- **Compile Parameter**:
|
||||
- `-Amapstruct.plus.builder.buildMethod`
|
||||
- `-Amapstruct.plus.builder.disableBuilder`
|
||||
|
||||
### adapterPackage
|
||||
|
||||
> since `1.2.3`
|
||||
|
||||
- **Description**:The package name of ConvertAdapterClass and MapConvertMapperAdapter
|
||||
- **Type**:`String`
|
||||
- **Default**:io.github.linpeilie
|
||||
- **Compile Parameter**:`-Amapstruct.plus.adapterPackage`
|
||||
|
||||
### adapterClassName
|
||||
|
||||
> since `1.2.3`
|
||||
|
||||
- **Description**:the class name of ConvertAdapterClass
|
||||
- **Type**:`String`
|
||||
- **Default**:ConvertMapperAdapter
|
||||
- **Compile Parameter**:`-Amapstruct.plus.adapterClassName`
|
||||
|
||||
### mapAdapterClassName
|
||||
|
||||
> since `1.2.3`
|
||||
|
||||
- **Description**:the class name of MapConvertMapperAdapter
|
||||
- **Type**:`String`
|
||||
- **Default**:MapConvertMapperAdapter
|
||||
- **Compile Parameter**:`-Amapstruct.plus.mapAdapterClassName`
|
||||
31
docs/en/guide/converter-api.md
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
title: API
|
||||
order: 5
|
||||
category:
|
||||
- Guide
|
||||
description: Mapstruct MapStructPlus Converter Converter接口API converter api
|
||||
---
|
||||
|
||||
## Converter
|
||||
|
||||
The previous sections, which were all about configuring transformation logic on entity classes, were mainly applied at the compile stage. In practice, the framework provides the `Converter` class to perform the concreate transformation logic.
|
||||
|
||||
This class provides the following methods for type conversion:
|
||||
|
||||
- **`<S, T> T convert(S source, Class<T> targetType)`**
|
||||
|
||||
Passes in the object and the target type to be converted, and finally returns an intance object of the target type.
|
||||
|
||||
- **`<S, T> T convert(S source, T target)`**
|
||||
|
||||
Passes in the `source` object and `target` object, finally returns target object, and eventually converting the properties in the `source` object to the `target` object.
|
||||
|
||||
This method differs from the above in that it returns an incoming `taring` object, whereas the above method return a new object.
|
||||
|
||||
- **`<S, T> List<T> convert(List<S> source, Class<T> targetType)`**
|
||||
|
||||
This method converts a collection of source types(`source`) to a collection of target types(`targetType`)
|
||||
|
||||
- **`<T> T convert(Map<String, Object> map, Class<T> target)`**
|
||||
|
||||
This method converts a `Map<String, Object>` to an instance object of the target type.
|
||||
77
docs/en/guide/enum-convert.md
Normal file
@ -0,0 +1,77 @@
|
||||
---
|
||||
title: 枚举转换
|
||||
order: 3
|
||||
category:
|
||||
- 指南
|
||||
description: MapStructPlus Map转为对象 map convert to class
|
||||
---
|
||||
|
||||
> The current feature is supported from 1.2.2
|
||||
|
||||
当需要进行枚举转换时(例如枚举转换为编码值,或者又编码转换为枚举),可以在目标枚举添加 `@AutoEnumMapper` 注解,
|
||||
增加该注解后,在任意类型中需要转换该枚举时都可以自动转换。
|
||||
|
||||
When an enum conversion is required(such as an enum converted to an encoded value, or from an encoding to an enum), you can add the `@AutoEnumMapper` annotation to the target enum, with this annotation added, the enum can be converted automatically whenever it is needed in any type.
|
||||
|
||||
Note to use this annotation: **The current enum must have a field that is guaranteed to be unique**, and then using the current annotation, add the field name to the `value` attribute provided by the annotation.
|
||||
|
||||
**There are also enum and classes that use enum, whick must be in the same module.**
|
||||
|
||||
eg:
|
||||
|
||||
- `GoodsStateEnum`
|
||||
|
||||
```java
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@AutoEnumMapper("state")
|
||||
public enum GoodsStateEnum {
|
||||
ENABLED(1, "Enabled"),
|
||||
DISABLED(0, "Disabled");
|
||||
|
||||
private final Integer state;
|
||||
private final String desc;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Add the annotation `@AutoEnumMapper` in the current enum and specify that the only field is `state`.
|
||||
|
||||
- `Goods`
|
||||
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = GoodsVo.class, reverseConvertGenerate = false)
|
||||
public class Goods {
|
||||
|
||||
private GoodsStateEnum state;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
- `GoodsVo`
|
||||
|
||||
```java
|
||||
@Data
|
||||
public class GoodsVo {
|
||||
|
||||
private Integer state;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
- Test
|
||||
|
||||
```java
|
||||
@Test
|
||||
public void enumMapTest() {
|
||||
final GoodsVo goodsVo = converter.convert(goods, GoodsVo.class);
|
||||
System.out.println(goodsVo);
|
||||
Assert.equals(goodsVo.getState(), goods.getState().getState());
|
||||
|
||||
final Goods goods2 = converter.convert(goodsVo, Goods.class);
|
||||
System.out.println(goods2);
|
||||
Assert.equals(goods2.getState(), GoodsStateEnum.ENABLED);
|
||||
}
|
||||
```
|
||||
|
||||
153
docs/en/guide/faq.md
Normal file
@ -0,0 +1,153 @@
|
||||
---
|
||||
title: FAQ
|
||||
order: 7
|
||||
category:
|
||||
- Guide
|
||||
description: MapStructPlus MapStructPlus常见问题 faq
|
||||
---
|
||||
|
||||
#### Where to view the generated mapper interfaces and implemation.
|
||||
|
||||
In the compiled `target/generated-sources` directory, If do not have this directory, need to configure the IDEA Show Excluded Files.
|
||||
|
||||
#### "cannot find converter from xxx to xxx"
|
||||
|
||||
1. It is recommended that you re-examine your dependencies and configuration against the [Quick Start](/en/introduction/quick-start.html) section.
|
||||
2. If Lombok is used in your project, follow the [Guide - FAQ#Integration with Lombok](/en/guide/faq.html) to configure it.
|
||||
3. Reload all maven projects.
|
||||
4. mvn clean compile
|
||||
5. Under the `/target/generated-sources` directory, see if the conversion interface generated, if not, contact the author.
|
||||
6. If it has already been generated, make sure that SpringBoot scans to the package where the generated interface is located!
|
||||
7. Check for dependencies on `spring-boot-devtools`, which modifies the class's ClassLoader! This causes the matching class to fail, and not only the framework, but the tool can also cause other puzzling problems! Remove the dependency.
|
||||
|
||||
#### Diretory rules for the generated converter interfaces and implementation class
|
||||
|
||||
By default, generated under the same package name as the source class, you can specify diirectory through [Configuration](/en/guide/configuration.html)
|
||||
|
||||
> Note that if it is an external dependency package, it will also be generated under the same package as the external dependency class, causing Spring not to scan it, in which case it is recommended to specify a specific directory.
|
||||
|
||||
#### "Couldn't retrieve @Mapper annotation" Error
|
||||
|
||||
This exception is due to MapStruct dependency conflicts, and since MapStructPlus already relies on MapStruct, there is no need to add MapStruct dependency when using it.
|
||||
|
||||
It is also recommended that other dependencies, such as the springfox-swagger2 dependency on MapStruct, be eliminated.
|
||||
|
||||
Once you've eliminated the dependencies, re-execute clean compile
|
||||
|
||||
#### "NoSuchMethodError: …… io.github.linpeilie.ConvertMapperAdapter.xxxMethod" Error
|
||||
|
||||
When all the converter class are generated correctly, an exception of `NoSuchMethodError` is thrownat execution time, but in the generated code, the method exists in the `ConverterMapperAdapter` class.
|
||||
|
||||
When this exception occurs, it is because there are multiple modules, and there are dependencies between the modules, and in each module, there are classes that need to be converterd.
|
||||
So at build time, `io.github.linpeilie.ConvertMapperAdapter` is generated in each module, because the ClassLoader only loads one class with the same name and package when it loads the class, when it actually executes, it doesn't actually call the class we want. Hence the `NoSuchMethod` exception.
|
||||
|
||||
**Solution**: add a configuration class for MapStructPlus to each module, specifying a different path for the `adapterPackage` package in each module.
|
||||
|
||||
#### Integration with `lombok`
|
||||
|
||||
In line with how MapStruct integrates lombok
|
||||
|
||||
##### before lombok 1.18.16:
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Maven
|
||||
|
||||
```xml
|
||||
|
||||
<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>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-processor</artifactId>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::: code-group-item Gradle
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: {lombok.version}
|
||||
annotationProcessor group: 'io.github.linpeilie', name: 'mapstruct-plus-processor', version: ${mapstruct-plus.version}
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
##### lombok 1.18.16 et seq:
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Maven
|
||||
|
||||
```xml
|
||||
|
||||
<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>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-processor</artifactId>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok-mapstruct-binding</artifactId>
|
||||
<version>0.2.0</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
:::
|
||||
::: code-group-item Gradle
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: {lombok.version}
|
||||
annotationProcessor group: 'io.github.linpeilie', name: 'mapstruct-plus-processor', version: ${mapstruct-plus.version}
|
||||
annotationProcessor group: 'org.projectlombok', name: 'lombok-mapstruct-binding', version: '0.2.0'
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
#### When developed locally, error reporting is started after the class is modified and returned to normal after mvn clean compile
|
||||
|
||||
The problem is that no configuration class was found due to the IDEA partial compilation.
|
||||
Update the latest version and change the configuration. See [Guide - Configuration](/en/guide/configuration.html) for details.
|
||||
99
docs/en/guide/map-to-class.md
Normal file
@ -0,0 +1,99 @@
|
||||
---
|
||||
title: Map to Object
|
||||
order: 2
|
||||
category:
|
||||
- Guide
|
||||
description: MapStructPlus Map转为对象 map convert to class
|
||||
---
|
||||
|
||||
MapStructPlus provides more powerful function for `Map<String, Object>` to object
|
||||
|
||||
## Usage
|
||||
|
||||
**Just add the `@AutoMapMapper` annotation to the target class when you want to automatically generate the interface and implementation classes that `Map<String, Object>` to the target class.**
|
||||
|
||||
## The supported value type
|
||||
|
||||
- `String`
|
||||
- `BigDecimal`
|
||||
- `BigInteger`
|
||||
- `Integer`
|
||||
- `Long`
|
||||
- `Double`
|
||||
- `Boolean`
|
||||
- `Date`
|
||||
- `LocalDateTime`
|
||||
- `LocalDate`
|
||||
- `LocalTime`
|
||||
- `URI`
|
||||
- `URL`
|
||||
- `Calendar`
|
||||
- `Currency`
|
||||
- `Custom classes(custom classes also require @AutoMapMapper annotation)`
|
||||
|
||||
## Transformation logic
|
||||
|
||||
**For an attribute in the target class, it first determintes whether the key exists in the Map.
|
||||
If it does, it first determines the type, the conversion is attempted to the target type based on the type conversion tool provided by [Hutool](https://hutool.cn/docs/#/core/%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E5%B7%A5%E5%85%B7%E7%B1%BB-Convert)**
|
||||
|
||||
**It also supports internally nested `Map<String, Object` attributes to internally nested custom type attributes.**
|
||||
|
||||
## Example
|
||||
|
||||
- Define two class:`MapModelA` 和 `MapModelB`
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item MapModelA
|
||||
```java
|
||||
@AutoMapMapper
|
||||
@Data
|
||||
public class MapModelA {
|
||||
|
||||
private String str;
|
||||
private int i1;
|
||||
private Long l2;
|
||||
private MapModelB mapModelB;
|
||||
|
||||
}
|
||||
```
|
||||
:::
|
||||
::: code-group-item MapModelB
|
||||
```java
|
||||
@AutoMapMapper
|
||||
@Data
|
||||
public class MapModelB {
|
||||
|
||||
private Date date;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
- Test
|
||||
|
||||
```java
|
||||
@SpringBootTest
|
||||
public class QuickStartTest {
|
||||
|
||||
@Autowired
|
||||
private Converter converter;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Map<String, Object> mapModel1 = new HashMap<>();
|
||||
mapModel1.put("str", "1jkf1ijkj3f");
|
||||
mapModel1.put("i1", 111);
|
||||
mapModel1.put("l2", 11231);
|
||||
|
||||
Map<String, Object> mapModel2 = new HashMap<>();
|
||||
mapModel2.put("date", DateUtil.parse("2023-02-23 01:03:23"));
|
||||
|
||||
mapModel1.put("mapModelB", mapModel2);
|
||||
|
||||
final MapModelA mapModelA = converter.convert(mapModel1, MapModelA.class);
|
||||
System.out.println(mapModelA); // MapModelA(str=1jkf1ijkj3f, i1=111, l2=11231, mapModelB=MapModelB(date=2023-02-23 01:03:23))
|
||||
}
|
||||
}
|
||||
```
|
||||
73
docs/en/guide/multiple-class-convert.md
Normal file
@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Class converted with multiple class
|
||||
order: 4
|
||||
category:
|
||||
- Guide
|
||||
description: MapStructPlus 一个类与多个类之间转换 multiple class convert
|
||||
---
|
||||
|
||||
MapStructPlus supports conversion of a single class to multiple target types as well as a single class to a single target type.
|
||||
|
||||
## Configure multiplee class conversions
|
||||
|
||||
When you want to configure a class to convert to multiple classes, you can do so through `@AutoMappers`, which supports configure multiple `@AutoMapper`
|
||||
|
||||
eg:
|
||||
|
||||
```java
|
||||
@Data
|
||||
@AutoMappers({
|
||||
@AutoMapper(target = UserDto.class),
|
||||
@AutoMapper(target = UserVO.class)
|
||||
})
|
||||
public class User {
|
||||
// fields
|
||||
}
|
||||
```
|
||||
|
||||
## Configures the rules for the specified class transformation
|
||||
|
||||
When configuring multiple class conversions, the same property has different conversion rules for different classes.
|
||||
|
||||
To solve this problem, you can first specify multiple transformation rules using `@AutoMappings` and,
|
||||
when using the `@AutoMapping` annotation, configure the `targetClass` attribute to specify the application target transformation class for the current rule.
|
||||
|
||||
If `targetClass` is not specified when the `@AutoMapping` annotation is configured, the current rule applies to all class conversions.
|
||||
|
||||
eg:
|
||||
|
||||
```java
|
||||
@Data
|
||||
@AutoMappers({
|
||||
@AutoMapper(target = UserDto.class),
|
||||
@AutoMapper(target = UserVO.class)
|
||||
})
|
||||
public class User {
|
||||
|
||||
private String username;
|
||||
|
||||
private int age;
|
||||
private boolean young;
|
||||
|
||||
@AutoMapping(targetClass = UserDto.class, target = "educations", expression = "java(java.lang.String.join(\",\", source.getEducationList()))")
|
||||
private List<String> educationList;
|
||||
|
||||
@AutoMappings({
|
||||
@AutoMapping(targetClass = UserDto.class, dateFormat = "yyyy-MM-dd HH:mm:ss"),
|
||||
@AutoMapping(targetClass = UserVO.class, ignore = true)
|
||||
})
|
||||
private Date birthday;
|
||||
|
||||
@AutoMapping(targetClass = UserDto.class, numberFormat = "$0.00")
|
||||
private double assets;
|
||||
|
||||
@AutoMapping(numberFormat = "$0.00")
|
||||
private double money;
|
||||
|
||||
@AutoMappings({
|
||||
@AutoMapping(targetClass = UserVO.class, target = "voField")
|
||||
})
|
||||
private String voField;
|
||||
|
||||
}
|
||||
```
|
||||
27
docs/en/introduction/about.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
title: About
|
||||
order: 1
|
||||
category:
|
||||
- Introduction
|
||||
tag:
|
||||
- About
|
||||
description: MapStructPlus MapstructPlus简介,MapstructPlus是什么 Abount
|
||||
---
|
||||
|
||||
> First, take a look at MapStruct:
|
||||
> [MapStruct](https://mapstruct.org) is a code generator that automatically implements the concrete logic of property conversion by defining an interface for class conversion. Mainly to simplify the implementation of conversion between Java types.
|
||||
|
||||
MapStructPlus is an enhancement tool of MapStruct, on the basis of MapStruct, it realizes the function of automatically generating Mapper interface, and strengthens some functions, making Java type conversion more convenient and elegant.
|
||||
|
||||
Like MapStruct, it is essentially JSR 269 based Java annotation handler, so triggers can be built by Maven、Gradle、Ant and so on.
|
||||
|
||||
MapStructPlus is embedded with MapStruct, fully compatible with MapStruct, and can seamlessly replace dependencies if you have previously used MapStruct.
|
||||
|
||||
## Code Warehouse
|
||||
|
||||
- [Gitee](https://gitee.com/linpeilie/mapstruct-plus)
|
||||
- [Github](https://github.com/linpeilie/mapstruct-plus)
|
||||
|
||||
## Participate and contribute
|
||||
- Contribution Code: You are welcome to submit an issue or pull requests
|
||||
- Maintain Documents: Docs directory under the project directory, welcome to participate in the translation and revision
|
||||
108
docs/en/introduction/install.md
Normal file
@ -0,0 +1,108 @@
|
||||
---
|
||||
title: Install
|
||||
order: 2
|
||||
category:
|
||||
- Introduction
|
||||
tag:
|
||||
- Install
|
||||
description: MapStructPlus 依赖安装 install
|
||||
---
|
||||
|
||||
::: warning
|
||||
Because it is already embedded with MapStruct, do not introduce MapStruct related dependencies to prevent differences between versions.
|
||||
:::
|
||||
|
||||
## Non-SpringBoot environment
|
||||
|
||||
### Maven
|
||||
|
||||
```xml
|
||||
<properties>
|
||||
<mapstruct-plus.version>latest version</mapstruct-plus.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus</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> <!-- Here to switch according to their need -->
|
||||
<target>1.8</target> <!-- Here to switch according to their need -->
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-processor</artifactId>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
### Gradle
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
implementation 'io.github.linpeilie:mapstruct-plus:latest version'
|
||||
|
||||
annotationProcessor 'io.github.linpeilie:mapstruct-plus-processor:latest version'
|
||||
}
|
||||
```
|
||||
|
||||
## SpringBoot environment
|
||||
|
||||
### Maven
|
||||
|
||||
```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> <!-- Here to switch according to their need -->
|
||||
<target>1.8</target> <!-- Here to switch according to their need -->
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-processor</artifactId>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
### Gradle
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
implementation 'io.github.linpeilie:mapstruct-plus-spring-boot-starter:latest version'
|
||||
|
||||
annotationProcessor 'io.github.linpeilie:mapstruct-plus-processor:latest version'
|
||||
}
|
||||
```
|
||||
|
||||
327
docs/en/introduction/quick-start.md
Normal file
@ -0,0 +1,327 @@
|
||||
---
|
||||
title: Quick Start
|
||||
order: 3
|
||||
category:
|
||||
- Introduction
|
||||
description: MapStructPlus 快速开始教程 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
|
||||
}
|
||||
```
|
||||
|
||||
## Non-SpringBoot environment
|
||||
|
||||
### add dependencies
|
||||
|
||||
Introducing `mapstruct-plus` dependencies:
|
||||
|
||||
#### Maven
|
||||
|
||||
```xml
|
||||
<properties>
|
||||
<mapstruct-plus.version>latest version</mapstruct-plus.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus</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>
|
||||
```
|
||||
|
||||
#### Gradle
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus', version: ${mapstruct-plus.version}
|
||||
|
||||
annotationProcessor group: 'io.github.linpeilie', name: 'mapstruct-plus-processor', version: ${mapstruct-plus.version}
|
||||
}
|
||||
```
|
||||
|
||||
### add configuration class
|
||||
|
||||
In the module package where the Bean object resides, add a comment on any class: `@ComponentModelConfig(componentModel = "default")`
|
||||
|
||||
eg:
|
||||
|
||||
```java
|
||||
@ComponentModelConfig(componentModel = "default")
|
||||
public class MapperConfiguration {
|
||||
}
|
||||
```
|
||||
|
||||
### Specifies the object mapping relationship
|
||||
|
||||
Add a annotation - `@AutoMapper` above `User` or `UserDto` and set `targetType` to the opposite class.
|
||||
|
||||
eg:
|
||||
|
||||
```java
|
||||
@AutoMapper(target = UserDto.class)
|
||||
public class User {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Test
|
||||
|
||||
```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 Environment
|
||||
|
||||
### Add dependencies
|
||||
|
||||
Introducing `mapstruct-plus-spring-boot-starter` dependencies:
|
||||
|
||||
#### Maven
|
||||
|
||||
```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>
|
||||
```
|
||||
|
||||
#### Gradle
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: ${mapstruct-plus.version}
|
||||
|
||||
annotationProcessor group: 'io.github.linpeilie', name: 'mapstruct-plus-processor', version: ${mapstruct-plus.version}
|
||||
}
|
||||
```
|
||||
|
||||
### Specifies the object mapping relationship
|
||||
|
||||
Same as non-SpringBoot environment
|
||||
|
||||
### 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();
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Solon
|
||||
|
||||
:::info
|
||||
since `1.2.5`
|
||||
:::
|
||||
|
||||
### Add dependencies
|
||||
|
||||
Introducing `mapstruct-plu-solon-plugin` dependencies:
|
||||
|
||||
> `mapstruct-plus-solon-plugin` has been added to `solon-parent` dependency management, and the latest version can be viewed in [solon-plugins](https://gitee.com/dromara/solon-plugins)
|
||||
|
||||
```xml
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dromara.solon-plugins</groupId>
|
||||
<artifactId>mapstruct-plus-solon-plugins</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-processor</artifactId>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs>
|
||||
<arg>
|
||||
-Amapstruct.defaultComponentModel=solon
|
||||
</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
### Specifies the object mapping relationship
|
||||
|
||||
Same as SpringBoot environment
|
||||
|
||||
### Test
|
||||
|
||||
```java
|
||||
@SolonTest(DemoApp.class)
|
||||
@ExtendWith(SolonJUnit5Extension.class)
|
||||
public class QuickStartTest {
|
||||
|
||||
@Inject
|
||||
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.
|
||||
100
docs/en/release/log.md
Normal file
@ -0,0 +1,100 @@
|
||||
---
|
||||
title: 更新日志
|
||||
order: 1
|
||||
category:
|
||||
- 更新日志
|
||||
description: MapStructPlus release log
|
||||
---
|
||||
|
||||
### 1.3.5
|
||||
|
||||
- AutoMapping、ReverseAutoMapping 支持配置在方法上面;
|
||||
- AutoMapping、ReverseAutoMapping 支持 defaultExpression 和 conditionExpression 属性
|
||||
|
||||
### 1.3.4
|
||||
|
||||
……什么都没更新,腾讯云maven源同步的jar有问题,只能重新发个新包
|
||||
|
||||
### 1.3.3
|
||||
|
||||
- fixbug: 修复 win JDK8 编译报错问题
|
||||
|
||||
### 1.3.2
|
||||
|
||||
- 不可变对象支持,可以使用任意包下的 `Immutable` 标注类型为不可变类
|
||||
- 全面适配 IDEA 部分编译问题,使用更加流畅丝滑
|
||||
|
||||
### 1.3.1
|
||||
|
||||
- 增加编译参数中指定配置类的功能
|
||||
- 更好地适配 IDEA 部分编译场景
|
||||
|
||||
### 1.3.0
|
||||
|
||||
- fix: 解决本地开发时 IDEA 编译或者运行时报错等与预期不一致的问题
|
||||
- feature: AutoMapper 注解增加 imports 属性支持
|
||||
|
||||
### 1.2.5
|
||||
|
||||
- fix: 解决 MapConvertMapperAdapter 编译警告问题
|
||||
- feat: 增加 `nullValueMappingStrategy` 和 `nullValuePropertyMappingStrategy` 配置项
|
||||
- feat: 适配 solon
|
||||
|
||||
### 1.2.4
|
||||
|
||||
- fixbug: 修复当项目中只有 AutoMappers 注解时,没有生成转换接口的问题
|
||||
|
||||
### 1.2.3
|
||||
|
||||
- MapStructPlus 版本由 `1.5.3.Final` 升级为 `1.5.5.Final`
|
||||
- 增加自定义 `ConvertMapperAdapter` 和 `MapConvertMapperAdapter` 类名和包名的功能
|
||||
- 生成的转换接口,自动接入自定义转换接口,具体[详见](/guide/class-convert.html#自动接入自定义转换接口)
|
||||
|
||||
### 1.2.2
|
||||
|
||||
- fixbug: 定义多个uses时的问题
|
||||
- feature: 增加 `@AutoEnumMapper` 注解,可以在类型转换时,自动转换枚举
|
||||
|
||||
### 1.2.1
|
||||
|
||||
- 解决JDK17编译警告
|
||||
|
||||
### 1.2.0
|
||||
|
||||
- 增加unmappedSourcePolicy、unmappedTargetPolicy配置,并且设置unmappedTargetPolicy默认为ignore
|
||||
- 增加Builder配置,并设置disableBuilder默认为true
|
||||
|
||||
### 1.1.8
|
||||
|
||||
- 解决当只有 @AutoMapMapper 注解时,没有生成转换器的问题
|
||||
- 修改没有找到转换器时的异常描述
|
||||
|
||||
## 1.1.7
|
||||
|
||||
- fixBug: [issue#8](https://github.com/linpeilie/mapstruct-plus/issues/11) Converter 转换已有对象不生效的问题
|
||||
- 添加寻找转换接口的缓存,转换速度更快
|
||||
|
||||
## 1.1.6
|
||||
|
||||
- 支持在添加 `AutoMapper` 的类中,配置目标类到当前类的转换规则,适配多种场景下的使用;
|
||||
- `AutoMapper` 增加注解,提供可以配置是否生成转换接口的功能;
|
||||
- `AutoMapping` 的 target 属性默认可以不填,不填则取当前字段
|
||||
- 升级 mapstruct 版本为 1.5.3.FINAL
|
||||
|
||||
## 1.1.5
|
||||
|
||||
- `AutoMapping` 增加 `source` 和 `defaultValue` 属性支持
|
||||
|
||||
## 1.1.4
|
||||
|
||||
- 增加反向转换配置功能
|
||||
- 解决树状结构转换bug
|
||||
|
||||
## 1.1.3
|
||||
|
||||
- 适配 SpringBoot3
|
||||
|
||||
## 1.1.1
|
||||
|
||||
- 增加 Map 转对象的功能
|
||||
- 增加单个对象与多个对象转换并配置的功能
|
||||
@ -22,7 +22,7 @@ public class Car {
|
||||
|
||||
当一个属性与它的目标实体对应物具有相同的名称时,将会被隐式映射。
|
||||
|
||||
除此之外,MapstructPlus 会根据当前的默认规则,生成 `CarDto` 转换为 `Car` 的接口 `CarDtoToCarMapper` 及实现类 `CarDtoToCarMapperImpl`。如果不想生成该转换逻辑的话,可以通过注解的 `reverseConvertGenerate` 属性来配置。
|
||||
除此之外,MapStructPlus 会根据当前的默认规则,生成 `CarDto` 转换为 `Car` 的接口 `CarDtoToCarMapper` 及实现类 `CarDtoToCarMapperImpl`。如果不想生成该转换逻辑的话,可以通过注解的 `reverseConvertGenerate` 属性来配置。
|
||||
|
||||
## 自定义对象的属性自动转换
|
||||
|
||||
@ -34,10 +34,8 @@ public class Car {
|
||||
|
||||
- 汽车模型
|
||||
|
||||
::: code-tabs#java
|
||||
|
||||
@tab Car
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Car
|
||||
```java
|
||||
@AutoMapper(target = CarDto.class)
|
||||
@Data
|
||||
@ -45,24 +43,21 @@ public class Car {
|
||||
private SeatConfiguration seatConfiguration;
|
||||
}
|
||||
```
|
||||
|
||||
@tab CarDto
|
||||
|
||||
:::
|
||||
::: code-group-item CarDto
|
||||
```java
|
||||
@Data
|
||||
public class CarDto {
|
||||
private SeatConfigurationDto seatConfiguration;
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
- 座椅模型
|
||||
|
||||
::: code-tabs#java
|
||||
|
||||
@tab SeatConfiguration
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item SeatConfiguration
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = SeatConfigurationDto.class)
|
||||
@ -70,17 +65,16 @@ public class SeatConfiguration {
|
||||
// fields
|
||||
}
|
||||
```
|
||||
|
||||
@tab SeatConfigurationDto
|
||||
|
||||
:::
|
||||
::: code-group-item SeatConfigurationDto
|
||||
```java
|
||||
@Data
|
||||
public class SeatConfigurationDto {
|
||||
// fields
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
在上面的例子中,首先会生成 `CarToCarDtoMapper` 和 `SeatConfigurationToSeatConfigurationDtoMapper` 两个转换接口,并且在转换 `Car` 时,会自动使用 `SeatConfigurationToSeatConfigurationDtoMapper` 来对其中的座椅属性来进行转换。
|
||||
|
||||
@ -171,10 +165,8 @@ public class Car {
|
||||
|
||||
例如:
|
||||
|
||||
::: code-tabs#java
|
||||
|
||||
@tab Goods
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Goods
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = GoodsVo.class, reverseConvertGenerate = false)
|
||||
@ -185,9 +177,8 @@ public class Goods {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@tab GoodsVo
|
||||
|
||||
:::
|
||||
::: code-group-item GoodsVo
|
||||
```java
|
||||
@Data
|
||||
public class GoodsVo {
|
||||
@ -196,8 +187,8 @@ public class GoodsVo {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
### 指定时间格式转换
|
||||
|
||||
@ -205,10 +196,8 @@ public class GoodsVo {
|
||||
|
||||
例如:
|
||||
|
||||
::: code-tabs#java
|
||||
|
||||
@tab Order
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Order
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = OrderEntity.class)
|
||||
@ -225,9 +214,8 @@ public class Order {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@tab OrderEntity
|
||||
|
||||
:::
|
||||
::: code-group-item OrderEntity
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = Order.class)
|
||||
@ -244,8 +232,8 @@ public class OrderEntity {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
### 指定数字格式转换
|
||||
|
||||
@ -255,10 +243,8 @@ public class OrderEntity {
|
||||
|
||||
例如:
|
||||
|
||||
::: code-tabs#java
|
||||
|
||||
@tab Order
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Order
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = OrderEntity.class)
|
||||
@ -272,9 +258,8 @@ public class Order {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@tab OrderEntity
|
||||
|
||||
:::
|
||||
::: code-group-item OrderEntity
|
||||
```java
|
||||
@Data
|
||||
@AutoMapper(target = Order.class)
|
||||
@ -288,8 +273,8 @@ public class OrderEntity {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
### 忽略指定属性的转换
|
||||
|
||||
@ -361,10 +346,8 @@ since `1.2.3`
|
||||
|
||||
例如:
|
||||
|
||||
::: code-tabs#java
|
||||
|
||||
@tab Car
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item Car
|
||||
```java
|
||||
@AutoMapper(target = CarDto.class)
|
||||
@Data
|
||||
@ -372,17 +355,16 @@ public class Car {
|
||||
private Tyre tyre;
|
||||
}
|
||||
```
|
||||
|
||||
@tab CarDto
|
||||
|
||||
:::
|
||||
::: code-group-item CarDto
|
||||
```java
|
||||
@Data
|
||||
public class CarDto {
|
||||
private TyreDTO tyre;
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
这里定义 `Tyre` 和 `TyreDTO` 之间的转换接口:
|
||||
|
||||
@ -399,10 +381,8 @@ public interface TyreMapper {
|
||||
|
||||
生成的 `Car` 与 `CarDto` 转换接口的实现类如下:
|
||||
|
||||
::: code-tabs#java
|
||||
|
||||
@tab CarToCarDtoMapperImpl
|
||||
|
||||
:::: code-group
|
||||
::: CarToCarDtoMapperImpl
|
||||
```java
|
||||
@Generated(
|
||||
value = "org.mapstruct.ap.MappingProcessor",
|
||||
@ -440,9 +420,8 @@ public class CarToCarDtoMapperImpl implements CarToCarDtoMapper {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@tab CarDtoToCarMapperImpl
|
||||
|
||||
:::
|
||||
::: CarDtoToCarMapperImpl
|
||||
```java
|
||||
@Generated(
|
||||
value = "org.mapstruct.ap.MappingProcessor",
|
||||
@ -481,7 +460,7 @@ public class CarDtoToCarMapperImpl implements CarDtoToCarMapper {
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::::
|
||||
|
||||
## 反向属性映射配置
|
||||
|
||||
@ -510,7 +489,7 @@ public class CarDtoToCarMapperImpl implements CarDtoToCarMapper {
|
||||
|
||||
可能会有人这里有疑问,为什么这里的配置像是反的?如果没有,可以直接跳过。
|
||||
|
||||
框架设计的时候,所有的属性转换配置,都是基于要转换的类型,该类转换为目标类,想要应用的效果。这里的 `source` 也应该是来源类中的属性。
|
||||
框架设计的时候,所有的属性转换配置,都是基于要转换的类型,最终想要的效果是将该类转换为目标类。这里的 `source` 也应该是来源类中的属性。
|
||||
|
||||
如果还是不理解,这里可以认为,该注解就是本该应用在目标类中的 `@AutoMapping` 注解,原封不动拷贝到当前类,再修改注解名称即可。
|
||||
|
||||
|
||||
@ -23,49 +23,6 @@ public class MapStructPlusConfiguration {
|
||||
}
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
1.3.2 已彻底适配 IDEA 部分编译,无需再添加如下配置。
|
||||
|
||||
~~当使用该方式配置时,强烈建议,在编译参数中,指定配置类为当前类,以解决IDEA部分编译场景时出现的各种问题,该功能从 1.3.1 开始支持
|
||||
|
||||
配置时,需要在启动参数中添加 `-Amapstruct.plus.mapperConfigClass` 参数,该参数的值为配置类的全路径名称~~:
|
||||
|
||||
```xml
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-processor</artifactId>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok-mapstruct-binding</artifactId>
|
||||
<version>0.2.0</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<compilerArgs>
|
||||
<arg>-Amapstruct.plus.mapperConfigClass=com.tutelary.MapStructPlusConfiguration</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
```
|
||||
:::
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
除此之外,配置属性还支持**增加编译参数**的方式,以 `-Akey=value` 的形式,传递给编译器。
|
||||
|
||||
例如,使用 Maven 时,可以在 `maven-compiler-plugin` 插件配置中,使用 `compilerArgs` 属性来配置传递,例如:
|
||||
|
||||
@ -8,12 +8,12 @@ description: MapStructPlus Map转为对象 map convert to class
|
||||
|
||||
> 当前特性从 1.2.2 开始支持
|
||||
|
||||
当需要进行枚举转换时(例如枚举转换为编码值,或者又编码转换为枚举),可以在目标枚举添加 `@AutoEnumMapper` 注解,
|
||||
当需要进行枚举转换时(例如枚举转换为编码值,或者由编码转换为枚举),可以在目标枚举添加 `@AutoEnumMapper` 注解,
|
||||
增加该注解后,在任意类型中需要转换该枚举时都可以自动转换。
|
||||
|
||||
使用该注解需要注意:**当前注解必须有一个可以保证唯一的字段**,并在使用当前注解时,将该字段名,添加到注解提供的 `value` 属性中。
|
||||
使用该注解需要注意:**当前枚举必须有一个可以保证唯一的字段**,并在使用当前注解时,将该字段名,添加到注解提供的 `value` 属性中。
|
||||
|
||||
还有就是**注解和使用注解的类,要在同一个模块中**。
|
||||
还有就是**枚举和使用枚举的类,要在同一个模块中**。
|
||||
|
||||
例如:
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ description: MapStructPlus MapStructPlus常见问题 faq
|
||||
4. 在 /target/generated-sources 目录下,查看是否生成转换接口。
|
||||
5. 如果没有生成,联系作者
|
||||
6. 如果已经生成,需要确认 SpringBoot 能否扫描到生成接口所在的包!
|
||||
7. 检测是否依赖 `spring-boot-devtools`,该工具会修改类的 `ClassLoader`!导致匹配类失败,不止该框架,该工具还会引发其他莫名奇妙的问题!去掉该依赖即可。
|
||||
|
||||
## 生成的转换接口及实现类的目录规则
|
||||
|
||||
@ -54,7 +55,8 @@ description: MapStructPlus MapStructPlus常见问题 faq
|
||||
|
||||
### lombok 1.18.16 之前:
|
||||
|
||||
#### Maven
|
||||
:::: code-group
|
||||
::: code-group-item Maven
|
||||
|
||||
```xml
|
||||
|
||||
@ -85,7 +87,9 @@ description: MapStructPlus MapStructPlus常见问题 faq
|
||||
</build>
|
||||
```
|
||||
|
||||
#### Gradle
|
||||
:::
|
||||
|
||||
::: code-group-item Gradle
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
@ -94,9 +98,13 @@ dependencies {
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
### lombok 1.18.16 及以后:
|
||||
|
||||
#### Maven
|
||||
:::: code-group
|
||||
::: code-group-item Maven
|
||||
|
||||
```xml
|
||||
|
||||
@ -131,8 +139,8 @@ dependencies {
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
#### Gradle
|
||||
:::
|
||||
::: code-group-item Gradle
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
@ -142,6 +150,9 @@ dependencies {
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
## 本地开发时,修改类后启动报错,mvn clean compile 后又恢复正常
|
||||
|
||||
该问题是由于 IDEA 部分编译导致没有找到配置类导致的,先更新最新版本,更换配置方式,详情可以查看[指南 - 配置](/guide/configuration.html)
|
||||
@ -6,7 +6,7 @@ category:
|
||||
description: MapStructPlus Map转为对象 map convert to class
|
||||
---
|
||||
|
||||
MapstructPlus 提供了更加强大的 `Map<String, Object>` 转对象的功能。
|
||||
MapStructPlus 提供了更加强大的 `Map<String, Object>` 转对象的功能。
|
||||
|
||||
## 使用
|
||||
|
||||
@ -41,10 +41,8 @@ MapstructPlus 提供了更加强大的 `Map<String, Object>` 转对象的功能
|
||||
|
||||
- 定义两个对象:`MapModelA` 和 `MapModelB`
|
||||
|
||||
::: code-tabs#java
|
||||
|
||||
@tab MapModelA
|
||||
|
||||
:::: code-group
|
||||
::: code-group-item MapModelA
|
||||
```java
|
||||
@AutoMapMapper
|
||||
@Data
|
||||
@ -57,9 +55,8 @@ public class MapModelA {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@tab MapModelB
|
||||
|
||||
:::
|
||||
::: code-group-item MapModelB
|
||||
```java
|
||||
@AutoMapMapper
|
||||
@Data
|
||||
@ -69,8 +66,8 @@ public class MapModelB {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
::::
|
||||
|
||||
- 转换测试
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ category:
|
||||
description: MapStructPlus 一个类与多个类之间转换 multiple class convert
|
||||
---
|
||||
|
||||
MapstructPlus 除了支持一个类与单个目标类型进行转换,还支持一个类与多个目标类型进行转换。
|
||||
MapStructPlus 除了支持一个类与单个目标类型进行转换,还支持一个类与多个目标类型进行转换。
|
||||
|
||||
## 配置多个类转换
|
||||
|
||||
@ -27,7 +27,7 @@ public class User {
|
||||
|
||||
## 配置指定类转换的规则
|
||||
|
||||
当配置多个类转换时,可能会有不同的类,同一属性转换规则不同的场景。
|
||||
当配置多个类转换时,同一属性针对不同的类有不一样的转换规则。
|
||||
|
||||
针对这个问题,首先可以使用 `@AutoMappings` 指定多个转换规则,并且在使用 `@AutoMapping` 注解时,配置 `targetClass` 属性,指定当前规则的应用目标转换类。
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ description: MapStructPlus 依赖安装 install
|
||||
<dependency>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus</artifactId>
|
||||
<version>{mapstruct-plus.version}</version>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
|
||||
@ -6,6 +6,11 @@ category:
|
||||
description: MapStructPlus release log
|
||||
---
|
||||
|
||||
### 1.3.5
|
||||
|
||||
- AutoMapping、ReverseAutoMapping 支持配置在方法上面;
|
||||
- AutoMapping、ReverseAutoMapping 支持 defaultExpression 和 conditionExpression 属性
|
||||
|
||||
### 1.3.4
|
||||
|
||||
……什么都没更新,腾讯云maven源同步的jar有问题,只能重新发个新包
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
package io.github.linpeilie.model;
|
||||
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import io.github.linpeilie.annotations.AutoMapping;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AutoMapper(target = MoveChange.class)
|
||||
public class IndMoveChangeFormVo {
|
||||
/**
|
||||
* 工号
|
||||
*/
|
||||
private String agentCode;
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 管理机构
|
||||
*/
|
||||
@AutoMapping(source = "manageCom", target = "oldManageCom")
|
||||
private String manageCom;
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package io.github.linpeilie.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MoveChange {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 工号
|
||||
*/
|
||||
private String agentCode;
|
||||
/**
|
||||
* 调整前机构
|
||||
*/
|
||||
private String oldManageCom;
|
||||
}
|
||||
19882
package-lock.json
generated
27
package.json
@ -1,26 +1,19 @@
|
||||
{
|
||||
"name": "mapstruct-plus",
|
||||
"name": "vuepress-theme-reco-demo",
|
||||
"version": "2.0.0",
|
||||
"description": "mapstruct-plus-document",
|
||||
"description": "Demo for vuepress-theme-reco@2.x.",
|
||||
"repository": "git@github.com:recoluan/vuepress-theme-reco-demo.git",
|
||||
"author": "reco_luan <recoluan@outlook.com>",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vuepress dev docs",
|
||||
"start": "vuepress dev docs",
|
||||
"build": "vuepress build docs",
|
||||
"docs:build": "vuepress build docs",
|
||||
"docs:clean-dev": "vuepress dev docs --clean-cache",
|
||||
"docs:dev": "vuepress dev docs",
|
||||
"docs:update-package": "npx vp-update"
|
||||
"docs:clean-dev": "vuepress dev docs --clean-cache"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vuepress/client": "2.0.0-beta.61",
|
||||
"@vuepress/plugin-google-analytics": "^2.0.0-beta.61",
|
||||
"@vuepress/plugin-search": "^2.0.0-beta.61",
|
||||
"@vuepress/plugin-shiki": "^2.0.0-beta.61",
|
||||
"vue": "^3.2.47",
|
||||
"vuepress": "2.0.0-beta.61",
|
||||
"vuepress-plugin-china-search-console": "^2.1.5",
|
||||
"vuepress-plugin-components": "^2.0.0-beta.197",
|
||||
"vuepress-theme-hope": "2.0.0-beta.185"
|
||||
"dependencies": {
|
||||
"vue": "3.3.11",
|
||||
"vuepress": "2.0.0-rc.0",
|
||||
"vuepress-theme-reco": "2.0.0-rc.1"
|
||||
}
|
||||
}
|
||||
|
||||