La Primavera De Arranque – Carga Inicial De Datos

Estoy preguntando cuál es la mejor manera para la carga inicial de datos de base de datos antes de que se inicie la aplicación? Lo que estoy buscando es algo que va a llenar mi H2 base de datos con los datos.

Por ejemplo, yo tengo un modelo de dominio «Usuario» puedo acceder a los usuarios por los que van a los usuarios, pero inicialmente no habrá ninguna usuarios en la base de datos, así que tengo que crear. Es de todos modos hay que rellenar la base de datos con los datos automáticamente?

Por el momento tengo un Bean que obtiene instanciado por el contenedor y crea usuarios para mí.

Ejemplo:

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

Pero dudo mucho de que es la mejor manera de hacerlo. O es?

  • Que va a trabajar, o simplemente agregar data.sql y/o schema.sql a init datos.. Todo esto es documentado en la guía de referencia (que me sugieren para leer).
  • Por favor, marque la respuesta correcta si que te ayudaron.
  • Alguien ha conseguido que esto funcione? Aún no puedo poner esto juntos y no está seguro de lo que me estoy perdiendo aquí. git.io/v5SWx
InformationsquelleAutor Lithicas | 2016-06-26

15 Kommentare

  1. 226

    Usted puede simplemente crear un de datos.sql archivo en su src/main/resources carpeta y automáticamente será ejecutado en el inicio. En este archivo, usted sólo tiene que añadir algunas instrucciones insert, ej.:

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

    Del mismo modo, puede crear un esquema.sql archivo (o esquema-h2.sql) así como para crear su esquema:

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

    Aunque normalmente usted no debería tener que hacerlo desde la Primavera de arranque ya configura Hibernate para crear su esquema basado en sus entidades en la memoria de la base de datos. Si usted realmente desea utilizar el esquema.sql tendrás que desactivar esta función mediante la adición de este para su aplicación.propiedades:

    spring.jpa.hibernate.ddl-auto=none

    Más información se puede encontrar en la documentación acerca de Inicialización de base de datos.


    Si usted está usando Primavera de arranque 2, inicialización de base de datos sólo funciona para bases de datos incrustadas (H2, HSQLDB, …). Si desea usar para otras bases de datos, así, usted necesita para cambiar el spring.datasource.initialization-mode propiedad:

    spring.datasource.initialization-mode=always

    Si está utilizando varios vendedores de bases de datos, usted puede nombrar a su archivo de datos-h2.sql o de datos mysql.sql dependiendo de la plataforma de base de datos que desea utilizar.

    Para hacer que el trabajo, tendrás que configurar el spring.datasource.platform de la propiedad, sin embargo:

    spring.datasource.platform=h2
    • Gracias @g00glen00b para aclarar : «y automáticamente será ejecutado en el inicio». Yo estaba errores como he incluido los datos.archivo sql en mi bean configuración mediante el addScript(s) opción. Como en este punto el esquema aún no había sido construida.
    • Estoy teniendo problema con la secuencia de la creación de la base de datos de objetos y ejecución de los datos.sql. El script se ejecuta antes de la creación de la base de datos de las entidades. Aquí está mi post sobre el tema:stackoverflow.com/questions/38040572/…
    • Parece enlace de arriba es incorrecta. stackoverflow.com/questions/46066575/… también he creado un proyecto de ejemplo destacando el tema. git.io/v5SWx
    • Yo diría que normalmente debe crear el esquema manualmente – ddl-auto es sólo un juguete para su uso en sandbox
    • De esta manera la instancia será crear en cada proceso de inicio, a la derecha? así, será necesario activar la bandera para truncar la DB para las instancias no son duplicados. Estoy pensando en un primer usuario admin por ejemplo, ¿cómo puede ser controlada?
    • No tengo idea de lo «ejemplo» de que estás hablando, pero en cualquier caso, usted probablemente debería hacer una nueva pregunta.
    • respuesta más rápida de la historia! 🙂 La respuesta fue que ya existe, debe haber leído detenidamente. El .archivo de sql sólo se ejecutará si la primavera.jpa.hibernate.ddl-auto=(crear|crear-drop) Por ejemplo me refiero a cualquier objeto de cualquier clase.
    • Lo tienes mal, aunque, la schema.sql/data.sql archivos será ejecutado cuando spring.datasource.initialize es true (que es el predeterminado). spring.jpa.hibernate.ddl-auto puede ser utilizado para generar las tablas que se basan en su entidad de configuración en lugar de utilizar un archivo SQL. Este es por defecto activado en la memoria de bases de datos. Por eso he añadido la nota en mi respuesta, explicando que si se utiliza una base de datos en memoria y desea utilizar el schema.sql, deberá desactivar spring.jpa.hibernate.ddl-auto de lo contrario, ambos intentarán crear la tabla.
    • Si desea utilizar el data-h2.sql nombre de archivo para el inicial de datos, debe configurar spring.datasource.platform=h2 en sus propiedades de la aplicación así.
    • Los datos.archivo sql que se ejecuta cada vez la primavera de inicio de la aplicación es disparado. Esto significa que si usted tiene instrucciones insert, pueden causar una org.h2.jdbc.JdbcSQLException-excepción, porque el datos ya está presente en la base de datos. Estoy usando una base de datos H2 embebida, pero el problema sigue siendo el mismo.
    • Es cierto, eso significa que significa que usted debe hacer que su archivo SQL adaptarse a él (por ejemplo. eliminar todos los registros de antemano, o insertar sólo cuando no existe).
    • lamentablemente, eso es todo, pero es fácil, porque la base de datos H2 por ejemplo tiene problemas con MERGE INTO. Me di cuenta, de que hay una forma de evitar esto mediante una importar.sql archivo en lugar de una datos.sql. Se requiere spring.jpa.hibernate.ddl-auto a crear o create-drop. A continuación, cuando el esquema se crea el archivo (y/o esquema.sql se ejecuta), la importar.sql se ejecuta así. Todavía: se siente como una solución y no una limpia ejecución de la creación de inicialización de datos.
    • Lo que si quiero generar 100000 entidades con valores aleatorios? de datos.sql no parece una buena solución.
    • Esto realmente debe ser aceptada respuesta, en mi opinión.
    • Puede utilizar la primavera.jpa.hibernate.ddl-auto=actualizar si desea permitir la hibernación para crear faltan columnas y tablas, incluso después de la ejecución de los scripts
    • Mi requisito es crear otro archivo, que deben trabajar exactamente igual a la de datos.sql, que utiliza la misma base de datos y las credenciales. Por ello, la necesidad de tener diferente .archivos de sql a ejecutar durante springboot de inicio. Veo springboot ejecuta de datos.archivo sql y datos${plataforma}.sql. Desde mi plataforma no es diferente, no sé cómo avanzar hacia el futuro que el presente. ¿Alguien tiene una idea acerca de este
    • Creo que no entiendo muy bien tu pregunta. De todos modos, siempre puedes crear un nueva pregunta.

  2. 66

    Si sólo desea insertar simple de los datos de prueba a menudo me implementar un ApplicationRunner. Implementaciones de esta interfaz se ejecutan al inicio de la aplicación y puede usarse, por ejemplo, un autowired repositorio para insertar algunos datos de prueba.

    Creo que este tipo de implementación podría ser un poco más explícito que la suya, porque la interfaz implica que su aplicación contiene algo que te gustaría hacer directamente después de que su solicitud está listo.

    Su implementación sería sth. como este:

    @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"));
        }
    }
    • public void run(); el método debe ser público
  3. 26

    Como sugerencia intente esto:

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

    Opción 2: Inicializar con el esquema y los datos de secuencias de comandos

    Requisitos previos: en application.properties tienes que mencionar esto:

    spring.jpa.hibernate.ddl-auto=none (de lo contrario los guiones serán ignorados por hibernate, y que se va a escanear proyecto para @Entity y/o @Table anotado clases)

    Luego, en su MyApplication clase pegar esto:

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

    Donde scripts carpeta se encuentra en resources carpeta (IntelliJ Idea)

    Espero que ayude a alguien

    • La opción 2 es grande, ya que le da explícito prueba de lo que está sucediendo. Con múltiples orígenes de datos, especialmente, puede ser necesario deshabilitar la Primavera DataSourceAutoConfiguration.class en caso que todos los demás datos.sql y el esquema.sql soluciones aquí dejar de trabajar.
    • Si desea cargar los datos iniciales, pero aún desea que Hibernate para crear el DDL pero tiene varios orígenes de datos y ponerlos manualmente, entonces la mejor opción en este caso es declarar la Primavera del DataSourceInitializer bean como por stackoverflow.com/a/23036217/3092830 como se toma de la @PostConstruct problema para usted.
  4. 23

    Puede agregar un spring.datasource.data propiedad application.properties listado de los archivos de sql que queremos ejecutar. Como este:

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

    El sql insert en cada uno de estos archivos, a continuación, ejecutar, lo cual permite mantener las cosas ordenadas

    • en caso de que desee un archivo externo no olvides poner file: en lugar de classpath:.
  5. 13

    Puedes usar algo como esto:

    @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. 8

    Primavera de Arranque le permite utilizar una simple secuencia de comandos para inicializar la base de datos, utilizando La Primavera Lote.

    Aún así, si quieres usar algo un poco más elaborado para administrar versiones DB y así sucesivamente, en la Primavera de Arranque se integra bien con El corredor de.

    Ver también:

    • lo que sugiere la primavera lote de aquí parece una exageración.
    • el OP no hablar de la cantidad de datos.. de todos Modos la respuesta no es todo acerca de spring batch.
    • En mi opinión, el Corredor de o Liquibase es la manera correcta de ir. No estoy seguro sobre el comentario de Nick y aún más acerca de la upvotes de /src/main/resources. Sí, el último trabajo para proyectos pequeños. La respuesta de Xtreme Ciclista da a través de muy pequeño esfuerzo para mucha más funcionalidad.
  7. 7

    En la Primavera de Arranque de datos 2.sql no estaba trabajando conmigo como en la primavera de arranque de 1,5

    de importación.sql

    Además, un archivo denominado import.sql en la raíz del classpath es ejecutado en el inicio si Hibernate crea el esquema de la nada (es decir, si el ddl-auto de la propiedad se establece para crear o create-drop).

    Nota muy importante si usted inserte las Llaves no pueden ser duplicados no utilice ddl-auto propiedad está configurado para actualizar ya que con cada reinicio insertar mismos datos

    Para obtener más información, visite la primavera websit

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

  8. 6

    Aquí es la manera que tengo de que:

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

    Gracias al autor de este artículo:

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

    • Esto no funciona si usted está utilizando el servicio, y si el servicio autowiring repositorio
  9. 4

    Usted puede simplemente crear un import.sql archivo en src/main/resources y de Hibernación, se ejecutará cuando el esquema es creado.

  10. 3

    He resuelto un problema similar de esta manera:

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

    Si alguien está luchando en hacer que esto funcione, incluso después de la aceptado respuesta, para mí, sólo el trabajo de agregar en mi src/test/resources/application.yml el H2 datasource detalles:

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

    puede registrarse y detector de eventos para lograr que, como el de abajo:

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

    Cuando el ContextRefreshEvent es despedido, tenemos acceso a todas autowired frijoles en la aplicación — incluyendo modelos y repositorios.

  13. 0

    Esto también 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)));
            };
        }
  14. 0

    El más compacto (para los datos dinámicos) poner @mathias-dpunkt solución en MainApp (con 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()));
      }
    }
  15. 0

    Si desea insertar sólo unas pocas filas y u tienen JPA Instalación. Usted puede usar debajo de

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

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea