模拟医院免安装绿色中文版
160M · 2025-10-13
通过本篇教程,你将学会:
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+ | - |
# 检查 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)
# 检查 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
项目配置:
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
创建 pom.xml
文件:
<?xml version="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.0</modelVersion>
<!-- 项目基本信息 -->
<groupId>com.example</groupId>
<artifactId>atlas-mapper-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Atlas Mapper Demo</name>
<description>Atlas Mapper 框架演示项目</description>
<!-- Spring Boot 父项目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.13.RELEASE</version>
<relativePath/>
</parent>
<!-- 属性配置 -->
<properties>
<java.version>1.8</java.version>
<atlas-mapper.version>1.0.0-SNAPSHOT</atlas-mapper.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 依赖管理 -->
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Atlas Mapper Spring Boot Starter -->
<dependency>
<groupId>io.github.nemoob</groupId>
<artifactId>atlas-mapper-spring-boot-starter</artifactId>
<version>${atlas-mapper.version}</version>
</dependency>
<!-- 开发工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 构建配置 -->
<build>
<plugins>
<!-- Spring Boot Maven 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Maven 编译插件 - 关键配置! -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
<!-- 注解处理器配置 - 核心配置 -->
<annotationProcessorPaths>
<path>
<groupId>io.github.nemoob</groupId>
<artifactId>atlas-mapper-processor</artifactId>
<version>${atlas-mapper.version}</version>
</path>
</annotationProcessorPaths>
<!-- 编译参数 -->
<compilerArgs>
<arg>-Amapstruct.defaultComponentModel=spring</arg>
<arg>-Amapstruct.unmappedTargetPolicy=IGNORE</arg>
</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 +
'}';
}
}
// 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<UserDto> toDtoList(List<User> 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("[email protected]");
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<UserDto> getDemoUserList() {
// 创建测试用户列表
List<User> users = Arrays.asList(
createUser(1L, "张", "三", "[email protected]", true),
createUser(2L, "李", "四", "[email protected]", false),
createUser(3L, "王", "五", "[email protected]", true)
);
// 批量映射
List<UserDto> 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;
}
}
# 清理并编译项目
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
编译成功后,检查生成的实现类:
# 查看生成的代码目录
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;
}
// ... 其他方法实现
}
# 启动 Spring Boot 应用
mvn spring-boot:run
# 期望看到启动日志:
# Atlas Mapper Demo 应用启动成功!
# 访问 http://localhost:8080/api/users/demo 查看演示效果
# 测试单个对象映射
curl http://localhost:8080/api/users/demo
# 期望返回:
# {
# "id": 1,
# "fullName": "张 三",
# "email": "[email protected]",
# "phone": "13800138000",
# "createTime": "2025-01-09 15:30:45",
# "status": "激活"
# }
# 测试批量映射
curl http://localhost:8080/api/users/demo-list
# 期望返回用户列表...
A: 这是因为 Atlas Mapper 还在开发中,需要先本地安装:
# 在 Atlas Mapper 源码目录执行
mvn clean install
# 然后在你的项目中就可以使用了
A: 需要配置 IDE 识别生成的源码目录:
IntelliJ IDEA:
target/generated-sources/annotations
Eclipse:
target/generated-sources/annotations
A: 检查以下配置:
<!-- 确保 Maven 编译插件配置正确 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- 必须配置注解处理器路径 -->
<annotationProcessorPaths>
<path>
<groupId>io.github.nemoob</groupId>
<artifactId>atlas-mapper-processor</artifactId>
<version>1.0.0-SNAPSHOT</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
A: 确保以下配置:
@SpringBootApplication
// 如果映射器不在主类包下,需要指定扫描路径
@ComponentScan(basePackages = {"com.example.atlasmapperdemo"})
public class AtlasMapperDemoApplication {
// ...
}
@Mapper(componentModel = "spring") // 必须指定 componentModel
public interface UserMapper {
// ...
}
通过本章学习,你应该掌握了:
在下一篇教程中,我们将深入学习: