Spring Boot - 加载初始数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38040572/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:06:53  来源:igfitidea点击:

Spring Boot - Loading Initial Data

springspring-bootspring-data

提问by Lithicas

I'm wondering what the best way to load initial database data before the application starts? What I'm looking for is something that will fill my H2 database with data.

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

For example, I have a domain model "User" I can access users by going to /users but initially there won't be any users in the database so I have to create them. Is there anyway to fill the database with data automatically?

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

At the moment I have a Bean that gets instantiated by the container and creates users for me.

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

Example:

例子:

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

But I very much doubt that is the best way of doing it. Or is it?

但我非常怀疑这是最好的方法。或者是吗?

回答by g00glen00b

You can simply create a data.sqlfile in your src/main/resourcesfolder and it will be automatically executed on startup. In this file you just add some insert statements, eg.:

您可以简单地在src/main/resources文件夹中创建一个data.sql文件,它会在启动时自动执行。在此文件中,您只需添加一些插入语句,例如:

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


Similarly, you can create a schema.sqlfile (or schema-h2.sql) as well to create your schema:

同样,您也可以创建一个schema.sql文件(或 schema-h2.sql)来创建您的架构:

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

Though normally you shouldn't have to do this since Spring boot already configures Hibernate to create your schema based on your entities for an in memory database. If you really want to use schema.sql you'll have to disable this feature by adding this to your application.properties:

虽然通常你不应该这样做,因为 Spring boot 已经配置了 Hibernate 来根据你的实体为内存数据库创建模式。如果您真的想使用 schema.sql,您必须通过将其添加到 application.properties 来禁用此功能:

spring.jpa.hibernate.ddl-auto=none

More information can be found at the documentation about Database initialization.

更多信息可以在关于数据库初始化的文档中找到。



If you're using Spring boot 2, database initialization only works for embedded databases (H2, HSQLDB, ...). If you want to use it for other databases as well, you need to change the spring.datasource.initialization-modeproperty:

如果您使用的是Spring boot 2,则数据库初始化仅适用于嵌入式数据库(H2、HSQLDB 等)。如果您还想将其用于其他数据库,则需要更改该spring.datasource.initialization-mode属性:

spring.datasource.initialization-mode=always


If you're using multiple database vendors, you can name your file data-h2.sqlor data-mysql.sqldepending on which database platform you want to use.

如果您使用多个数据库供应商,则可以根据要使用的数据库平台将文件命名为data-h2.sqldata-mysql.sql

To make that work, you'll have to configure the spring.datasource.platformproperty though:

为了使其工作,您必须配置该spring.datasource.platform属性:

spring.datasource.platform=h2

回答by Mathias Dpunkt

If I just want to insert simple test data I often implement a ApplicationRunner. Implementations of this interface are run at application startup and can use e.g. a autowired repository to insert some test data.

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

I think such an implementation would be slightly more explicit than yours because the interface implies that your implementation contains something you would like to do directly after your application is ready.

我认为这样的实现会比你的更明确一些,因为接口暗示你的实现包含你想要在应用程序准备好后直接做的事情。

Your implementation would look sth. like this:

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

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

回答by Reborn

As suggestion try this:

作为建议试试这个:

@Bean
public CommandLineRunner loadData(CustomerRepository repository) {
    return (args) -> {
        // save a couple of customers
        repository.save(new Customer("Hyman", "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("");
    }
}

Option 2:Initialize with schema and data scripts

选项 2:使用架构和数据脚本初始化

Prerequisites: in application.propertiesyou have to mention this:

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

spring.jpa.hibernate.ddl-auto=none(otherwise scripts will be ignored by hibernate, and it will scan project for @Entityand/or @Tableannotated classes)

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

Then, in your MyApplicationclass paste this:

然后,在你的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;
}

Where scriptsfolder is located under resourcesfolder (IntelliJ Idea)

scripts文件夹位于下的resources文件夹(的IntelliJ IDEA)

Hope it helps someone

希望它可以帮助某人

回答by robjwilkins

You can add a spring.datasource.dataproperty to application.propertieslisting the sql files you want to run. Like this:

您可以添加一个spring.datasource.data属性来application.properties列出要运行的 sql 文件。像这样:

spring.datasource.data=classpath:accounts.sql, classpath:books.sql, classpath:reviews.sql

The sql insert statements in each of these files will then be run, allowing you to keep things tidy.

然后将运行每个文件中的 sql insert 语句,让您保持整洁。

If you put the files in the classpath, for example in src/main/resourcesthey will be applied. Or replace classpath:with file:and use an absolute path to the file

如果您将文件放在类路径中,例如src/main/resources它们将被应用。或者替换classpath:file:并使用文件的绝对路径

回答by Grauzone

You can use something like this:

你可以使用这样的东西:

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

回答by Xtreme Biker

Spring Boot allows you to use a simple script to initialize your database, using Spring Batch.

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

Still, if you want to use something a bit more elaborated to manage DB versions and so on, Spring Boot integrates well with Flyway.

尽管如此,如果您想使用更精细的东西来管理数据库版本等,Spring Boot 与Flyway集成得很好。

See also:

也可以看看:

回答by Ismail

In Spring Boot 2 data.sql was not working with me as in spring boot 1.5

在 Spring Boot 2 中 data.sql 不像在 spring boot 1.5 中那样与我一起工作

import.sql

导入文件

In addition, a file named import.sqlin the root of the classpath is executed on startup if Hibernate creates the schema from scratch (that is, if the ddl-auto property is set to create or create-drop).

此外,import.sql如果 Hibernate 从头开始​​创建模式(即,如果 ddl-auto 属性设置为 create 或 create-drop),则在启动时会执行在类路径的根目录中命名的文件。

Note very important if you insert Keys cannot be duplicated do not use ddl-auto property is set to update because with each restart will insert same data again

注意非常重要,如果你插入的 Keys 不能被复制,不要使用 ddl-auto 属性设置为 update 因为每次重启都会再次插入相同的数据

For more information you vist spring websit

有关更多信息,请访问 spring 网站

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html

回答by adkl

Here is the way I got that:

这是我得到的方式:

@Component
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {

    /**
     * This event is executed as late as conceivably possible to indicate that
     * the application is ready to service requests.
     */

    @Autowired
    private MovieRepositoryImpl movieRepository;

    @Override
    public void onApplicationEvent(final ApplicationReadyEvent event) {
        seedData();
    }

    private void seedData() {
        movieRepository.save(new Movie("Example"));

        // ... add more code
    }

}

Thanks to the author of this article:

感谢本文作者:

http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/

http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/

回答by Francesco Papagno

You can simply create a import.sqlfile in src/main/resourcesand Hibernate will execute it when the schema is created.

您可以简单地在其中创建一个import.sql文件src/main/resources,Hibernate 将在创建模式时执行它。

回答by A-Bag

I solved similar problem this way:

我这样解决了类似的问题:

@Component
public class DataLoader {

    @Autowired
    private UserRepository userRepository;

    //method invoked during the startup
    @PostConstruct
    public void loadData() {
        userRepository.save(new User("user"));
    }

    //method invoked during the shutdown
    @PreDestroy
    public void removeData() {
        userRepository.deleteAll();
    }
}