更新文档
14
.dumirc.ts
@ -1,14 +0,0 @@
|
|||||||
import { defineConfig } from 'dumi';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
themeConfig: {
|
|
||||||
name: 'mapstruct-plus',
|
|
||||||
logo: false,
|
|
||||||
prefersColor: { default: 'auto' },
|
|
||||||
github: 'https://github.com/linpeilie',
|
|
||||||
footer: false
|
|
||||||
},
|
|
||||||
base: '/',
|
|
||||||
publicPath: '/',
|
|
||||||
sitemap: { hostname: 'https://mapstruct.plus' }
|
|
||||||
});
|
|
||||||
49
.github/workflows/deploy-docs.yml
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
name: 部署文档
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
# 确保这是你正在使用的分支名称
|
||||||
|
- docs
|
||||||
|
# 手动触发部署
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy-gh-pages:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
# 如果你文档需要 Git 子模块,取消注释下一行
|
||||||
|
# submodules: true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- name: 设置 Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: 安装依赖
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: 构建文档
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: --max_old_space_size=8192
|
||||||
|
run: |-
|
||||||
|
npm run docs:build
|
||||||
|
> docs/.vuepress/dist/.nojekyll
|
||||||
|
|
||||||
|
- name: 部署文档
|
||||||
|
uses: JamesIves/github-pages-deploy-action@v4
|
||||||
|
with:
|
||||||
|
# 这是文档部署到的分支名称
|
||||||
|
branch: gh-pages
|
||||||
|
folder: docs/.vuepress/dist
|
||||||
|
env:
|
||||||
|
# @see https://docs.github.com/cn/actions/reference/authentication-in-a-workflow#about-the-github_token-secret
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
23
.github/workflows/gh-pages.yml
vendored
@ -1,23 +0,0 @@
|
|||||||
name: github pages
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main # default branch
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: npm install
|
|
||||||
# 文档编译命令,如果是 react 模板需要修改为 npm run docs:build
|
|
||||||
- run: npm run build
|
|
||||||
- name: Publish github pages
|
|
||||||
run: |
|
|
||||||
git config --global user.email "linpeilie@users.noreply.com"
|
|
||||||
git config --global user.name "linpeilie"
|
|
||||||
git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
|
|
||||||
npm run deploy -u "github-actions-bot <support+actions@github.com>"
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
6
.gitignore
vendored
@ -46,3 +46,9 @@ package-lock.json
|
|||||||
dist
|
dist
|
||||||
.dumi/tmp
|
.dumi/tmp
|
||||||
.dumi/tmp-production
|
.dumi/tmp-production
|
||||||
|
|
||||||
|
|
||||||
|
node_modules/
|
||||||
|
docs/.vuepress/.cache/
|
||||||
|
docs/.vuepress/.temp/
|
||||||
|
docs/.vuepress/dist/
|
||||||
41
docs/.vuepress/config.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import {defineUserConfig} from "vuepress";
|
||||||
|
import {shikiPlugin} from "@vuepress/plugin-shiki";
|
||||||
|
import {searchPlugin} from "@vuepress/plugin-search";
|
||||||
|
import theme from "./theme.js";
|
||||||
|
|
||||||
|
export default defineUserConfig({
|
||||||
|
base: "/",
|
||||||
|
|
||||||
|
head: [['script', {}, `
|
||||||
|
<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);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
`]],
|
||||||
|
|
||||||
|
locales: {
|
||||||
|
"/": {
|
||||||
|
lang: "zh-CN",
|
||||||
|
title: "MapstructPlus",
|
||||||
|
description: "MapstructPlus指南",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
theme,
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
shikiPlugin({
|
||||||
|
// theme: 'github-dark-dimmed'
|
||||||
|
theme: 'material-theme-darker'
|
||||||
|
}),
|
||||||
|
searchPlugin({
|
||||||
|
isSearchable: (page) => page.path !== '/'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
1
docs/.vuepress/navbar/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./zh.js";
|
||||||
8
docs/.vuepress/navbar/zh.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { navbar } from "vuepress-theme-hope";
|
||||||
|
|
||||||
|
export const zhNavbar = navbar([
|
||||||
|
"/",
|
||||||
|
{ text: "指南", icon: "discover", link: "/guide/class-convert" },
|
||||||
|
{ text: "更新日志", icon: "discover", link: "/release/log" }
|
||||||
|
]);
|
||||||
|
|
||||||
BIN
docs/.vuepress/public/assets/contact-me.png
Normal file
|
After Width: | Height: | Size: 229 KiB |
BIN
docs/.vuepress/public/assets/icon/apple-icon-152.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
docs/.vuepress/public/assets/icon/chrome-192.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
docs/.vuepress/public/assets/icon/chrome-512.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
docs/.vuepress/public/assets/icon/chrome-mask-192.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
docs/.vuepress/public/assets/icon/chrome-mask-512.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
docs/.vuepress/public/assets/icon/guide-maskable.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
docs/.vuepress/public/assets/icon/ms-icon-144.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
docs/.vuepress/public/favicon-bak.ico
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
docs/.vuepress/public/logo-bak.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
1
docs/.vuepress/public/logo-bak.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" class="icon" viewBox="0 0 3280.944 2800"><path fill="#41b883" d="M1645.332 601.004h375.675L1081.82 2238.478 142.636 601.004h718.477l220.708 379.704 216.013-379.704z"/><path fill="#41b883" d="M142.636 601.004l939.185 1637.474 939.186-1637.474h-375.675l-563.51 982.484-568.208-982.484z"/><path fill="#35495e" d="M513.188 601.004l568.207 987.23 563.511-987.23h-347.498l-216.013 379.704-220.708-379.704zM1607.792 1311.83l594.678 2.293 187.353-316.325-598.662 2.292zM2198.506 1909.57C2867.436 732.7 2939.502 605.426 2937.874 603.78c-.715-.723 45.303-1.314 102.262-1.314s103.562.428 103.562.951c0 .523-208.57 367.978-463.491 816.567L2216.715 2235.6l-102.1.596-102.102.596z"/><path fill="#41b883" d="M1680.563 2233.328c0-1.34 168.208-298.145 440.375-777.048a4135645.775 4135645.775 0 00337.619-594.19l146.13-257.25 170.746-.04 170.747-.04-5.536 9.741c-3.044 5.358-43.727 77.302-90.407 159.875-85.356 150.992-337.562 595.163-656.602 1156.373l-172 302.559-170.536.588c-93.795.322-170.536.069-170.536-.567z"/><path fill="#35495e" d="M1429.783 1625.351l594.679 2.292 187.353-316.324-598.662 2.292z"/><path fill="#41b883" d="M1524.207 1464.903l608.285 6.877 173.746-320.909h-619.072z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
1
docs/.vuepress/sidebar/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./zh.js";
|
||||||
23
docs/.vuepress/sidebar/zh.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import {sidebar} from "vuepress-theme-hope";
|
||||||
|
|
||||||
|
export const zhSidebar = sidebar({
|
||||||
|
"/": [
|
||||||
|
{
|
||||||
|
text: '介绍',
|
||||||
|
prefix: 'introduction/',
|
||||||
|
link: 'introduction/',
|
||||||
|
children: 'structure'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "指南",
|
||||||
|
icon: "note",
|
||||||
|
prefix: "guide/",
|
||||||
|
children: "structure",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '更新日志',
|
||||||
|
prefix: 'release/',
|
||||||
|
children: 'structure'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
3
docs/.vuepress/styles/config.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// you can change config here
|
||||||
|
$colors: #c0392b, #d35400, #f39c12, #27ae60, #16a085, #2980b9, #8e44ad, #2c3e50,
|
||||||
|
#7f8c8d !default;
|
||||||
8
docs/.vuepress/styles/index.scss
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// place your custom styles here
|
||||||
|
@media (min-width: 1440px) {
|
||||||
|
.feature-item {
|
||||||
|
flex-basis: calc(33% - 3rem);
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
padding-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
docs/.vuepress/styles/palette.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// you can change colors here
|
||||||
|
$theme-color: #096dd9;
|
||||||
91
docs/.vuepress/theme.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
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",
|
||||||
|
|
||||||
|
repo: "linpeilie/mapstruct",
|
||||||
|
docsDir: 'docs',
|
||||||
|
docsBranch: 'docs',
|
||||||
|
|
||||||
|
locales: {
|
||||||
|
"/": {
|
||||||
|
// navbar
|
||||||
|
navbar: zhNavbar,
|
||||||
|
|
||||||
|
// sidebar
|
||||||
|
sidebar: zhSidebar,
|
||||||
|
|
||||||
|
// footer: "默认页脚",
|
||||||
|
|
||||||
|
displayFooter: true,
|
||||||
|
|
||||||
|
// page meta
|
||||||
|
metaLocales: {
|
||||||
|
editLink: "在 GitHub 上编辑此页",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
91
docs/README.md
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
---
|
||||||
|
home: true
|
||||||
|
icon: home
|
||||||
|
title: 主页
|
||||||
|
heroText: MapstructPlus
|
||||||
|
tagline: 可能是最简单最强大的Java Bean转换工具
|
||||||
|
actions:
|
||||||
|
- text: 快速开始 💡
|
||||||
|
link: /introduction/quick-start/
|
||||||
|
type: primary
|
||||||
|
|
||||||
|
features:
|
||||||
|
- title: 快速
|
||||||
|
icon: launch
|
||||||
|
details: Java 类之间的转换,仅需要增加一个注解,减少了乏味且容易出错的开发任务
|
||||||
|
|
||||||
|
- title: 效率
|
||||||
|
icon: light
|
||||||
|
details: 基于注解处理器,所有生成工作都在编译期完成
|
||||||
|
|
||||||
|
- title: 转换
|
||||||
|
icon: change
|
||||||
|
details: 属性转换基于类中的 getter/setter 方法
|
||||||
|
|
||||||
|
- title: 兼容
|
||||||
|
icon: any
|
||||||
|
details: 支持JDK8~17、SpringBoot2~3
|
||||||
|
|
||||||
|
- title: 多类转换
|
||||||
|
icon: structure
|
||||||
|
details: 支持单个类配置多个类型转换
|
||||||
|
|
||||||
|
- title: Map转对象
|
||||||
|
icon: type
|
||||||
|
details: 更强大的Map转对象功能
|
||||||
|
|
||||||
|
copyright: false
|
||||||
|
---
|
||||||
|
|
||||||
|
## 最新版本
|
||||||
|
|
||||||
|
- maven
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.linpeilie</groupId>
|
||||||
|
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
|
||||||
|
<version>1.1.6</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
- gradle
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.1.6'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 更新日志
|
||||||
|
|
||||||
|
### 1.1.6
|
||||||
|
|
||||||
|
- 支持在添加 `AutoMapper` 的类中,配置目标类到当前类的转换规则,适配多种场景下的使用;
|
||||||
|
- `AutoMapper` 增加注解,提供可以配置是否生成转换接口的功能;
|
||||||
|
- `AutoMapping` 的 `target` 属性默认可以不填,不填则取当前字段
|
||||||
|
- 升级 mapstruct 版本为 1.5.3.FINAL
|
||||||
|
|
||||||
|
……
|
||||||
|
|
||||||
|
## 代码仓库
|
||||||
|
|
||||||
|
- [Github](https://github.com/linpeilie/mapstruct-plus)
|
||||||
|
- [Gitee](https://gitee.com/linpeilie/mapstruct-plus)
|
||||||
|
|
||||||
|
## 参与贡献
|
||||||
|
|
||||||
|
- 贡献代码:欢迎提交 Issue 或 Pull Requests
|
||||||
|
- 维护文档:项目目录下的 docs 目录,欢迎参与翻译与修订
|
||||||
|
|
||||||
|
## 推荐文章
|
||||||
|
|
||||||
|
- [彻底干掉 BeanUtils,最优雅的 Mapstruct 增强工具全新出炉](https://juejin.cn/post/7204307381688909882)
|
||||||
|
|
||||||
|
## 友情链接
|
||||||
|
|
||||||
|
- [RuoYi-Vue-Plus](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages)
|
||||||
|
- [RuoYi-Cloud-Plus](https://gitee.com/JavaLionLi/RuoYi-Cloud-Plus/wikis/pages)
|
||||||
|
|
||||||
|
## 联系我
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
nav: 更新日志
|
|
||||||
title: 简介
|
|
||||||
order: 1
|
|
||||||
---
|
|
||||||
|
|
||||||
# 更新日志
|
|
||||||
|
|
||||||
## **1.1.3**
|
|
||||||
> `2022-02-26`
|
|
||||||
|
|
||||||
- 适配 SpringBoot3
|
|
||||||
|
|
||||||
## 1.1.1
|
|
||||||
> `2022-02-06`
|
|
||||||
|
|
||||||
- 增加 `Map` 转对象的功能
|
|
||||||
- 增加单个类对多类转换的功能
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
---
|
|
||||||
title: 常见问题
|
|
||||||
order: 8
|
|
||||||
---
|
|
||||||
|
|
||||||
# 与 `lombok` 整合
|
|
||||||
|
|
||||||
与 Mapstruct 整合 lombok 的方式一致。
|
|
||||||
|
|
||||||
- lombok 1.18.16 之前:
|
|
||||||
|
|
||||||
```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>
|
|
||||||
```
|
|
||||||
|
|
||||||
- lombok 1.18.16 之后:
|
|
||||||
|
|
||||||
```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>
|
|
||||||
```
|
|
||||||
@ -1,317 +0,0 @@
|
|||||||
---
|
|
||||||
title: 注解
|
|
||||||
order: 5
|
|
||||||
---
|
|
||||||
|
|
||||||
# 注解
|
|
||||||
|
|
||||||
## @AutoMapper
|
|
||||||
|
|
||||||
`@AutoMapper` 定义**标识需要生成类转换接口**
|
|
||||||
需要在实体类上面定义
|
|
||||||
|
|
||||||
### **`target`**
|
|
||||||
|
|
||||||
- 类型:`Class<?>`
|
|
||||||
|
|
||||||
**指定需要转换的目标类**
|
|
||||||
|
|
||||||
**该属性表明会生成被注解的类,转换为目标类的接口**
|
|
||||||
|
|
||||||
示例::
|
|
||||||
如下配置,默认会生成 `Car` 转为 `CarDto` 的逻辑,如果没有配置 `CarDto` 转 `Car`
|
|
||||||
细节的话,还会根据默认的规则,生成相反的转换逻辑。具体细节,参考[转换接口生成约定](/guide/mapper-generate-appoint)
|
|
||||||
|
|
||||||
```java
|
|
||||||
|
|
||||||
@AutoMapper(target = CarDto.class)
|
|
||||||
public class Car {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### `uses`
|
|
||||||
|
|
||||||
- 类型:`Class<?>[]`
|
|
||||||
|
|
||||||
**使用自定义类转换器**
|
|
||||||
|
|
||||||
**该属性可以将自定义映射器,传递给生成的转换接口使用。常用于在进行一些属性转换时,针对一些特定目标类型进行自定义的映射**
|
|
||||||
|
|
||||||
示例场景:
|
|
||||||
|
|
||||||
项目中会有字符串用 `,` 分隔,在一些类中,需要根据逗号拆分为字符串集合。针对于这种场景,可以有两种方式:首先可以指定字段映射时的表达式,但需要对每种该情况的字段,都添加表达式,复杂且容易出错。
|
|
||||||
|
|
||||||
第二,就可以自定义一个类型转换器,通过 `uses` 来使用
|
|
||||||
|
|
||||||
```java
|
|
||||||
public interface StringToListString {
|
|
||||||
default List<String> stringToListString(String str) {
|
|
||||||
return StrUtil.split(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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;
|
|
||||||
// ......
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
测试:
|
|
||||||
|
|
||||||
```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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## @AutoMappers
|
|
||||||
|
|
||||||
`@AutoMappers` 定义标识需要生成多个类的转换接口
|
|
||||||
需要在实体类上面定义
|
|
||||||
当同时需要转换多个类时,不同类之间的属性配置,需要结合 `@AutoMappings` 来使用
|
|
||||||
|
|
||||||
例如,如下配置,同时会生成 `User <---> UserDto` 和 `User <---> UserVO` 之间的映射
|
|
||||||
|
|
||||||
```java
|
|
||||||
@AutoMappers({
|
|
||||||
@AutoMapper(target = UserDto.class),
|
|
||||||
@AutoMapper(target = UserVO.class)
|
|
||||||
})
|
|
||||||
public class User {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## @AutoMapMapper
|
|
||||||
|
|
||||||
`@AutoMapMapper` 标识需要生成 `Map<String, Object>` 转为当前对象的转换接口
|
|
||||||
需要在实体类上定义
|
|
||||||
|
|
||||||
其中,`value` 支持的类型如下:
|
|
||||||
- String
|
|
||||||
- BigDecimal
|
|
||||||
- BigInteger
|
|
||||||
- Integer
|
|
||||||
- Long
|
|
||||||
- Double
|
|
||||||
- Number
|
|
||||||
- Boolean
|
|
||||||
- Date
|
|
||||||
- LocalDateTime
|
|
||||||
- LocalDate
|
|
||||||
- LocalTime
|
|
||||||
- URI
|
|
||||||
- URL
|
|
||||||
- Calendar
|
|
||||||
- Currency
|
|
||||||
- 自定义类(自定义类也需要增加 `@AutoMapMapper` 注解)
|
|
||||||
|
|
||||||
其中,类型的转换,交由 [hutool](https://hutool.cn) 包中的 `Convert` 接口实现,如果要转换的类已经是目标类型,则直接执行强转,否则,根据类型进行一定的适配转换。
|
|
||||||
|
|
||||||
例如:
|
|
||||||
|
|
||||||
定义两个对象,`MapModelA` 和 `MapModelB`:
|
|
||||||
|
|
||||||
- `MapModelA`
|
|
||||||
```java
|
|
||||||
@AutoMapMapper
|
|
||||||
@Data
|
|
||||||
public class MapModelA {
|
|
||||||
|
|
||||||
private String str;
|
|
||||||
private int i1;
|
|
||||||
private Long l2;
|
|
||||||
private MapModelB mapModelB;
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `MapModelB`
|
|
||||||
```java
|
|
||||||
@AutoMapMapper
|
|
||||||
@Data
|
|
||||||
public class MapModelB {
|
|
||||||
|
|
||||||
private Date date;
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
测试:
|
|
||||||
|
|
||||||
```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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## @AutoMapping
|
|
||||||
|
|
||||||
`@AutoMapping` 用于**字段**上面,**配置特定属性映射时的规则**,该注解会在生成时,转换为 Mapstruct 中的 `@Mapping` 注解
|
|
||||||
|
|
||||||
### `targetClass`
|
|
||||||
|
|
||||||
**应用于的目标类**
|
|
||||||
用于多类转换时,区分当前规则,只应用于哪个类型之间的转换。
|
|
||||||
当指定了多个类转换时,如果该注解没有配置 `targetClass`,则当前配置的规则应用于所有的类型转换中。
|
|
||||||
|
|
||||||
例如:
|
|
||||||
```java
|
|
||||||
@AutoMappers({
|
|
||||||
@AutoMapper(target = UserDto.class),
|
|
||||||
@AutoMapper(target = UserVO.class)
|
|
||||||
})
|
|
||||||
public class User {
|
|
||||||
|
|
||||||
@AutoMapping(targetClass = UserDto.class, target = "educations", expression = "java(java.lang.String.join(\",\", source.getEducationList()))")
|
|
||||||
private List<String> educationList;
|
|
||||||
|
|
||||||
@AutoMappings({
|
|
||||||
@AutoMapping(targetClass = UserDto.class, target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss"),
|
|
||||||
@AutoMapping(targetClass = UserVO.class, target = "birthday", ignore = true)
|
|
||||||
})
|
|
||||||
private Date birthday;
|
|
||||||
|
|
||||||
@AutoMapping(target = "money", numberFormat = "$0.00")
|
|
||||||
private double money;
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### `target`
|
|
||||||
|
|
||||||
- 类型:`String`
|
|
||||||
|
|
||||||
**目标字段,指定该注解的配置,应用于目标类中的哪个字段**
|
|
||||||
|
|
||||||
示例:
|
|
||||||
|
|
||||||
```java
|
|
||||||
|
|
||||||
@AutoMapper(target = Goods.class)
|
|
||||||
public class GoodsDto {
|
|
||||||
|
|
||||||
@AutoMapping(target = "price", numberFormat = "$#.00")
|
|
||||||
private int price;
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### dateFormat
|
|
||||||
|
|
||||||
- 类型:`String`
|
|
||||||
|
|
||||||
**在字段映射时,进行时间格式化,应用于 Date 类型转为 String 类型**
|
|
||||||
|
|
||||||
例如:
|
|
||||||
|
|
||||||
```java
|
|
||||||
@AutoMapper(target = Goods.class)
|
|
||||||
public class GoodsDto {
|
|
||||||
|
|
||||||
@AutoMapping(target = "takeDownTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date takeDownTime;
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### numberFormat
|
|
||||||
|
|
||||||
- 类型:`String`
|
|
||||||
|
|
||||||
**在字段映射时,进行数字格式化,应用于数字类型转换为 String 类型,可以指定 `java.text.DecimalFormat` 所支持的格式化字符串**
|
|
||||||
|
|
||||||
例如:
|
|
||||||
|
|
||||||
```java
|
|
||||||
@AutoMapper(target = Goods.class)
|
|
||||||
public class GoodsDto {
|
|
||||||
|
|
||||||
@AutoMapping(target = "price", numberFormat = "$#.00")
|
|
||||||
private int price;
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### expression
|
|
||||||
|
|
||||||
- 类型:`String`
|
|
||||||
|
|
||||||
**类型,这个比较强大,其字符串实际上是一行可执行的 Java 代码,需要写在 `java()` 括号内**
|
|
||||||
|
|
||||||
例如,用该属性,实现前面的列表转字符串:
|
|
||||||
|
|
||||||
```java
|
|
||||||
@AutoMapper(target = UserDto.class)
|
|
||||||
public class User {
|
|
||||||
|
|
||||||
@AutoMapping(target = "educations", expression = "java(java.lang.String.join(\",\", source.getEducationList()))")
|
|
||||||
private List<String> educationList;
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## @AutoMappings
|
|
||||||
|
|
||||||
`@AutoMappings` 定义该字段在不同类之间的转换规则,一般和 `@AutoMappers` 结合使用。
|
|
||||||
|
|
||||||
例如:
|
|
||||||
下面的配置,当 `User` to `UserDto` 时,需要进行时间格式化转换;当 `User` to `UserVO` 时,忽略该字段。
|
|
||||||
|
|
||||||
```java
|
|
||||||
@AutoMappers({
|
|
||||||
@AutoMapper(target = UserDto.class),
|
|
||||||
@AutoMapper(target = UserVO.class)
|
|
||||||
})
|
|
||||||
public class User {
|
|
||||||
|
|
||||||
@AutoMappings({
|
|
||||||
@AutoMapping(targetClass = UserDto.class, target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss"),
|
|
||||||
@AutoMapping(targetClass = UserVO.class, target = "birthday", ignore = true)
|
|
||||||
})
|
|
||||||
private Date birthday;
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
383
docs/guide/class-convert.md
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
---
|
||||||
|
title: 两个类之间的转换
|
||||||
|
icon: creative
|
||||||
|
order: 1
|
||||||
|
category:
|
||||||
|
- 指南
|
||||||
|
description: MapstructPlus两个类之间的转换及配置
|
||||||
|
---
|
||||||
|
|
||||||
|
## 简单转换
|
||||||
|
|
||||||
|
**要实现两个类之间的转换,只需要在其中一个类上增加注解 `@AutoMapper` ,配置 `target` 属性,指定目标类即可**。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@AutoMapper(target = CarDto.class)
|
||||||
|
public class Car {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
该例子表示,会生成 `Car` 转换为 `CarDto` 的接口 `CarToCarDtoMapper` 及实现类 `CarToCarDtoMapperImpl`。在生成的转换代码中,源类型(`Car`)的所有可读属性将被复制到目标属性类型(`CarDto`)的相应属性中。
|
||||||
|
|
||||||
|
当一个属性与它的目标实体对应物具有相同的名称时,将会被隐式映射。
|
||||||
|
|
||||||
|
除此之外,MapstructPlus 会根据当前的默认规则,生成 `CarDto` 转换为 `Car` 的接口 `CarDtoToCarMapper` 及实现类 `CarDtoToCarMapperImpl`。如果不想生成该转换逻辑的话,可以通过注解的 `reverseConvertGenerate` 属性来配置。
|
||||||
|
|
||||||
|
## 自定义对象的属性自动转换
|
||||||
|
|
||||||
|
当要转换的类中,存在自定义类时,会自动寻找该类型的转换方法。
|
||||||
|
|
||||||
|
例如,分别有两组对象模型:汽车(`Car`)和座椅(`SeatConfiguration`),其中 `Car` 依赖于 `SeatConfiguration`。
|
||||||
|
|
||||||
|
分别对应对象如下:
|
||||||
|
|
||||||
|
- 汽车模型
|
||||||
|
|
||||||
|
::: code-tabs#java
|
||||||
|
|
||||||
|
@tab Car
|
||||||
|
|
||||||
|
```java
|
||||||
|
@AutoMapper(target = CarDto.class)
|
||||||
|
@Data
|
||||||
|
public class Car {
|
||||||
|
private SeatConfiguration seatConfiguration;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
@tab CarDto
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
public class CarDto {
|
||||||
|
private SeatConfigurationDto seatConfiguration;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
- 座椅模型
|
||||||
|
|
||||||
|
::: code-tabs#java
|
||||||
|
|
||||||
|
@tab SeatConfiguration
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
@AutoMapper(target = SeatConfigurationDto.class)
|
||||||
|
public class SeatConfiguration {
|
||||||
|
// fields
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
@tab SeatConfigurationDto
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
public class SeatConfigurationDto {
|
||||||
|
// fields
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
在上面的例子中,首先会生成 `CarToCarDtoMapper` 和 `SeatConfigurationToSeatConfigurationDtoMapper` 两个转换接口,并且在转换 `Car` 时,会自动使用 `SeatConfigurationToSeatConfigurationDtoMapper` 来对其中的座椅属性来进行转换。
|
||||||
|
|
||||||
|
## 引入自定义类型转换器
|
||||||
|
|
||||||
|
当不同类型的属性,想要按照自定义的规则进行转换时,可以有两种办法:
|
||||||
|
|
||||||
|
1. 通过 `@AutoMapping` 中配置的 `expression` 表达式配置
|
||||||
|
2. 自定义一个类型转换器,通过 `@AutoMapper` 的 `uses` 属性来引入
|
||||||
|
|
||||||
|
方式一可以参考下面的[表达式](#表达式)章节。
|
||||||
|
|
||||||
|
这里基于方式二,实现将 `String` 类型的属性,根据逗号分隔,转换为 `List<String>` 类型的属性:
|
||||||
|
|
||||||
|
首先,定义一个类型转换器 —— `StringToListString`:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Component
|
||||||
|
public class StringToListString {
|
||||||
|
public List<String> stringToListString(String str) {
|
||||||
|
return StrUtil.split(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
- 类型转换器提供的类型转换方法,可以定义为 `static` 或 `nonstatic`的。
|
||||||
|
- 如果是基于 `SpringBoot` 的方式使用该框架,则类型转换器需要定义为 Spring 的一个 Bean。
|
||||||
|
:::
|
||||||
|
|
||||||
|
下一步,使用该类型转换器:
|
||||||
|
|
||||||
|
```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;
|
||||||
|
// ......
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
测试:
|
||||||
|
|
||||||
|
```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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 自定义属性转换
|
||||||
|
|
||||||
|
当两个类中属性存在不一致的场景时,例如名称、类型等不一致,可以进行自定义转换,通过在属性上面添加 `@AutoMapping`,来配置映射规则。
|
||||||
|
|
||||||
|
### 不同属性名称映射
|
||||||
|
|
||||||
|
`@AutoMapping` 注解中,提供了 `target` 属性,可以配置当前属性与目标类中 `target` 属性之间映射。
|
||||||
|
|
||||||
|
例如,`Car` 转换为 `CatDto` 时,`seatConfiguration` 属性与 `seat` 属性相对应:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@AutoMapper(target = CarDto.class)
|
||||||
|
@Data
|
||||||
|
public class Car {
|
||||||
|
@AutoMapping(target = "seat")
|
||||||
|
private SeatConfiguration seatConfiguration;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`@AutoMapping` 注解中还提供 `source` 方法,该配置默认取当前属性的名称,之所以可以配置,是为了适应一种场景,当前类的某个属性,其内部的属性,转换为目标中的属性字段,则可以通过当前属性来配置。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
::: code-tabs#java
|
||||||
|
|
||||||
|
@tab Goods
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
@AutoMapper(target = GoodsVo.class, reverseConvertGenerate = false)
|
||||||
|
public class Goods {
|
||||||
|
|
||||||
|
@AutoMapping(source = "sku.price", target = "price")
|
||||||
|
private Sku sku;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
@tab GoodsVo
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
public class GoodsVo {
|
||||||
|
|
||||||
|
private Integer price;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 指定时间格式转换
|
||||||
|
|
||||||
|
当时间类型(例如:`Date`、`LocalDateTime`、`LocalDate` 等等)需要和 `String` 通过指定时间格式进行转换时,可以通过 `@AutoMapping` 中的 `dateFormat` 来配置:
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
::: code-tabs#java
|
||||||
|
|
||||||
|
@tab 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
@tab 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 指定数字格式转换
|
||||||
|
|
||||||
|
当数字类型(例如:`int`/`Integer` 等数字基本类型及包装类、`BigDecimal`)和 `String` 之间的转换需要指定数字格式,可以通过 `@AutoMapping` 的 `numberFormat` 来配置。
|
||||||
|
|
||||||
|
> 该格式需要 `java.text.DecimalFormat` 所支持
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
::: code-tabs#java
|
||||||
|
|
||||||
|
@tab Order
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
@AutoMapper(target = OrderEntity.class)
|
||||||
|
public class Order {
|
||||||
|
|
||||||
|
@AutoMapping(numberFormat = "$0.00")
|
||||||
|
private BigDecimal orderPrice;
|
||||||
|
|
||||||
|
@AutoMapping(numberFormat = "$0.00")
|
||||||
|
private Integer goodsNum;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
@tab OrderEntity
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
@AutoMapper(target = Order.class)
|
||||||
|
public class OrderEntity {
|
||||||
|
|
||||||
|
@AutoMapping(numberFormat = "$0.00")
|
||||||
|
private String orderPrice;
|
||||||
|
|
||||||
|
@AutoMapping(numberFormat = "$0.00")
|
||||||
|
private String goodsNum;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
### 忽略指定属性的转换
|
||||||
|
|
||||||
|
当在进行转换时,需要忽略指定属性的转换,可以通过 `@AutoMapping` 的 `ignore` 来配置。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@AutoMapper(target = CarDto.class)
|
||||||
|
@Data
|
||||||
|
public class Car {
|
||||||
|
|
||||||
|
@AutoMapping(target = "wheels", ignore = true)
|
||||||
|
private Wheels wheels;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 属性转换时的默认值
|
||||||
|
|
||||||
|
`@AutoMapping` 中的 `defaultValue` 可以指定在转换属性时,当属性为 `null` 时,转换到目标类中的默认值。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```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;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 表达式
|
||||||
|
|
||||||
|
在执行属性转换时,可以通过指定执行一段 Java 代码来进行转换操作,例如,对源对象中的某个属性进行转换后返回。
|
||||||
|
|
||||||
|
需要注意的是,在生成时,会直接将表达式插入到转换逻辑中,并不会验证其语法。
|
||||||
|
|
||||||
|
例如,将源对象中的 `List<String>` 属性,通过 `,` 拼接为字符串:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@AutoMapper(target = UserDto.class)
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@AutoMapping(target = "educations", expression = "java(java.lang.String.join(\",\", source.getEducationList()))")
|
||||||
|
private List<String> educationList;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 反向属性映射配置
|
||||||
|
|
||||||
|
::: info
|
||||||
|
**在该文中,所有提到的源类指通过 `@AutoMapper` 注解的类;目标类指的是 `@AutoMapper` 中 `target` 属性指定的类型。**
|
||||||
|
:::
|
||||||
|
|
||||||
|
前面提到,当在一个类上面添加 `@AutoMapper` 注解时,默认情况下,除了会生成源类到目标类的转换接口,还会生成目标类到源类的转换接口和实现类,这里需要注意的是,默认情况下生成的该转换接口,并没有任何自定义配置,即使在源类中配置了 `@AutoMapping` 注解。
|
||||||
|
|
||||||
|
这里要实现目标类到源类的自定义转换配置,可以有两种方式:
|
||||||
|
|
||||||
|
1. 在目标类上面添加 `@AutoMapper` 注解。这是最建议的方式,当转换双方都有添加该注解时,便不会生成默认的转换接口,即按照自定义的规则进行生成。
|
||||||
|
2. 当目标类访问不到源类,或者项目规范不允许在目标类上面添加该种注解时,可以将自定义配置全部添加在源类中。这就是下面要介绍的**反向属性映射配置**。
|
||||||
|
|
||||||
|
框架中提供了 `@ReverseAutoMapping` 注解,该注解就是为了配置目标类到源类的自定义转换规则。
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
这里需要注意的是,防止配置冲突,一旦添加 `@ReverseAutoMapping` 注解,在目标类中,便不能添加任何自定义转换注解
|
||||||
|
:::
|
||||||
|
|
||||||
|
**`@ReverseAutoMapping` 注解表示的含义,是目标类到源类转换时,需要指定的自定义转换规则,其中可以配置的属性,与 `@AutoMapping` 注解一致。**
|
||||||
|
|
||||||
|
这里有两个属性需要注意,分别是 `source` 和 `target`。
|
||||||
|
|
||||||
|
**这里的 `source` 指的是目标类中的属性,`target` 指的是源类中的属性。**
|
||||||
|
|
||||||
|
可能会有人这里有疑问,为什么这里的配置像是反的?如果没有,可以直接跳过。
|
||||||
|
|
||||||
|
框架设计的时候,所有的属性转换配置,都是基于要转换的类型,该类转换为目标类,想要应用的效果。这里的 `source` 也应该是来源类中的属性。
|
||||||
|
|
||||||
|
如果还是不理解,这里可以认为,该注解就是本该应用在目标类中的 `@AutoMapping` 注解,原封不动拷贝到当前类,再修改注解名称即可。
|
||||||
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
title: 配置
|
|
||||||
order: 4
|
|
||||||
---
|
|
||||||
|
|
||||||
# 配置
|
|
||||||
|
|
||||||
由于 Mapstruct Plus 是注解处理器,主要工作是在编译阶段完成的,只能通过注解的方式,来进行项目配置。
|
|
||||||
|
|
||||||
且需要注意的是,**所有的配置类,都必须与需要进行对象转换的类,在同一个模块包中,且只能定义一个**。
|
|
||||||
|
|
||||||
目前提供了两个配置类:
|
|
||||||
|
|
||||||
- `ComponentModelConfig`
|
|
||||||
- `MapperConfig`
|
|
||||||
|
|
||||||
## ComponentModelConfig
|
|
||||||
|
|
||||||
`ComponentModelConfig` **定义获取 Mapper 接口对象的注入方式**,只有一个属性 `componentModel`。
|
|
||||||
可以在与要转换对象同模块包下的任意类或者接口上使用。
|
|
||||||
|
|
||||||
目前 Mapstruct plus 中支持两种:`default` 和 `spring`。
|
|
||||||
|
|
||||||
当使用非 Spring 模式时,必须定义该配置,`componentModel=default`。
|
|
||||||
|
|
||||||
## MapperConfig
|
|
||||||
|
|
||||||
`MapperConfig` 注解定义 **Mapper 接口生成的规则**,目前只支持配置生成接口的包名
|
|
||||||
可以在与要转换对象同模块包下的任意类或接口上使用。
|
|
||||||
|
|
||||||
### mapperPackage
|
|
||||||
|
|
||||||
指定生成的 Mapper 包名。
|
|
||||||
|
|
||||||
当没有指定该目录时,会在指定 `AutoMapper` 注解的类同级目录下,生成 Mapper 接口
|
|
||||||
@ -1,25 +1,30 @@
|
|||||||
---
|
---
|
||||||
title: 类型转换API
|
title: 类转换 API
|
||||||
order: 6
|
icon: creative
|
||||||
|
order: 4
|
||||||
|
category:
|
||||||
|
- 指南
|
||||||
|
description: Mapstruct Converter接口API
|
||||||
---
|
---
|
||||||
|
|
||||||
# 类型转换 API
|
## Converter
|
||||||
|
|
||||||
在 Mapstruct Plus 中,类型转换对外提供了一个接口:`Converter`
|
前面的章节,都是介绍,在实体类上面配置转换逻辑,它们主要应用在编译阶段。在实际应用时,框架提供了 `Converter` 类,来执行具体的转换逻辑。
|
||||||
|
|
||||||
> `Converter` 类实际根据源类型和目标类型,寻找相应的 `Mapper` 接口,然后交由 `Mapper` 接口来转换。
|
针对类型转换该类提供了如下方法:
|
||||||
> 其内部做了缓存处理,所以,建议全局只定义一个 `Converter` 对象。
|
|
||||||
|
|
||||||
其中提供了三个方法:
|
- **`<S, T> T convert(S source, Class<T> targetType)`**
|
||||||
|
|
||||||
- `T convert(S source, Class<T> targetType)`
|
传入需要转换的对象(`source`)与目标类型(`targetType`),最终返回目标类型的实例对象。
|
||||||
将 `S` 类型的对象,转换为 `targetType` 类型的对象并返回
|
|
||||||
|
|
||||||
- `T convert(S source, T target)`
|
- **`<S, T> T convert(S source, T target)`**
|
||||||
将 `S` 类型的对象,按照配置的映射字段规则,给 `target` 类型的对象赋值,并返回 `target` 对象
|
|
||||||
|
|
||||||
- `List<T> convert(List<S> source, Class<T> targetType)`
|
传入需要转换对象(`source`)与目标对象(`target`),最终将 `source` 中的属性,转换到 `target` 对象中,该方法与上面的区别在于,该方法返回的是传入的 `target` 对象,上面的方法返回的是一个新的对象。
|
||||||
将 `S` 类型的集合,转换为 `targetType` 类型的集合并返回
|
|
||||||
|
|
||||||
- `<T> T convert(Map<String, Object> map, Class<T> target)`
|
- **`<S, T> List<T> convert(List<S> source, Class<T> targetType)`**
|
||||||
将 `Map<String, Object>` 转换为 `target` 类型的集合并返回
|
|
||||||
|
该方法会将一个源类型(`source`)的集合转换为目标类型(`targetType`)的集合
|
||||||
|
|
||||||
|
- **`<T> T convert(Map<String, Object> map, Class<T> target)`**
|
||||||
|
|
||||||
|
该方法会将一个 `Map<String, Object>` 转换为目标类型的实例对象。
|
||||||
79
docs/guide/faq.md
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
title: 常见问题
|
||||||
|
icon: creative
|
||||||
|
order: 5
|
||||||
|
category:
|
||||||
|
- 指南
|
||||||
|
description: MapstructPlus常见问题
|
||||||
|
---
|
||||||
|
|
||||||
|
## 与 `lombok` 整合
|
||||||
|
|
||||||
|
与 Mapstruct 整合 lombok 的方式一致。
|
||||||
|
|
||||||
|
### lombok 1.18.16 之前:
|
||||||
|
|
||||||
|
```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>
|
||||||
|
```
|
||||||
|
|
||||||
|
### lombok 1.18.16 及以后:
|
||||||
|
|
||||||
|
```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>
|
||||||
|
```
|
||||||
101
docs/guide/map-to-class.md
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
---
|
||||||
|
title: Map 转对象
|
||||||
|
icon: creative
|
||||||
|
order: 2
|
||||||
|
category:
|
||||||
|
- 指南
|
||||||
|
description: MapstructPlus Map转为对象
|
||||||
|
---
|
||||||
|
|
||||||
|
MapstructPlus 提供了更加强大的 `Map<String, Object>` 转对象的功能。
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
|
||||||
|
**当想要自动生成 `Map<String, Object>` 转为目标类的接口及实现类时,只需要在目标类上添加 `@AutoMapMapper` 注解**。
|
||||||
|
|
||||||
|
## 支持的 value 类型
|
||||||
|
|
||||||
|
- `String`
|
||||||
|
- `BigDecimal`
|
||||||
|
- `BigInteger`
|
||||||
|
- `Integer`
|
||||||
|
- `Long`
|
||||||
|
- `Double`
|
||||||
|
- `Boolean`
|
||||||
|
- `Date`
|
||||||
|
- `LocalDateTime`
|
||||||
|
- `LocalDate`
|
||||||
|
- `LocalTime`
|
||||||
|
- `URI`
|
||||||
|
- `URL`
|
||||||
|
- `Calendar`
|
||||||
|
- `Currency`
|
||||||
|
- `自定义类(自定义类也需要增加 @AutoMapMapper 注解)`
|
||||||
|
|
||||||
|
## 转换逻辑
|
||||||
|
|
||||||
|
**针对目标类中的一个属性,首先会判断 `Map` 中是否存在该键,如果存在的话,首先判断类型,如果相同类型,直接强转,如果不同类型,则会基于 [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) 提供的类型转换工具尝试转换为目标类型**。
|
||||||
|
|
||||||
|
**且同时支持内部嵌套 `Map<String, Object>` 属性转为内部嵌套的自定义类型属性**。
|
||||||
|
|
||||||
|
## 示例
|
||||||
|
|
||||||
|
- 定义两个对象:`MapModelA` 和 `MapModelB`
|
||||||
|
|
||||||
|
::: code-tabs#java
|
||||||
|
|
||||||
|
@tab MapModelA
|
||||||
|
|
||||||
|
```java
|
||||||
|
@AutoMapMapper
|
||||||
|
@Data
|
||||||
|
public class MapModelA {
|
||||||
|
|
||||||
|
private String str;
|
||||||
|
private int i1;
|
||||||
|
private Long l2;
|
||||||
|
private MapModelB mapModelB;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
@tab MapModelB
|
||||||
|
|
||||||
|
```java
|
||||||
|
@AutoMapMapper
|
||||||
|
@Data
|
||||||
|
public class MapModelB {
|
||||||
|
|
||||||
|
private Date date;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
- 转换测试
|
||||||
|
|
||||||
|
```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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
@ -1,84 +0,0 @@
|
|||||||
---
|
|
||||||
title: Mapper 接口生成约定
|
|
||||||
order: 7
|
|
||||||
---
|
|
||||||
|
|
||||||
# Mapper 接口生成约定
|
|
||||||
|
|
||||||
## Mapper 接口包名
|
|
||||||
|
|
||||||
`Mapper` 接口包名按照如下规则获取:
|
|
||||||
|
|
||||||
1. 转换对象所在模块中,配置的 `@sMapperConfig` 中指定的 `mapperPackage` 属性
|
|
||||||
2. 如果没有指定,则会取 `@AutoMapper` 类的包名
|
|
||||||
|
|
||||||
## Mapper 接口命名
|
|
||||||
|
|
||||||
`Mapper` 接口命名规则如下:`源类名` + `To` + `目标类名` + `Mapper`
|
|
||||||
|
|
||||||
例如,在 `User` 类上指定 `@AutoMapper(target = UserDto.class)`,则生成的 `Mapper` 接口类名为:`UserToUserDtoMapper`
|
|
||||||
|
|
||||||
## 自动生成相反类型转换及 `@AutoMapping` 继承
|
|
||||||
|
|
||||||
假如,在 `User` 类上指定 `@AutoMapper(target = UserDto.class)`,同时如果没有在 `UserDto` 上标注 `@AutoMapper(target = User.class)` 的话,除了会生成 `UserToUserDtoMapper` 接口,默认也会生成 `UserDtoToUserMapper` 接口。
|
|
||||||
|
|
||||||
即,**同时会生成两个类的相互转换接口**。所以[快速开始](/guide/quick_start)中才可以由 `UserDto` 转为 `User` 对象。
|
|
||||||
|
|
||||||
但是,具体属性上面的 `@AutoMapping` 注解,不能够完全继承。
|
|
||||||
|
|
||||||
例如,`User` 中的 `Date` 类型的属性,在 `@AutoMapping` 中指定了 `dateFormat` 时间格式,当反过来时,却不能这样子用,因为 `dateFormat` 只能应用于 String 类型。
|
|
||||||
|
|
||||||
由于这个原因,默认情况下生成反向转换 `Mapper`,`@AutoMapping` 的部分属性是不能够继承的。
|
|
||||||
|
|
||||||
目前,反向转换 `Mapper` 中,支持继承的 `@AutoMapping` 属性有如下:
|
|
||||||
|
|
||||||
- `target`:目标属性为当前源对象的标注 `@AutoMapping` 的属性
|
|
||||||
- `ignore`:忽略当前属性的转换
|
|
||||||
|
|
||||||
例如:
|
|
||||||
|
|
||||||
定义 `User` 类如下:
|
|
||||||
|
|
||||||
```java
|
|
||||||
@AutoMapper(target = UserDto.class)
|
|
||||||
public class User {
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
private int age;
|
|
||||||
private boolean young;
|
|
||||||
|
|
||||||
@AutoMapping(target = "educations", ignore = true)
|
|
||||||
private List<String> educationList;
|
|
||||||
|
|
||||||
@AutoMapping(target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date birthday;
|
|
||||||
|
|
||||||
@AutoMapping(target = "assets", numberFormat = "$0.00")
|
|
||||||
private double assets;
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
当在 `User` 类上没有定义 `@AutoMapper` 注解时,会按照默认规则进行生成。
|
|
||||||
|
|
||||||
相当于:
|
|
||||||
|
|
||||||
```java
|
|
||||||
@AutoMapper(target = User.class)
|
|
||||||
public class UserDto {
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
private int age;
|
|
||||||
private boolean young;
|
|
||||||
|
|
||||||
@AutoMapping(target = "educationList", ignore = true)
|
|
||||||
private List<String> educations;
|
|
||||||
|
|
||||||
@AutoMapping(target = "birthday")
|
|
||||||
private Date birthday;
|
|
||||||
|
|
||||||
@AutoMapping(target = "assets")
|
|
||||||
private double assets;
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
73
docs/guide/multiple-class-convert.md
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
title: 一个类与多个类之间转换
|
||||||
|
icon: creative
|
||||||
|
order: 3
|
||||||
|
category:
|
||||||
|
- 指南
|
||||||
|
description: MapstructPlus一个类与多个类之间转换
|
||||||
|
---
|
||||||
|
|
||||||
|
MapstructPlus 除了支持一个类与单个目标类型进行转换,还支持一个类与多个目标类型进行转换。
|
||||||
|
|
||||||
|
## 配置多个类转换
|
||||||
|
|
||||||
|
当想要配置一个类与多个类进行转换时,可以通过 `@AutoMappers` 来配置,该注解支持配置多个 `@AutoMapper`
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
@AutoMappers({
|
||||||
|
@AutoMapper(target = UserDto.class),
|
||||||
|
@AutoMapper(target = UserVO.class)
|
||||||
|
})
|
||||||
|
public class User {
|
||||||
|
// fields
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置指定类转换的规则
|
||||||
|
|
||||||
|
当配置多个类转换时,可能会有不同的类,同一属性转换规则不同的场景。
|
||||||
|
|
||||||
|
针对这个问题,首先可以使用 `@AutoMappings` 指定多个转换规则,并且在使用 `@AutoMapping` 注解时,配置 `targetClass` 属性,指定当前规则的应用目标转换类。
|
||||||
|
|
||||||
|
如果在配置 `@AutoMapping` 注解时,没有指定 `targetClass` 时,则当前规则,会应用于与所有类转换。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```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;
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
title: A static site based on dumi
|
|
||||||
hero:
|
|
||||||
title: mapstruct plus
|
|
||||||
description: 简单、强大的 Java Bean 转换工具
|
|
||||||
actions:
|
|
||||||
- text: 快速开始
|
|
||||||
link: /guide/quick-start
|
|
||||||
features:
|
|
||||||
- title: 快速开发
|
|
||||||
emoji: 🚀
|
|
||||||
description: Java 实体类之间的转换,仅需要一个注解,减少了乏味且容易出错的开发任务
|
|
||||||
- title: 效率
|
|
||||||
emoji: 🌈
|
|
||||||
description: 基于注解处理器,所有生成工作在编译阶段完成;生成的代码基于原有 getter/setter 方法,不会影响原有性能
|
|
||||||
- title: 目标
|
|
||||||
emoji: 💡
|
|
||||||
description: 做最简单、最强大的类转换工具
|
|
||||||
---
|
|
||||||
@ -1,11 +1,14 @@
|
|||||||
---
|
---
|
||||||
nav: 指南
|
|
||||||
title: 简介
|
title: 简介
|
||||||
order: -1
|
icon: creative
|
||||||
|
order: 1
|
||||||
|
category:
|
||||||
|
- 介绍
|
||||||
|
tag:
|
||||||
|
- 简介
|
||||||
|
description: MapstructPlus简介,MapstructPlus是什么
|
||||||
---
|
---
|
||||||
|
|
||||||
# 简介
|
|
||||||
|
|
||||||
> 首先,先了解一下 Mapstruct:
|
> 首先,先了解一下 Mapstruct:
|
||||||
> [Mapstruct](https://mapstruct.org) 是一个代码生成器,通过定义类转换的接口,自动实现属性转换的具体逻辑。主要为了简化 Java 类型之间转换的实现。
|
> [Mapstruct](https://mapstruct.org) 是一个代码生成器,通过定义类转换的接口,自动实现属性转换的具体逻辑。主要为了简化 Java 类型之间转换的实现。
|
||||||
|
|
||||||
@ -15,13 +18,12 @@ Mapstruct Plus 是 Mapstruct 的增强工具,在 Mapstruct 的基础上,实
|
|||||||
|
|
||||||
Mapstruct Plus 内嵌 Mapstruct,和 Mapstruct 完全兼容,如果之前已经使用 Mapstruct,可以无缝替换依赖。
|
Mapstruct Plus 内嵌 Mapstruct,和 Mapstruct 完全兼容,如果之前已经使用 Mapstruct,可以无缝替换依赖。
|
||||||
|
|
||||||
# 代码托管
|
## 代码托管
|
||||||
|
|
||||||
- [Gitee](https://gitee.com/linpeilie/mapstruct-plus)
|
- [Gitee](https://gitee.com/linpeilie/mapstruct-plus)
|
||||||
- [Github](https://github.com/linpeilie/mapstruct-plus)
|
- [Github](https://github.com/linpeilie/mapstruct-plus)
|
||||||
|
|
||||||
# 联系我
|
## 参与贡献
|
||||||
|
|
||||||
> vx : Clue8a796d01
|
- 贡献代码:欢迎提交 Issue 或 Pull Requests
|
||||||
|
- 维护文档:项目目录下的 docs 目录,欢迎参与翻译与修订
|
||||||
<img src="https://raw.githubusercontent.com/linpeilie/mapstruct-plus/main/assets/contact-me.jpeg" alt="联系我" width="364" height="497" />
|
|
||||||
@ -1,13 +1,17 @@
|
|||||||
---
|
---
|
||||||
title: 安装
|
title: 安装
|
||||||
order: 3
|
icon: creative
|
||||||
|
order: 2
|
||||||
|
category:
|
||||||
|
- 介绍
|
||||||
|
tag:
|
||||||
|
- 安装
|
||||||
|
description: MapstructPlus依赖安装
|
||||||
---
|
---
|
||||||
|
|
||||||
|
::: warning
|
||||||
# 安装
|
|
||||||
|
|
||||||
由于其已经内嵌 Mapstruct,为了防止不同版本之间的差异,请不要再引入 Mapstruct 相关依赖
|
由于其已经内嵌 Mapstruct,为了防止不同版本之间的差异,请不要再引入 Mapstruct 相关依赖
|
||||||
|
:::
|
||||||
|
|
||||||
## 非 SpringBoot 环境
|
## 非 SpringBoot 环境
|
||||||
|
|
||||||
@ -15,7 +19,7 @@ order: 3
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<properties>
|
<properties>
|
||||||
<mapstruct-plus.version>1.1.3</mapstruct-plus.version>
|
<mapstruct-plus.version>最新版本</mapstruct-plus.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -31,8 +35,8 @@ order: 3
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>1.8</source> <!-- 这里根据自己的需要进行切换 -->
|
||||||
<target>1.8</target>
|
<target>1.8</target> <!-- 这里根据自己的需要进行切换 -->
|
||||||
<annotationProcessorPaths>
|
<annotationProcessorPaths>
|
||||||
<path>
|
<path>
|
||||||
<groupId>io.github.linpeilie</groupId>
|
<groupId>io.github.linpeilie</groupId>
|
||||||
@ -50,9 +54,9 @@ order: 3
|
|||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'io.github.linpeilie:mapstruct-plus:1.1.3'
|
implementation 'io.github.linpeilie:mapstruct-plus:最新版本'
|
||||||
|
|
||||||
annotationProcessor 'io.github.linpeilie:mapstruct-plus-processor:1.1.3'
|
annotationProcessor 'io.github.linpeilie:mapstruct-plus-processor:最新版本'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -62,7 +66,7 @@ dependencies {
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<properties>
|
<properties>
|
||||||
<mapstruct-plus.version>1.1.3</mapstruct-plus.version>
|
<mapstruct-plus.version>最新版本</mapstruct-plus.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -78,8 +82,8 @@ dependencies {
|
|||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>1.8</source> <!-- 这里根据自己的需要进行切换 -->
|
||||||
<target>1.8</target>
|
<target>1.8</target> <!-- 这里根据自己的需要进行切换 -->
|
||||||
<annotationProcessorPaths>
|
<annotationProcessorPaths>
|
||||||
<path>
|
<path>
|
||||||
<groupId>io.github.linpeilie</groupId>
|
<groupId>io.github.linpeilie</groupId>
|
||||||
@ -97,8 +101,8 @@ dependencies {
|
|||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'io.github.linpeilie:mapstruct-plus-spring-boot-starter:1.1.3'
|
implementation 'io.github.linpeilie:mapstruct-plus-spring-boot-starter:最新版本'
|
||||||
|
|
||||||
annotationProcessor 'io.github.linpeilie:mapstruct-plus-processor:1.1.3'
|
annotationProcessor 'io.github.linpeilie:mapstruct-plus-processor:最新版本'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -1,10 +1,14 @@
|
|||||||
---
|
---
|
||||||
title: 快速开始
|
title: 快速开始
|
||||||
order: 2
|
icon: creative
|
||||||
|
order: 3
|
||||||
|
category:
|
||||||
|
- 介绍
|
||||||
|
tag:
|
||||||
|
- 快速开始
|
||||||
|
description: MapstructPlus快速开始教程
|
||||||
---
|
---
|
||||||
|
|
||||||
# 快速开始
|
|
||||||
|
|
||||||
下面演示如何使用 MapStruct Plus 来映射两个对象。
|
下面演示如何使用 MapStruct Plus 来映射两个对象。
|
||||||
|
|
||||||
假设有两个类 `UserDto` 和 `User`,分别表示数据层对象和业务层对象:
|
假设有两个类 `UserDto` 和 `User`,分别表示数据层对象和业务层对象:
|
||||||
@ -41,7 +45,7 @@ public class User {
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<properties>
|
<properties>
|
||||||
<mapstruct-plus.version>1.1.3</mapstruct-plus.version>
|
<mapstruct-plus.version>最新版本</mapstruct-plus.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -137,7 +141,7 @@ public class QuickStart {
|
|||||||
|
|
||||||
```xml
|
```xml
|
||||||
<properties>
|
<properties>
|
||||||
<mapstruct-plus.version>1.1.3</mapstruct-plus.version>
|
<mapstruct-plus.version>最新版本</mapstruct-plus.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
32
docs/release/log.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
title: 更新日志
|
||||||
|
icon: creative
|
||||||
|
order: 1
|
||||||
|
category:
|
||||||
|
- 更新日志
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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 转对象的功能
|
||||||
|
- 增加单个对象与多个对象转换并配置的功能
|
||||||
31
package.json
@ -1,22 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "mapstruct-plus",
|
"name": "mapstruct-plus",
|
||||||
"version": "0.0.1",
|
"version": "2.0.0",
|
||||||
"description": "mapstruct-plus document",
|
"description": "mapstruct-plus-document",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "dumi build",
|
"dev": "vuepress dev docs",
|
||||||
"predeploy": "cp CNAME ./dist",
|
"build": "vuepress build docs",
|
||||||
"deploy": "gh-pages -d dist",
|
"docs:build": "vuepress build docs",
|
||||||
"dev": "dumi dev",
|
"docs:clean-dev": "vuepress dev docs --clean-cache",
|
||||||
"prepare": "dumi setup",
|
"docs:dev": "vuepress dev docs",
|
||||||
"start": "npm run dev"
|
"docs:update-package": "npx vp-update"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dumi": "^2.0.2",
|
"@vuepress/client": "2.0.0-beta.61",
|
||||||
"dumi-theme-antd-style": "^0.10.5",
|
"@vuepress/plugin-search": "^2.0.0-beta.61",
|
||||||
"gh-pages": "^5.0.0"
|
"@vuepress/plugin-shiki": "^2.0.0-beta.61",
|
||||||
},
|
"vue": "^3.2.47",
|
||||||
"authors": [
|
"vuepress": "2.0.0-beta.61",
|
||||||
"linpeilie@qq.com"
|
"vuepress-theme-hope": "2.0.0-beta.185"
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"strict": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"baseUrl": "./",
|
|
||||||
"paths": {
|
|
||||||
"@@/*": [".dumi/tmp/*"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"include": [".dumi/**/*", ".dumirc.ts"]
|
|
||||||
}
|
|
||||||