복붙노트

[SPRING] 스프링 부트 - 초기 데이터로드

SPRING

스프링 부트 - 초기 데이터로드

응용 프로그램을 시작하기 전에 초기 데이터베이스 데이터를로드하는 가장 좋은 방법은 무엇입니까? 내가 찾고있는 것은 내 H2 데이터베이스를 데이터로 채울 수있는 무언가이다.

예를 들어 도메인 모델 "User"를 / user로 이동하여 사용자에게 액세스 할 수 있지만 처음에는 데이터베이스에 사용자가 없으므로 사용자를 생성해야합니다. 데이터베이스에 데이터를 자동으로 채우려합니까?

현재 컨테이너에 의해 인스턴스화되고 사용자를 생성하는 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"));
    }
}

그러나 나는 그것을하는 가장 좋은 방법이라고 생각합니다. 아니면 그렇지?

해결법

  1. ==============================

    1.src / main / resources 폴더에 data.sql 파일 (또는 H2가 데이터베이스 인 경우에만 적용되도록하려면 data-h2.sql)을 만들면 시작할 때 자동으로 실행됩니다. 이 파일에서 몇 가지 insert 문을 추가하면됩니다. 예 :

    src / main / resources 폴더에 data.sql 파일 (또는 H2가 데이터베이스 인 경우에만 적용되도록하려면 data-h2.sql)을 만들면 시작할 때 자동으로 실행됩니다. 이 파일에서 몇 가지 insert 문을 추가하면됩니다. 예 :

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

    마찬가지로 스키마를 생성하기 위해 schema.sql 파일 (또는 schema-h2.sql)을 만들 수 있습니다.

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

    비록 Spring 부트가 이미 Hibernate가 당신의 엔티티를 기반으로 메모리 데이터베이스를위한 스키마를 생성하도록 설정했기 때문에 이것을하지 않아도됩니다. schema.sql을 실제로 사용하려면 application.properties에이 기능을 추가하여이 기능을 비활성화해야합니다.

    spring.jpa.hibernate.ddl-auto=none
    

    자세한 정보는 데이터베이스 초기화에 대한 문서에서 찾을 수 있습니다.

    스프링 부트 2를 사용하고 있다면, 데이터베이스 초기화는 임베디드 데이터베이스 (H2, HSQLDB, ...)에서만 작동합니다. 다른 데이터베이스에서도이 속성을 사용하려면 spring.datasource.initialization-mode 속성을 변경해야합니다.

    spring.datasource.initialization-mode=always
    
  2. ==============================

    2.간단한 테스트 데이터를 삽입하려는 경우 ApplicationRunner를 구현하기도합니다. 이 인터페이스의 구현은 응용 프로그램 시작시 실행되며 예를 들어 다음과 같이 사용할 수 있습니다. 일부 테스트 데이터를 삽입하는 자동 리포지토리.

    간단한 테스트 데이터를 삽입하려는 경우 ApplicationRunner를 구현하기도합니다. 이 인터페이스의 구현은 응용 프로그램 시작시 실행되며 예를 들어 다음과 같이 사용할 수 있습니다. 일부 테스트 데이터를 삽입하는 자동 리포지토리.

    인터페이스 구현은 애플리케이션 준비가 끝나면 바로 수행 할 작업이 포함되어 있음을 암시하기 때문에 이러한 구현은 사용자보다 약간 더 명확하게 나타낼 것이라고 생각합니다.

    귀하의 구현은 sth처럼 보일 것입니다. 이렇게 :

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

    3.제안으로서 이것을 시도하십시오 :

    제안으로서 이것을 시도하십시오 :

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

    스크립트 폴더가 resources 폴더 아래에있는 곳 (IntelliJ Idea)

    누군가가 도움이되기를 바랍니다.

  4. ==============================

    4.Spring Boot는 Spring Batch를 사용하여 간단한 스크립트를 사용하여 데이터베이스를 초기화 할 수있게합니다.

    Spring Boot는 Spring Batch를 사용하여 간단한 스크립트를 사용하여 데이터베이스를 초기화 할 수있게합니다.

    DB 버전 등을 관리하기 위해 좀 더 정교한 것을 사용하고자한다면 Spring Boot는 Flyway와 잘 통합됩니다.

    참조 :

  5. ==============================

    5.다음과 같이 사용할 수 있습니다.

    다음과 같이 사용할 수 있습니다.

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

    6.실행할 sql 파일을 나열하는 application.properties에 spring.datasource.data 속성을 추가 할 수 있습니다. 이렇게 :

    실행할 sql 파일을 나열하는 application.properties에 spring.datasource.data 속성을 추가 할 수 있습니다. 이렇게 :

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

    이 파일들 각각에있는 sql insert 문이 실행되어 여러분이 일을 깔끔하게 유지할 수있게 해줍니다.

  7. ==============================

    7.내가 얻은 방법은 다음과 같습니다.

    내가 얻은 방법은 다음과 같습니다.

    @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
        }
    
    }
    

    이 기사의 저자에게 감사드립니다.

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

  8. ==============================

    8.당신은 간단하게 src / main / resources에 import.sql 파일을 생성 할 수 있으며, Hibernate는 스키마가 생성 될 때 그것을 실행할 것이다.

    당신은 간단하게 src / main / resources에 import.sql 파일을 생성 할 수 있으며, Hibernate는 스키마가 생성 될 때 그것을 실행할 것이다.

  9. ==============================

    9.당신은 아래와 같이 그것을 달성하기 위해 이벤트 리스너를 등록 할 수 있습니다 :

    당신은 아래와 같이 그것을 달성하기 위해 이벤트 리스너를 등록 할 수 있습니다 :

    @EventListener
    public void seed(ContextRefreshedEvent event) {
        userRepository.save(new User("lala", "lala", "lala"));
    }
    

    ContextRefreshEdevent가 실행되면 모델과 저장소를 포함하여 애플리케이션의 모든 자동 완성 빈에 액세스 할 수 있습니다.

  10. ==============================

    10.만약 누군가가 고민을 풀고 답을 따라가더라도, 내 src / test / resources / application.yml에 H2 데이터 소스 세부 정보를 추가하면된다.

    만약 누군가가 고민을 풀고 답을 따라가더라도, 내 src / test / resources / application.yml에 H2 데이터 소스 세부 정보를 추가하면된다.

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

    11.이것은 또한 작동합니다.

    이것은 또한 작동합니다.

        @Bean
        CommandLineRunner init (StudentRepo studentRepo){
            return args -> {
                // Adding two students objects
                List<String> names = Arrays.asList("udara", "sampath");
                names.forEach(name -> studentRepo.save(new Student(name)));
            };
        }
    
  12. ==============================

    12.가장 압축 된 (동적 데이터 용) Lombok @AllArgsConstructor와 함께 MainApp에 @ mathias-dpunkt 솔루션을 넣습니다.

    가장 압축 된 (동적 데이터 용) Lombok @AllArgsConstructor와 함께 MainApp에 @ mathias-dpunkt 솔루션을 넣습니다.

    @SpringBootApplication
    @AllArgsConstructor
    public class RestaurantVotingApplication implements ApplicationRunner {
      private final VoteRepository voteRepository;
      private final UserRepository userRepository;
    
      public static void main(String[] args) {
        SpringApplication.run(RestaurantVotingApplication.class, args);
      }
    
      @Override
      public void run(ApplicationArguments args) {
        voteRepository.save(new Vote(userRepository.getOne(1), LocalDate.now(), LocalTime.now()));
      }
    }
    
  13. ==============================

    13.스프링 부트 2에서 data.sql은 스프링 부트 1.5에서와 같이 작동하지 않았습니다.

    스프링 부트 2에서 data.sql은 스프링 부트 1.5에서와 같이 작동하지 않았습니다.

    또한 클래스 패스의 루트에있는 import.sql이라는 이름의 파일은 Hibernate가 처음부터 스키마를 생성 할 경우 (즉, ddl-auto 속성이 create 또는 drop-drop으로 설정된 경우) 시작할 때 실행됩니다.

    삽입 할 때 매우 중요합니다. 키를 복제 할 수 없습니다. ddl-auto 속성을 사용하지 마십시오. 각 다시 시작할 때 동일한 데이터가 다시 삽입되므로 업데이트하도록 설정됩니다.

    자세한 내용은 봄 웹 사이트를 방문하십시오.

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

  14. ==============================

    14.이런 식으로 비슷한 문제를 해결했습니다.

    이런 식으로 비슷한 문제를 해결했습니다.

    @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();
        }
    }
    
  15. from https://stackoverflow.com/questions/38040572/spring-boot-loading-initial-data by cc-by-sa and MIT license