学习目标
通过本篇教程,你将学会:
- 搭建 Atlas Mapper 开发环境
- 创建第一个 Atlas Mapper 项目
- 配置 Maven 构建和注解处理器
- 验证环境配置是否正确
概念讲解:开发环境要求
技术栈要求
Atlas Mapper 基于以下技术栈开发:
graph TB
subgraph "基础环境"
A1[JDK 8+] --> A2[Maven 3.6+]
A2 --> A3[IDE支持]
end
subgraph "Spring 技术栈"
B1[Spring Framework 5.2+] --> B2[Spring Boot 2.2+]
end
subgraph "开发工具"
C1[IntelliJ IDEA] --> C2[Eclipse]
C2 --> C3[VS Code]
end
A3 --> B1
B2 --> C1
style A1 fill:#e8f5e8
style B1 fill:#e3f2fd
style C1 fill:#fff3e0
环境检查清单
| 组件 | 最低版本 | 推荐版本 | 检查命令 |
|---|---|---|---|
| JDK | 1.8 | 1.8.0_271+ | java -version |
| Maven | 3.6.0 | 3.8.0+ | mvn -version |
| IDE | - | IntelliJ IDEA 2020+ | - |
实现步骤:环境搭建详细指南
步骤 1:验证 Java 环境
# 检查 Java 版本
java -version
# 期望输出类似:
# java version "1.8.0_271"
# Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
# Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)
# 检查 JAVA_HOME 环境变量
echo $JAVA_HOME
# 期望输出:/usr/lib/jvm/java-8-openjdk-amd64 (Linux)
# 或:C:Program FilesJavajdk1.8.0_271 (Windows)
步骤 2:验证 Maven 环境
# 检查 Maven 版本
mvn -version
# 期望输出类似:
# Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)
# Maven home: /usr/share/maven
# Java version: 1.8.0_271, vendor: Private Build
# Java home: /usr/lib/jvm/java-8-openjdk-amd64/jre
步骤 3:创建 Spring Boot 项目
方式一:使用 Spring Initializr(推荐)
- 访问 start.spring.io/
- 配置项目参数:
项目配置:
Project: Maven Project
Language: Java
Spring Boot: 2.2.13
项目元数据:
Group: com.example
Artifact: atlas-mapper-demo
Name: atlas-mapper-demo
Description: Atlas Mapper Demo Project
Package name: com.example.atlasmapperdemo
Packaging: Jar
Java: 8
依赖选择:
- Spring Web
- Spring Boot DevTools
- Lombok (可选)
方式二:手动创建项目结构
# 创建项目目录
mkdir atlas-mapper-demo
cd atlas-mapper-demo
# 创建标准 Maven 目录结构
mkdir -p src/main/java/com/example/atlasmapperdemo
mkdir -p src/main/resources
mkdir -p src/test/java/com/example/atlasmapperdemo
步骤 4:配置 Maven POM 文件
创建 pom.xml 文件:
"1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.examplegroupId>
<artifactId>atlas-mapper-demoartifactId>
<version>1.0.0-SNAPSHOTversion>
<packaging>jarpackaging>
<name>Atlas Mapper Demoname>
<description>Atlas Mapper 框架演示项目description>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.13.RELEASEversion>
<relativePath/>
parent>
<properties>
<java.version>1.8java.version>
<atlas-mapper.version>1.0.0-SNAPSHOTatlas-mapper.version>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>io.github.nemoobgroupId>
<artifactId>atlas-mapper-spring-boot-starterartifactId>
<version>${atlas-mapper.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.1version>
<configuration>
<source>8source>
<target>8target>
<encoding>UTF-8encoding>
<annotationProcessorPaths>
<path>
<groupId>io.github.nemoobgroupId>
<artifactId>atlas-mapper-processorartifactId>
<version>${atlas-mapper.version}version>
path>
annotationProcessorPaths>
<compilerArgs>
<arg>-Amapstruct.defaultComponentModel=springarg>
<arg>-Amapstruct.unmappedTargetPolicy=IGNOREarg>
compilerArgs>
configuration>
plugin>
plugins>
build>
project>
示例代码:创建第一个映射器
创建实体类
// src/main/java/com/example/atlasmapperdemo/entity/User.java
package com.example.atlasmapperdemo.entity;
import java.time.LocalDateTime;
/**
* 用户实体类
*/
public class User {
private Long id;
private String firstName;
private String lastName;
private String email;
private String phoneNumber;
private LocalDateTime createdAt;
private Boolean active;
// 构造方法
public User() {}
public User(Long id, String firstName, String lastName, String email) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.createdAt = LocalDateTime.now();
this.active = true;
}
// Getter 和 Setter 方法
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPhoneNumber() { return phoneNumber; }
public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public Boolean getActive() { return active; }
public void setActive(Boolean active) { this.active = active; }
@Override
public String toString() {
return "User{" +
"id=" + id +
", firstName='" + firstName + ''' +
", lastName='" + lastName + ''' +
", email='" + email + ''' +
", phoneNumber='" + phoneNumber + ''' +
", createdAt=" + createdAt +
", active=" + active +
'}';
}
}
创建 DTO 类
// src/main/java/com/example/atlasmapperdemo/dto/UserDto.java
package com.example.atlasmapperdemo.dto;
/**
* 用户 DTO 类
*/
public class UserDto {
private Long id;
private String fullName; // 组合字段
private String email;
private String phone; // 字段名不同
private String createTime; // 类型不同
private String status; // 字段名和类型都不同
// 构造方法
public UserDto() {}
// Getter 和 Setter 方法
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getFullName() { return fullName; }
public void setFullName(String fullName) { this.fullName = fullName; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; }
public String getCreateTime() { return createTime; }
public void setCreateTime(String createTime) { this.createTime = createTime; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
@Override
public String toString() {
return "UserDto{" +
"id=" + id +
", fullName='" + fullName + ''' +
", email='" + email + ''' +
", phone='" + phone + ''' +
", createTime='" + createTime + ''' +
", status='" + status + ''' +
'}';
}
}
创建映射器接口
// src/main/java/com/example/atlasmapperdemo/mapper/UserMapper.java
package com.example.atlasmapperdemo.mapper;
import com.example.atlasmapperdemo.dto.UserDto;
import com.example.atlasmapperdemo.entity.User;
import io.github.nemoob.atlas.mapper.Mapper;
import io.github.nemoob.atlas.mapper.Mapping;
import java.util.List;
/**
* 用户映射器接口
*
* 关键点:
* 1. 使用 @Mapper 注解标记接口
* 2. componentModel = "spring" 让生成的实现类成为 Spring Bean
* 3. 使用 @Mapping 注解处理字段映射
*/
@Mapper(componentModel = "spring")
public interface UserMapper {
/**
* 将 User 实体转换为 UserDto
*
* 映射规则:
* - id -> id (自动映射,字段名和类型相同)
* - email -> email (自动映射)
* - phoneNumber -> phone (字段名映射)
* - createdAt -> createTime (字段名和类型映射)
* - firstName + lastName -> fullName (表达式映射)
* - active -> status (自定义方法映射)
*/
@Mapping(target = "phone", source = "phoneNumber")
@Mapping(target = "createTime", source = "createdAt", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(target = "fullName",
expression = "java(user.getFirstName() + " " + user.getLastName())")
@Mapping(target = "status", source = "active", qualifiedByName = "mapActiveToStatus")
UserDto toDto(User user);
/**
* 批量转换
*/
List toDtoList(List users) ;
/**
* 反向映射:UserDto -> User
*/
@Mapping(target = "phoneNumber", source = "phone")
@Mapping(target = "createdAt", source = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(target = "firstName", ignore = true) // 需要特殊处理
@Mapping(target = "lastName", ignore = true) // 需要特殊处理
@Mapping(target = "active", source = "status", qualifiedByName = "mapStatusToActive")
User toEntity(UserDto dto);
/**
* 自定义映射方法:Boolean -> String
*/
@org.mapstruct.Named("mapActiveToStatus")
default String mapActiveToStatus(Boolean active) {
if (active == null) {
return "未知";
}
return active ? "激活" : "禁用";
}
/**
* 自定义映射方法:String -> Boolean
*/
@org.mapstruct.Named("mapStatusToActive")
default Boolean mapStatusToActive(String status) {
if (status == null) {
return null;
}
return "激活".equals(status);
}
}
创建主应用类
// src/main/java/com/example/atlasmapperdemo/AtlasMapperDemoApplication.java
package com.example.atlasmapperdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Atlas Mapper 演示应用主类
*/
@SpringBootApplication
public class AtlasMapperDemoApplication {
public static void main(String[] args) {
SpringApplication.run(AtlasMapperDemoApplication.class, args);
System.out.println(" Atlas Mapper Demo 应用启动成功!");
System.out.println(" 访问 http://localhost:8080/api/users/demo 查看演示效果");
}
}
创建测试控制器
// src/main/java/com/example/atlasmapperdemo/controller/UserController.java
package com.example.atlasmapperdemo.controller;
import com.example.atlasmapperdemo.dto.UserDto;
import com.example.atlasmapperdemo.entity.User;
import com.example.atlasmapperdemo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
/**
* 用户控制器 - 演示 Atlas Mapper 的使用
*/
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserMapper userMapper; // 自动注入生成的映射器实现
/**
* 演示单个对象映射
*/
@GetMapping("/demo")
public UserDto getDemoUser() {
// 创建测试用户
User user = new User();
user.setId(1L);
user.setFirstName("张");
user.setLastName("三");
user.setEmail("zhangsan@example.com");
user.setPhoneNumber("13800138000");
user.setCreatedAt(LocalDateTime.now());
user.setActive(true);
// 使用 Atlas Mapper 进行映射
UserDto dto = userMapper.toDto(user);
System.out.println("原始用户: " + user);
System.out.println("映射结果: " + dto);
return dto;
}
/**
* 演示批量映射
*/
@GetMapping("/demo-list")
public List getDemoUserList() {
// 创建测试用户列表
List users = Arrays.asList(
createUser(1L, "张", "三", "zhangsan@example.com", true),
createUser(2L, "李", "四", "lisi@example.com", false),
createUser(3L, "王", "五", "wangwu@example.com", true)
);
// 批量映射
List dtos = userMapper.toDtoList(users);
System.out.println("批量映射完成,共处理 " + dtos.size() + " 个用户");
return dtos;
}
/**
* 演示反向映射
*/
@PostMapping("/demo-reverse")
public User createUserFromDto(@RequestBody UserDto dto) {
// 反向映射:DTO -> Entity
User user = userMapper.toEntity(dto);
// 手动处理无法自动映射的字段
if (dto.getFullName() != null && dto.getFullName().contains(" ")) {
String[] names = dto.getFullName().split(" ", 2);
user.setFirstName(names[0]);
user.setLastName(names.length > 1 ? names[1] : "");
}
System.out.println("反向映射结果: " + user);
return user;
}
/**
* 辅助方法:创建测试用户
*/
private User createUser(Long id, String firstName, String lastName, String email, Boolean active) {
User user = new User();
user.setId(id);
user.setFirstName(firstName);
user.setLastName(lastName);
user.setEmail(email);
user.setPhoneNumber("138" + String.format("%08d", id));
user.setCreatedAt(LocalDateTime.now().minusDays(id));
user.setActive(active);
return user;
}
}
效果演示:验证环境配置
步骤 1:编译项目
# 清理并编译项目
mvn clean compile
# 期望看到类似输出:
# [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ atlas-mapper-demo ---
# [INFO] Changes detected - recompiling the module!
# [INFO] Compiling 5 source files to /path/to/target/classes
# [INFO] Atlas Mapper processor is running...
# [INFO] Processing @Mapper interface: UserMapper
# [INFO] Generated implementation: UserMapperImpl
# [INFO] BUILD SUCCESS
步骤 2:检查生成的代码
编译成功后,检查生成的实现类:
# 查看生成的代码目录
ls -la target/generated-sources/annotations/com/example/atlasmapperdemo/mapper/
# 应该看到生成的文件:
# UserMapperImpl.java
生成的 UserMapperImpl.java 内容示例:
// target/generated-sources/annotations/.../UserMapperImpl.java
@Component
public class UserMapperImpl implements UserMapper {
@Override
public UserDto toDto(User user) {
if (user == null) {
return null;
}
UserDto userDto = new UserDto();
userDto.setPhone(user.getPhoneNumber());
if (user.getCreatedAt() != null) {
userDto.setCreateTime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.format(user.getCreatedAt()));
}
userDto.setStatus(mapActiveToStatus(user.getActive()));
userDto.setId(user.getId());
userDto.setEmail(user.getEmail());
userDto.setFullName(user.getFirstName() + " " + user.getLastName());
return userDto;
}
// ... 其他方法实现
}
步骤 3:启动应用
# 启动 Spring Boot 应用
mvn spring-boot:run
# 期望看到启动日志:
# Atlas Mapper Demo 应用启动成功!
# 访问 http://localhost:8080/api/users/demo 查看演示效果
步骤 4:测试映射功能
# 测试单个对象映射
curl http://localhost:8080/api/users/demo
# 期望返回:
# {
# "id": 1,
# "fullName": "张 三",
# "email": "zhangsan@example.com",
# "phone": "13800138000",
# "createTime": "2025-01-09 15:30:45",
# "status": "激活"
# }
# 测试批量映射
curl http://localhost:8080/api/users/demo-list
# 期望返回用户列表...
常见问题
Q1: 编译时提示找不到 Atlas Mapper 依赖?
A: 这是因为 Atlas Mapper 还在开发中,需要先本地安装:
# 在 Atlas Mapper 源码目录执行
mvn clean install
# 然后在你的项目中就可以使用了
Q2: IDE 中看不到生成的代码?
A: 需要配置 IDE 识别生成的源码目录:
IntelliJ IDEA:
- 右键项目 → Open Module Settings
- Sources → Add Content Root
- 选择
target/generated-sources/annotations - 标记为 Sources
Eclipse:
- 项目属性 → Java Build Path
- Source → Add Folder
- 选择
target/generated-sources/annotations
Q3: 注解处理器没有运行?
A: 检查以下配置:
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.github.nemoobgroupId>
<artifactId>atlas-mapper-processorartifactId>
<version>1.0.0-SNAPSHOTversion>
path>
annotationProcessorPaths>
configuration>
plugin>
Q4: Spring Boot 启动时找不到映射器 Bean?
A: 确保以下配置:
- 包扫描路径正确:
@SpringBootApplication
// 如果映射器不在主类包下,需要指定扫描路径
@ComponentScan(basePackages = {"com.example.atlasmapperdemo"})
public class AtlasMapperDemoApplication {
// ...
}
- 映射器接口配置正确:
@Mapper(componentModel = "spring") // 必须指定 componentModel
public interface UserMapper {
// ...
}
本章小结
通过本章学习,你应该掌握了:
- 环境搭建:JDK 8 + Maven + IDE 的配置
- 项目创建:Spring Boot 项目的标准结构
- 依赖配置:Atlas Mapper 的 Maven 配置
- 注解处理器:编译时代码生成的配置
- 验证方法:如何确认环境配置正确
下一步学习
在下一篇教程中,我们将深入学习:
- Atlas Mapper 的核心注解详解
- 基础映射规则和配置
- 字段映射的各种场景