You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将复杂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. 验证步骤

  1. 启动应用,访问http://localhost:8080/h2-console,用配置的JDBC URL连接数据库。
  2. 用Postman/curl发送你的JSON到http://localhost:8080/api/users(注意把JSON里的languge改成language和DTO匹配)。
  3. 在H2控制台查看USER、SOCIAL_MEDIA等表,数据已成功存储。

用到的高级特性说明

  • Lombok:消除90%的样板代码,代码更简洁。
  • MapStruct:编译期生成转换代码,比反射转换更高效,类型安全。
  • Spring Data JPA:Repository接口自动实现CRUD,无需手写SQL。
  • DTO模式:隔离API和持久化层,避免暴露实体细节,增强扩展性。
  • 级联操作:CascadeType.ALL实现主实体保存时自动保存子实体,简化逻辑。
  • 懒加载:关联关系用FetchType.LAZY,避免不必要的数据查询,提升性能。

内容的提问来源于stack exchange,提问作者Siva Reddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:01:13