Spring Boot – 加载初始数据

我想知道在应用程序启动之前加载初始数据库数据的最佳方式是什么? 我正在寻找的东西,将填补我的H2数据库的数据。

例如,我有一个域模型“用户”,我可以通过去/用户访问用户,但最初将不会有数据库中的任何用户,所以我必须创build它们。 是否有自动填充数据的数据库?

目前,我有一个容器实例化的Bean,并为我创build用户。

例:

@Component public class DataLoader { private UserRepository userRepository; @Autowired public DataLoader(UserRepository userRepository) { this.userRepository = userRepository; LoadUsers(); } private void LoadUsers() { userRepository.save(new User("lala", "lala", "lala")); } } 

但是我非常怀疑这是做这件事的最好方法。 还是呢?

您可以在src / main / resources文件夹中简单地创build一个data.sql文件(或者,如果您只希望在数据库中使用H2,使用data-h2.sql),它将在启动时自动执行。 在这个文件中,你只需添加一些插入语句,例如:

 INSERT INTO users (username, firstname, lastname) VALUES ('lala', 'lala', 'lala'), ('lolo', 'lolo', 'lolo'); 

同样,您也可以创build一个schema.sql文件(或schema-h2.sql)来创build您的模式:

 CREATE TABLE task ( id INTEGER PRIMARY KEY, description VARCHAR(64) NOT NULL, completed BIT NOT NULL); 

尽pipe通常你不应该这样做,因为Spring引导已经configurationHibernate来根据你的实体为内存数据库创build你的模式。 如果你真的想使用schema.sql,你必须禁用这个function,把它添加到你的application.properties中:

 spring.jpa.hibernate.ddl-auto=none 

有关数据库初始化的文档可以find更多信息。

如果我只想插入简单的testing数据,我经常实现一个ApplicationRunner 。 这个接口的实现在应用程序启动时运行,可以使用自动装载的存储库来插入一些testing数据。

我认为这样的实现会比你的实现稍微更明确,因为这个接口意味着你的实现包含了你的应用程序准备就绪之后你想要做的事情。

你的实现看起来像。 喜欢这个:

 @Component public class DataLoader implements ApplicationRunner { private UserRepository userRepository; @Autowired public DataLoader(UserRepository userRepository) { this.userRepository = userRepository; } public void run(ApplicationArguments args) { userRepository.save(new User("lala", "lala", "lala")); } } 

Spring Boot允许你使用一个简单的脚本来初始化你的数据库,使用Spring Batch 。

不过,如果你想用一些更精细的东西来pipe理数据库版本等,Spring Boot与Flyway很好地集成在一起。

也可以看看:

  • Spring Boot数据库初始化

build议试试这个:

 @Bean public CommandLineRunner loadData(CustomerRepository repository) { return (args) -> { // save a couple of customers repository.save(new Customer("Jack", "Bauer")); repository.save(new Customer("Chloe", "O'Brian")); repository.save(new Customer("Kim", "Bauer")); repository.save(new Customer("David", "Palmer")); repository.save(new Customer("Michelle", "Dessler")); // fetch all customers log.info("Customers found with findAll():"); log.info("-------------------------------"); for (Customer customer : repository.findAll()) { log.info(customer.toString()); } log.info(""); // fetch an individual customer by ID Customer customer = repository.findOne(1L); log.info("Customer found with findOne(1L):"); log.info("--------------------------------"); log.info(customer.toString()); log.info(""); // fetch customers by last name log.info("Customer found with findByLastNameStartsWithIgnoreCase('Bauer'):"); log.info("--------------------------------------------"); for (Customer bauer : repository .findByLastNameStartsWithIgnoreCase("Bauer")) { log.info(bauer.toString()); } log.info(""); } } 

选项2:使用模式和数据脚本进行初始化

先决条件:在application.properties你必须提到这一点:

spring.jpa.hibernate.ddl-auto=none (否则脚本将被hibernate忽略,它将扫描@Entity和/或@Table注释类的项目)

然后,在你的MyApplication类中粘贴这个:

 @Bean(name = "dataSource") public DriverManagerDataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("org.h2.Driver"); dataSource.setUrl("jdbc:h2:~/myDB;MV_STORE=false"); dataSource.setUsername("sa"); dataSource.setPassword(""); // schema init Resource initSchema = new ClassPathResource("scripts/schema-h2.sql"); Resource initData = new ClassPathResource("scripts/data-h2.sql"); DatabasePopulator databasePopulator = new ResourceDatabasePopulator(initSchema, initData); DatabasePopulatorUtils.execute(databasePopulator, dataSource); return dataSource; } 

scripts文件夹位于resources文件夹下(IntelliJ Idea)

希望它可以帮助别人

你可以使用这样的东西:

 @SpringBootApplication public class Application { @Autowired private UserRepository userRepository; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean InitializingBean sendDatabase() { return () -> { userRepository.save(new User("John")); userRepository.save(new User("Rambo")); }; } } 

您可以简单地在src/main/resources创build一个import.sql文件,当架构创build时Hibernate会执行它。