数据填充
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.sqlsql
-- 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"));
}
}
ApplicationRunner和CommandLineRunner功能一样,区别在于参数封装方式。CommandLineRunner直接接收String[],ApplicationRunner封装为ApplicationArguments对象。