如何将复杂JSON转换为Spring Boot代码并存储到H2内存数据库
实现方案:基于Spring Boot高级特性存储JSON到H2内存数据库
针对你提供的JSON结构,我会用Spring Boot生态中的高级特性(比如Lombok、MapStruct、Spring Data JPA)来实现优雅的持久化方案,既减少样板代码,又保证扩展性。
1. 项目依赖配置(pom.xml)
先引入核心依赖,涵盖Web、JPA、H2、简化代码工具和对象转换工具:
<dependencies> <!-- Spring Web:处理HTTP请求 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Data JPA:简化持久化操作 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- H2内存数据库 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <!-- Lombok:消除getter/setter等样板代码 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- MapStruct:类型安全的对象转换工具 --> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.5.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.5.5.Final</version> <scope>provided</scope> </dependency> </dependencies>
2. H2数据库配置(application.properties)
配置内存模式和控制台,方便调试:
# H2连接配置 spring.datasource.url=jdbc:h2:mem:userdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect # 开启H2控制台,访问地址:http://localhost:8080/h2-console spring.h2.console.enabled=true spring.h2.console.path=/h2-console # JPA自动建表+SQL日志 spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true
3. 实体类设计(对应数据库表)
根据JSON结构拆解为嵌套实体,用Lombok简化代码:
3.1 子实体:Developer
package com.example.demo.entity; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor @AllArgsConstructor public class Developer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String companyName; private String years; }
3.2 子实体:Tester
package com.example.demo.entity; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor @AllArgsConstructor public class Tester { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String companyName; private String years; }
3.3 子实体:Experience
package com.example.demo.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor @AllArgsConstructor public class Experience { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @OneToOne(cascade = CascadeType.ALL) private Developer developer; @OneToOne(cascade = CascadeType.ALL) private Tester tester; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user; }
3.4 子实体:SocialMedia
package com.example.demo.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Entity @Data @NoArgsConstructor @AllArgsConstructor public class SocialMedia { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String fb; private String insta; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") private User user; }
3.5 主实体:User
package com.example.demo.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; @Entity @Data @NoArgsConstructor @AllArgsConstructor public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String age; private String language; private String country; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<SocialMedia> socialMedia; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<Experience> experience; }
4. DTO设计(接收前端JSON)
用DTO分离API层和持久化层,避免暴露实体内部结构:
4.1 DeveloperDTO
package com.example.demo.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class DeveloperDTO { private String companyName; private String years; }
4.2 TesterDTO
package com.example.demo.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class TesterDTO { private String companyName; private String years; }
4.3 ExperienceDTO
package com.example.demo.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class ExperienceDTO { private DeveloperDTO developer; private TesterDTO tester; }
4.4 SocialMediaDTO
package com.example.demo.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class SocialMediaDTO { private String fb; private String insta; }
4.5 主DTO:UserDTO
package com.example.demo.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor public class UserDTO { private String name; private String age; private List<SocialMediaDTO> socialMedia; private String language; private String country; private List<ExperienceDTO> experience; }
5. MapStruct转换器(DTO与实体转换)
用MapStruct替代手动转换,类型安全且高效:
package com.example.demo.mapper; import com.example.demo.dto.UserDTO; import com.example.demo.entity.User; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @Mapper(componentModel = "spring") public interface UserMapper { UserMapper INSTANCE = Mappers.getMapper(UserMapper.class); User toEntity(UserDTO userDTO); UserDTO toDTO(User user); }
6. Repository层(Spring Data JPA)
无需手写SQL,Spring自动实现CRUD:
package com.example.demo.repository; import com.example.demo.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User, Long> { }
7. Service层(业务逻辑封装)
用Lombok的@RequiredArgsConstructor替代@Autowired,更优雅:
package com.example.demo.service; import com.example.demo.dto.UserDTO; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import com.example.demo.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class UserService { private final UserRepository userRepository; private final UserMapper userMapper; public UserDTO saveUser(UserDTO userDTO) { // DTO转实体 User user = userMapper.toEntity(userDTO); // 设置关联关系(子实体绑定主实体) user.getSocialMedia().forEach(social -> social.setUser(user)); user.getExperience().forEach(exp -> exp.setUser(user)); // 保存到数据库 User savedUser = userRepository.save(user); // 实体转DTO返回 return userMapper.toDTO(savedUser); } }
8. Controller层(REST接口)
提供接收JSON的POST接口:
package com.example.demo.controller; import com.example.demo.dto.UserDTO; import com.example.demo.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/users") @RequiredArgsConstructor public class UserController { private final UserService userService; @PostMapping public ResponseEntity<UserDTO> createUser(@RequestBody UserDTO userDTO) { UserDTO savedUser = userService.saveUser(userDTO); return new ResponseEntity<>(savedUser, HttpStatus.CREATED); } }
9. 验证步骤
- 启动应用,访问
http://localhost:8080/h2-console,用配置的JDBC URL连接数据库。 - 用Postman/curl发送你的JSON到
http://localhost:8080/api/users(注意把JSON里的languge改成language和DTO匹配)。 - 在H2控制台查看
USER、SOCIAL_MEDIA等表,数据已成功存储。
用到的高级特性说明
- Lombok:消除90%的样板代码,代码更简洁。
- MapStruct:编译期生成转换代码,比反射转换更高效,类型安全。
- Spring Data JPA:Repository接口自动实现CRUD,无需手写SQL。
- DTO模式:隔离API和持久化层,避免暴露实体细节,增强扩展性。
- 级联操作:
CascadeType.ALL实现主实体保存时自动保存子实体,简化逻辑。 - 懒加载:关联关系用
FetchType.LAZY,避免不必要的数据查询,提升性能。
内容的提问来源于stack exchange,提问作者Siva Reddy
相关产品推荐
相关产品推荐

