2016-06-26 58 views
41

我想知道在应用程序启动之前加载初始数据库数据的最佳方式是什么?我正在寻找的是能够填充我的H2数据库的数据。Spring Boot - 加载初始数据

例如,我有一个域模型“用户”,我可以通过访问/用户来访问用户,但最初在数据库中不会有任何用户,因此我必须创建它们。有没有办法自动填充数据库?

目前我有一个Bean,它被容器实例化并为我创建用户。

例子:

@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")); 
    } 
} 

但我很怀疑这是做的最好的方式。或者是?

+3

这将工作,或者简单地将'data.sql'和/或'schema.sql'添加到init数据中。所有这些[记录](http://docs.spring.io/spring-boot/docs/current /reference/html/howto-database-initialization.html)参考指南(我建议阅读)。 –

+0

如果这对您有帮助,请标记正确的答案。 – Reborn

+0

有没有人得到这个工作?我仍然无法把它放在一起,不知道我在这里错过了什么。 https://git.io/v5SWx – Srini

回答

8

Spring Boot允许您使用一个简单的脚本来初始化您的数据库,使用Spring Batch。但是,如果你想使用一些更精细的东西来管理数据库版本等,Spring Boot与Flyway很好地集成在一起。

参见:

59

您可以简单地创建一个data.sql文件(或数据h2.sql如果你只希望它的情况下应用H2是你的数据库)在你的src/main/resources文件夹中,它会在启动时自动执行。在这个文件中,你只需添加一些INSERT语句,如:

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

同样,你可以创建一个schema.sql文件文件(或架构h2.sql),以及创建您的模式:

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

虽然正常情况下你不应该这样做,因为春天已经启动休眠配置根据您的实体为内存数据库创建架构。如果你真的想使用schema.sql文件你必须通过添加以下内容到application.properties禁用此功能:

spring.jpa.hibernate.ddl-auto=none 

的更多信息可以在文档中关于Database initialization找到。

+0

谢谢@ g00glen00b清理:“它会在启动时自动执行”。由于我使用addScript(s)选项将data.sql文件包含在我的bean配置中,因此出现错误。至此,架构还没有建成。 –

+0

我遇到了创建数据库对象和运行data.sql的顺序问题。该脚本在创建数据库实体之前运行。这里是我的帖子在这个问题上:https://stackoverflow.com/questions/38040572/spring-boot-loading-initial-data?rq = 1 – Srini

+0

看起来像上面的链接是不正确的。 https://stackoverflow.com/questions/46066575/spring-boot-data-initialization 我也创建了一个突出显示问题的示例项目。 https://git.io/v5SWx – Srini

35

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

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

你的实现看起来像。像这样:

@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")); 
    } 
} 
+0

public void run();方法需要公开 – eosimosu

1

可以在src/main/resources只需创建一个import.sql文件,并在创建架构时Hibernate会执行它。

9

至于建议试试这个:

@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(否则脚本将被休眠忽略,并且它将扫描项目@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)

希望它可以帮助别人

2

您可以使用下像这样:

@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")); 
     }; 
    } 
} 
相关问题