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

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

目前,我有一个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"));
    }
}

但我非常怀疑这是不是最好的办法。真的是这样吗?


当前回答

如果我只想插入简单的测试数据,我通常实现一个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"));
    }
}

其他回答

我用这种方法解决了类似的问题:

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

你可以这样使用:

@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/test/资源/应用程序中添加工作。yml H2数据源详细信息:

spring:
  datasource:
    platform: h2
    url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
    driver-class-name: org.h2.Driver
    username: sa
    password:

在Spring Boot 2数据中。SQL不像spring boot 1.5那样适合我

import.sql

此外,还有一个名为import的文件。如果Hibernate从头创建模式(也就是说,如果ddl-auto属性设置为create或create-drop),则在启动时执行类路径根目录中的sql。

非常重要的一点是,如果你插入键不可复制,不要使用ddl-auto属性被设置为更新,因为每次重启都会再次插入相同的数据

欲了解更多信息,请访问spring网站

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

如果你想快速插入一些查询,你可以使用h2数据。还有SQL查询

应用程序。属性包括:

spring.jpa.show-sql=true
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb

#This directs the data.sql file and help it to run
spring.sql.init.data-locations=classpath:data.sql
spring.jpa.defer-datasource-initialization=true

数据。SQL文件包括:

INSERT INTO todo (id, username, description, target_date, is_done) VALUES (10001, 'lighteducation', 'Learn dance', CURRENT_DATE ,false);

INSERT INTO todo (id, username, description, target_date, is_done) VALUES (10002, 'lighteducation', 'Learn Angular14', CURRENT_DATE, false);

INSERT INTO todo (id, username, description, target_date, is_done) VALUES (10003, 'lighteducation', 'Learn Microservices', CURRENT_DATE,false);

注:数据。SQL文件应该在src/main/resources中

你的@实体包含

@Getter
@Setter
@AllArgsConstructor
@ToString
@Entity
public class Todo {
    @Id
    @GeneratedValue
    private Long id;

    private String username;
    private String description;
    private Date targetDate;
    private boolean isDone;

    protected Todo() {

    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Todo todo = (Todo) o;
        return id == todo.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

基本上就是这样。它将在内存中,这意味着当您重新启动应用程序时,数据将再次与查询显示的相同。

但它很容易进行快速检查

此外,您可以通过http://localhost:8080/h2-console/访问该路径,也可以从.properties文件编辑该路径