스프링 부트-초기 데이터로드
응용 프로그램이 시작되기 전에 초기 데이터베이스 데이터를로드하는 가장 좋은 방법이 무엇인지 궁금합니다. 내가 찾고있는 것은 H2 데이터베이스를 데이터로 채울 무언가입니다.
예를 들어, / users로 이동하여 사용자에게 액세스 할 수있는 도메인 모델 "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"));
}
}
그러나 그것이 최선의 방법이라고 의심합니다. 아니면?
src / main / resources 폴더 에 data.sql 파일을 만들면 시작할 때 자동으로 실행됩니다. 이 파일에는 다음과 같은 삽입 문 만 추가하면됩니다.
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
자세한 내용은 데이터베이스 초기화 관련 설명서를 참조하십시오 .
Spring boot 2를 사용하는 경우 데이터베이스 초기화는 임베디드 데이터베이스 (H2, HSQLDB, ...)에서만 작동합니다. 다른 데이터베이스에도 사용하려면 spring.datasource.initialization-mode
속성 을 변경해야 합니다.
spring.datasource.initialization-mode=always
여러 데이터베이스 공급 업체 를 사용하는 경우 사용할 데이터베이스 플랫폼에 따라 파일 이름을 data-h2.sql 또는 data-mysql.sql로 지정할 수 있습니다.
이 작업을 수행하려면 spring.datasource.platform
속성 을 구성해야 합니다.
spring.datasource.platform=h2
간단한 테스트 데이터를 삽입하고 싶다면 종종을 구현합니다 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"));
}
}
제안으로 이것을 시도하십시오 :
@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 아이디어)
누군가에게 도움이되기를 바랍니다.
실행할 SQL 파일 spring.datasource.data
을 application.properties
나열 하는 특성을 추가 할 수 있습니다 . 이처럼 :
spring.datasource.data=classpath:accounts.sql, classpath:books.sql, classpath:reviews.sql
그런 다음 각 파일의 sql insert 문이 실행되어 깔끔하게 유지할 수 있습니다.
다음과 같은 것을 사용할 수 있습니다.
@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"));
};
}
}
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.
See also:
In Spring Boot 2 data.sql was not working with me as in 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).
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
For more information you vist spring websit
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html
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/
You can simply create a import.sql
file in src/main/resources
and Hibernate will execute it when the schema is created.
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();
}
}
If someone are struggling in make this to work even following the accepted answer, for me only work adding in my src/test/resources/application.yml
the H2 datasource
details:
spring:
datasource:
platform: h2
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
driver-class-name: org.h2.Driver
username: sa
password:
you can register and event listener to achieve that like below:
@EventListener
public void seed(ContextRefreshedEvent event) {
userRepository.save(new User("lala", "lala", "lala"));
}
When the ContextRefreshEvent is fired, we get access to all autowired beans in the application — including models and repositories.
This will also work.
@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)));
};
}
The most compact (for dynamic data) put @mathias-dpunkt solution into MainApp (with Lombok @AllArgsConstructor
):
@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()));
}
}
If you want to insert only few rows and u have JPA Setup. You can use below
@SpringBootApplication
@Slf4j
public class HospitalManagementApplication {
public static void main(String[] args) {
SpringApplication.run(HospitalManagementApplication.class, args);
}
@Bean
ApplicationRunner init(PatientRepository repository) {
return (ApplicationArguments args) -> dataSetup(repository);
}
public void dataSetup(PatientRepository repository){
//inserts
}
참고URL : https://stackoverflow.com/questions/38040572/spring-boot-loading-initial-data
'Programing' 카테고리의 다른 글
C ++ 재정의 헤더 파일 (winsock2.h) (0) | 2020.06.28 |
---|---|
NodeJS는 글로벌 모듈 / 패키지를 필요로합니다 (0) | 2020.06.28 |
Windows SDK 7.1을 사용하여 명령 줄에서 msbuild를 어떻게 실행합니까? (0) | 2020.06.28 |
MySQL에서 한 테이블에서 다른 새 테이블로 데이터를 복사하는 방법은 무엇입니까? (0) | 2020.06.28 |
자바 스크립트에서 숫자의 길이 (0) | 2020.06.28 |