Skip to content

数据填充


CommandLineRunner(类比 Seeder 的 run())

Spring Boot 没有 Laravel 的 php artisan db:seed 命令,但提供了 CommandLineRunner 接口,在应用启动完成后执行初始化逻辑。

java
@Component
public class DatabaseSeeder implements CommandLineRunner {

    @Autowired
    private UserMapper userMapper;

    @Override
    public void run(String... args) {
        // 只在开发环境执行
        if (userMapper.selectCount(null) > 0) {
            log.info("数据库已有数据,跳过填充");
            return;
        }

        log.info("开始填充初始数据...");

        // 创建用户
        User admin = new User();
        admin.setName("Admin");
        admin.setEmail("admin@example.com");
        admin.setAge(18);
        userMapper.insert(admin);

        // 批量创建
        for (int i = 0; i < 10; i++) {
            User user = new User();
            user.setName("User " + i);
            user.setEmail("user" + i + "@example.com");
            user.setAge(20 + i);
            userMapper.insert(user);
        }

        log.info("数据填充完成");
    }
}

CommandLineRunner 在 Spring 容器初始化完成后、应用正式接受请求前执行。多个 Runner 可以用 @Order 控制顺序。


只对特定 Profile 生效

java
@Component
@Profile("dev")   // 只在 spring.profiles.active=dev 时执行
public class DevDatabaseSeeder implements CommandLineRunner {
    @Override
    public void run(String... args) {
        // 填充测试数据
    }
}

使用 SQL 脚本

yaml
# application.yml
spring:
  sql:
    init:
      mode: always               # always / embedded / never
      schema-locations: classpath:sql/schema.sql
      data-locations: classpath:sql/data.sql
sql
-- src/main/resources/sql/data.sql
INSERT INTO users (name, email, age) VALUES ('Admin', 'admin@test.com', 18);
INSERT INTO users (name, email, age) VALUES ('Test', 'test@test.com', 25);

Spring Boot 原生的 spring.sql.init 会在启动时执行 SQL 文件。和 Flyway 不同,它不带版本管理,每次启动都会执行,通常用于测试或演示环境。


ApplicationRunner(CommandLineRunner 的替代)

java
@Component
public class DataInitializer implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) {
        // 可以访问 main 方法的参数
        log.info("是否包含 --seed 参数: {}", args.containsOption("seed"));
    }
}

ApplicationRunnerCommandLineRunner 功能一样,区别在于参数封装方式。CommandLineRunner 直接接收 String[]ApplicationRunner 封装为 ApplicationArguments 对象。

面向 PHP 开发者的 Spring Boot 文档