starter - spring jpa reference
Spring Boot-Carregando Dados Iniciais (10)
Eu estou querendo saber qual a melhor maneira de carregar os dados do banco de dados inicial antes de iniciar o aplicativo? O que estou procurando é algo que preencherá meu banco de dados H2 com dados.
Por exemplo, eu tenho um modelo de domínio "Usuário" Eu posso acessar os usuários, indo para / users, mas inicialmente não haverá nenhum usuário no banco de dados, então eu tenho que criá-los. Existe alguma maneira de preencher o banco de dados com dados automaticamente?
No momento, tenho um Bean que é instanciado pelo contêiner e cria usuários para mim.
Exemplo:
@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"));
}
}
Mas duvido muito que essa seja a melhor maneira de fazer isso. Ou é?
https://src-bin.com
Answer #1
Aqui está o jeito que eu peguei isso:
@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
}
}
Graças ao autor deste artigo:
http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/
Answer #2
Como sugestão, tente isto:
@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("");
}
}
Opção 2:
inicializar com scripts de esquema e dados
Pré-requisitos: em
application.properties
você deve mencionar isto:
spring.jpa.hibernate.ddl-auto=none
(senão os scripts serão ignorados pelo hibernate, e ele fará a varredura do projeto para as classes anotadas
@Entity
e / ou
@Table
)
Então, na sua classe
MyApplication
cole isto:
@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;
}
Onde pasta de
scripts
está localizada na pasta de
resources
(IntelliJ Idea)
Espero que ajude alguém
Answer #3
Isso também funcionará.
@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)));
};
}
Answer #4
No Spring Boot 2, o data.sql não estava funcionando comigo como na inicialização da mola 1.5
import.sql
Além disso, um arquivo chamado
import.sql
na raiz do classpath é executado na inicialização se o Hibernate criar o esquema a partir do zero (ou seja, se a propriedade ddl-auto estiver configurada para criar ou criar-soltar).
Nota muito importante se você inserir Chaves não podem ser duplicadas não use ddl-auto propriedade está definida para atualizar porque a cada reinício irá inserir os mesmos dados novamente
Para mais informações você visita spring websit
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html
Answer #5
O mais compacto (para dados dinâmicos) coloca a solução @ mathias-dpunkt no MainApp (com o 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()));
}
}
Answer #6
Se alguém está lutando para fazer isso funcionar mesmo seguindo a
resposta aceita
, para mim só trabalho adicionando no meu
src/test/resources/application.yml
os detalhes da
datasource
H2:
spring:
datasource:
platform: h2
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
driver-class-name: org.h2.Driver
username: sa
password:
Answer #7
Você pode adicionar uma propriedade
spring.datasource.data
a
application.properties
listando os arquivos sql que deseja executar.
Como isso:
spring.datasource.data=classpath:accounts.sql, classpath:books.sql, classpath:reviews.sql
As instruções de inserção do SQL em cada um desses arquivos serão executadas, permitindo que você mantenha as coisas organizadas
Answer #8
Você pode simplesmente criar um arquivo
import.sql
em
src/main/resources
e o Hibernate irá executá-lo quando o esquema for criado.
Answer #9
Você pode usar algo assim:
@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"));
};
}
}
Answer #10
você pode se registrar e ouvinte de eventos para conseguir isso como abaixo:
@EventListener
public void seed(ContextRefreshedEvent event) {
userRepository.save(new User("lala", "lala", "lala"));
}
Quando o ContextRefreshEvent é disparado, obtemos acesso a todos os beans autowired no aplicativo - incluindo modelos e repositórios.