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
Spring Boot - Loading Initial 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-mode
property:
如果您使用的是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.sql或data-mysql.sql。
To make that work, you'll have to configure the spring.datasource.platform
property 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.properties
you 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 @Entity
and/or @Table
annotated classes)
spring.jpa.hibernate.ddl-auto=none
(否则脚本将被 hibernate 忽略,它将扫描项目@Entity
和/或带@Table
注释的类)
Then, in your MyApplication
class 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 scripts
folder is located under resources
folder (IntelliJ Idea)
当scripts
文件夹位于下的resources
文件夹(的IntelliJ IDEA)
Hope it helps someone
希望它可以帮助某人
回答by robjwilkins
You can add a spring.datasource.data
property to application.properties
listing 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/resources
they 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.sql
in 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.sql
file in src/main/resources
and 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();
}
}