1. 简介

在实际开发中,我们经常需要在应用启动时初始化一些基础数据。除了使用 data.sql 脚本外,Spring Data JPA 提供了一个更优雅的替代方案 —— Repository Populators。它支持通过 JSON 或 XML 文件格式来初始化数据库数据,结构清晰、易于维护。

本文将通过一个简单的水果库存系统示例,演示如何使用 Spring Data JPA 的 Repository Populators 功能来初始化数据。


2. 示例应用

我们先定义一个简单的 Fruit 实体类:

@Entity
public class Fruit {
    @Id
    private long id;
    private String name;
    private String color;
    
    // getters and setters
}

然后定义一个继承 JpaRepository 的 Repository 接口:

@Repository
public interface FruitRepository extends JpaRepository<Fruit, Long> {
}

接下来我们将分别使用 JSON 和 XML 格式来初始化数据。


3. JSON Repository Populators

✅ 准备 JSON 数据文件

src/main/resources 目录下创建 fruit-data.json 文件,内容如下:

[
    {
        "_class": "com.baeldung.entity.Fruit",
        "name": "apple",
        "color": "red",
        "id": 1
    },
    {
        "_class": "com.baeldung.entity.Fruit",
        "name": "guava",
        "color": "green",
        "id": 2
    }
]

⚠️ 注意:每个 JSON 对象中必须包含 _class 字段,用于指定实体类的完整类名。

✅ 添加依赖

pom.xml 中添加 Jackson 依赖,用于处理 JSON 格式数据:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.5</version>
</dependency>

✅ 配置 Repository Populator Bean

在配置类中添加如下 Bean:

@Bean
public Jackson2RepositoryPopulatorFactoryBean getRespositoryPopulator() {
    Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean();
    factory.setResources(new Resource[]{new ClassPathResource("fruit-data.json")});
    return factory;
}

✅ 单元测试验证

编写测试方法验证数据是否成功插入数据库:

@Test
public void givenFruitJsonPopulatorThenShouldInsertRecordOnStart() {
    List<Fruit> fruits = fruitRepository.findAll();
    assertEquals("record count is not matching", 2, fruits.size());

    fruits.forEach(fruit -> {
        if (1 == fruit.getId()) {
            assertEquals("apple", fruit.getName());
            assertEquals("red", fruit.getColor());
        } else if (2 == fruit.getId()) {
            assertEquals("guava", fruit.getName());
            assertEquals("green", fruit.getColor());
        }
    });
}

4. XML Repository Populators

✅ 准备 XML 数据文件

分别创建两个 XML 文件,每个文件代表一条水果记录:

apple-fruit-data.xml

<fruit>
    <id>1</id>
    <name>apple</name>
    <color>red</color>
</fruit>

guava-fruit-data.xml

<fruit>
    <id>2</id>
    <name>guava</name>
    <color>green</color>
</fruit>

✅ 添加依赖

pom.xml 中添加 Spring OXM 依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-oxm</artifactId>
    <version>6.1.4</version>
</dependency>

✅ 修改实体类

Fruit 实体类上添加 @XmlRootElement 注解,用于支持 XML 解析:

@XmlRootElement
@Entity
public class Fruit {
    // ...
}

✅ 配置 Repository Populator Bean

添加如下配置 Bean:

@Bean
public UnmarshallerRepositoryPopulatorFactoryBean repositoryPopulator() {
    Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller();
    unmarshaller.setClassesToBeBound(Fruit.class);

    UnmarshallerRepositoryPopulatorFactoryBean factory = new UnmarshallerRepositoryPopulatorFactoryBean();
    factory.setUnmarshaller(unmarshaller);
    factory.setResources(new Resource[] { 
        new ClassPathResource("apple-fruit-data.xml"), 
        new ClassPathResource("guava-fruit-data.xml") 
    });
    return factory;
}

✅ 单元测试

XML 的测试逻辑与 JSON 类似,不再赘述。


5. 总结

✅ Spring Data JPA 的 Repository Populators 提供了一种结构化、可维护的数据初始化方式,适用于中小型项目中初始化数据的需求。

  • ✅ JSON 格式更简洁,适合现代开发场景
  • ✅ XML 格式适合已有 XML 配置体系的项目
  • ❌ 不适合大规模数据初始化(建议使用 SQL 脚本或 Flyway 等工具)

使用 Repository Populators 可以避免 SQL 脚本的语法差异问题,同时还能利用 JPA 的映射机制,确保数据插入的准确性,是初始化数据的一种简单粗暴但非常实用的方式。


原始标题:Spring Data JPA Repository Populators | Baeldung