295

I'm wondering what the best way to load initial database data before the application starts? What I'm looking for is something that will fill my H2 database with data.

For example, I have a domain model "User" I can access users by going to /users but initially there won't be any users in the database so I have to create them. Is there anyway to fill the database with data automatically?

At the moment I have a Bean that gets instantiated by the container and creates users for me.

Example:

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

But I very much doubt that is the best way of doing it. Or is it?

Lithicas
  • 3,793
  • 7
  • 23
  • 32
  • 9
    That will work, or simply add `data.sql` and/or `schema.sql` to init data.. All this is [documented](http://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html) in the reference guide (which I suggest to read). – M. Deinum Jun 27 '16 at 05:47
  • Please mark the correct answer if that helped you. – Malakai Mar 08 '17 at 09:40

22 Answers22

455

You can create a data.sql file in your src/main/resources folder and it will be automatically executed on startup. In this file you can add some insert statements, eg.:

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

Similarly, you can create a schema.sql file (or schema-h2.sql) as well to create your schema:

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

Though normally you shouldn't have to do this since Spring boot already configures Hibernate to create your schema based on your entities for an in memory database. If you really want to use schema.sql you'll have to disable this feature by adding this to your application.properties:

spring.jpa.hibernate.ddl-auto=none

More information can be found at the documentation about Database initialization.


If you're using Spring Boot 2, database initialization only works for embedded databases (H2, HSQLDB, ...). If you want to use it for other databases as well, you need to change the initialization mode property:

spring.sql.init.mode=always # Spring Boot >=v2.5.0
spring.datasource.initialization-mode=always # Spring Boot <v2.5.0

If you're using multiple database vendors, you can name your file data-h2.sql or data-mysql.sql depending on which database platform you want to use.

To make that work, you'll have to configure the datasource platform property:

spring.sql.init.platform=h2 # Spring Boot >=v2.5.0
spring.datasource.platform=h2 # Spring Boot <v2.5.0
g00glen00b
  • 41,995
  • 13
  • 95
  • 133
  • Thank you @g00glen00b for clearing up : "and it will be automatically executed on startup". I was getting errors as I included the data.sql file in my bean's configuration using the addScript(s) option. As at this point the schema had not yet been built. – Benjamin Slabbert Apr 26 '17 at 07:40
  • I am having issue with the sequencing of creating the DB objects and running the data.sql. The script is run before creating the db entities. Here is my post on the issue:https://stackoverflow.com/questions/38040572/spring-boot-loading-initial-data?rq=1 – srini Sep 07 '17 at 15:57
  • Looks like above link is incorrect. https://stackoverflow.com/questions/46066575/spring-boot-data-initialization I have also created a sample project highlighting the issue. https://git.io/v5SWx – srini Sep 15 '17 at 21:10
  • I'd say that normally you must create schema manually - ddl-auto is just a toy to use in sandbox – xenteros Sep 26 '17 at 07:07
  • This way the instance will be create in every startup process, right? so you will need to activate flag to truncate the DB so instances are not duplicated. I am thinking in an initial admin user e.g. how can this be controlled? – nespapu Oct 11 '17 at 07:49
  • @nespapu I have no idea what "instance" you're talking about, but in either case, you should probably ask a new question. – g00glen00b Oct 11 '17 at 07:52
  • quickest answer ever! :) The answer was already there, should have read carefully. The .sql file will only be executed if spring.jpa.hibernate.ddl-auto=(create|create-drop) By instance I mean any object for whatever class. – nespapu Oct 11 '17 at 08:00
  • 9
    @nespapu You have it wrong though, the `schema.sql`/`data.sql` files will be executed when `spring.datasource.initialize` is `true` (which is the default). `spring.jpa.hibernate.ddl-auto` can be used to generate your tables based on your entity configuration rather than using a SQL file. This is by default enabled on in-memory databases. That's why I added the note in my answer, explaining that if you use an in-memory database and you want to use the `schema.sql`, you need to disable `spring.jpa.hibernate.ddl-auto` otherwise both will try to create your table. – g00glen00b Oct 11 '17 at 08:03
  • 9
    If you want to use the `data-h2.sql` filename for your initial data, you should set `spring.datasource.platform=h2` in your application properties as well. – Jason Evans Mar 29 '18 at 10:45
  • 2
    The data.sql file is executed **each time** the spring-boot application is fired up. This means that if you have insert statements, they may cause an `org.h2.jdbc.JdbcSQLException`-exception, because the **data is already present** in the database. I am using an embedded H2 database, but the problem stays the same. – Igor Apr 22 '18 at 10:22
  • @Igor True, that means that means you should make your SQL file adapt to it (eg. delete all records beforehand, or insert only when it doesn't exist). – g00glen00b Apr 22 '18 at 14:16
  • 2
    @g00glen00b sadly that's all but easy, because the H2 database for instance has trouble with `MERGE INTO`. I figured out, that there is a way to circumvent this using an **import.sql** file instead of a **data.sql**. It requires `spring.jpa.hibernate.ddl-auto` to **create** or **create-drop**. Then whenever the schema file is created (and/or a **schema.sql** is executed), the **import.sql** is executed as well. Still: it feels like a workaround and not a clean implementation of creating init data. – Igor Apr 23 '18 at 12:55
  • What if I want to generate 100000 entities with random values? data.sql doesn't look like a good solution. – s-kaczmarek Apr 03 '19 at 14:40
  • You can use spring.jpa.hibernate.ddl-auto=update if you want to let hibernate to create missing columns and tables even after running your scripts – Vadim Kirilchuk Aug 09 '19 at 09:31
  • My requirement is to create another file which must work exactly like data.sql, which uses the same db and credentials. So the need to have different .sql files to run during springboot start. I see springboot executes data.sql file and data-${platform}.sql. Since my platform is not different i dont know how to move forward which this. Does someone have an idea about this – Melvin Richard Sep 22 '19 at 10:03
  • @MelvinRichard I don't think I completely understand your question. Anyways, you can always create a [new question](https://stackoverflow.com/questions/ask). – g00glen00b Sep 22 '19 at 15:45
  • for multiple database doesnt work for me. my files name are as schema-h2.sql and data-h2.sql. – djavaphp Jan 20 '20 at 09:25
  • great. I have data.sql and schema.sql in src/test/resources. I am using this for integration tests. I simply added spring.datasource.initialization-mode=always to application.yml in src/test/resources. I am using SQLSERVER. – Apurva Singh Jun 03 '21 at 18:44
  • all these options won't work in case you are using : (exclude = { DataSourceAutoConfiguration.class }) – Tiago Medici Dec 07 '21 at 08:45
126

If I just want to insert simple test data I often implement a ApplicationRunner. Implementations of this interface are run at application startup and can use e.g. a autowired repository to insert some test data.

I think such an implementation would be slightly more explicit than yours because the interface implies that your implementation contains something you would like to do directly after your application is ready.

Your implementation would look sth. like this:

@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"));
    }
}
eenblam
  • 438
  • 1
  • 6
  • 20
Mathias Dpunkt
  • 11,594
  • 4
  • 45
  • 70
96

You can add a spring.datasource.data property to application.properties listing the sql files you want to run. Like this:

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

//or (depending on SB version)

spring.sql.init.data-locations=classpath:accounts.sql, classpath:books.sql, file:reviews.sql

The sql insert statements in each of these files will then be run, allowing you to keep things tidy.

If you put the files in the classpath, for example in src/main/resources they will be applied. Or replace classpath: with file: and use an absolute path to the file

If you want to run DDL type SQL then use:

spring.datasource.schema=classpath:create_account_table.sql

// depending on spring version

spring.sql.init.schema-locations=classpath:create_account_table.sql 

Edit: these solutions are great to get you up and running quickly, however for a more production ready solution it would be worth looking at a framework such as flyway, or liquibase. These frameworks integrate well with spring, and provide a quick, consistent, version-controlled means of initialising schema, and standing-data.

robjwilkins
  • 5,462
  • 5
  • 43
  • 59
50

There are multiple ways how to achieve this. I prefer to use one of following options:

Option 1: Initializing with CommandLineRunner bean:

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

Option 2: Initializing with schema and data SQL scripts

Prerequisites:

application.properties

spring.jpa.hibernate.ddl-auto=none

Explanation:

Without ddl-auto SQL scripts will be ignored by Hibernate and trigger default behavior - scanning project for @Entity and/or @Table annotated classes.

Then, in your MyApplication class paste this:

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

Where scripts folder is located under resources folder (IntelliJ Idea)

Hope it helps someone

Update 04-2021: Both options are great to combine with Spring Profiles as this will help you to avoid creating additional config files making your life as the developer easy.

Malakai
  • 3,011
  • 9
  • 35
  • 49
  • 4
    Option 2 is great as it gives explicit proof of what's happening. With multiple datasources especially it may be necessary to disable Spring's DataSourceAutoConfiguration.class in which case all the other data.sql and schema.sql solutions provided here stop working. – kaicarno May 18 '19 at 21:04
  • 1
    If you want to load initial data but still want Hibernate to create the DDL but you have multiple datasources and set them up manually, then a better option in this case is to declare Spring's DataSourceInitializer bean as per https://stackoverflow.com/a/23036217/3092830 as it will take of the @PostConstruct issue for you. – kaicarno May 18 '19 at 22:14
  • spring.jpa.hibernate.ddl-auto=none fixed my problem, as my data.sql file was ignored by JPA until I set the property. Many thanks. – Tomas Antos Apr 14 '21 at 08:40
17

You can use something like this:

@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"));
      };
   }
}
Grauzone
  • 215
  • 3
  • 10
15

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

Ismail
  • 1,668
  • 1
  • 15
  • 10
  • In Spring 2 database initialization only works for embedded databases If you want to use it for other databases you need to specify spring.datasource.initialization-mode=always – Edu Costa Dec 27 '19 at 16:22
12

Spring Boot allows you to use a simple script to initialize your database, using 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:

Aritz
  • 30,971
  • 16
  • 136
  • 217
  • 9
    suggesting spring batch here seems overkill. – Nick Jun 22 '18 at 16:10
  • @Nick, the OP does not mention the amount of data.. Anyway the answer is not all about spring batch. – Aritz Jun 22 '18 at 17:25
  • In my opinion, Flyway or Liquibase is the correct way to go. Not sure about the comment of Nick and further more about the upvotes of /src/main/resources. Yes, the latter would work for small projects. The answer of Xtreme Biker gives via very small effort so much more functionality. – Alexandros May 27 '19 at 07:19
10

You can simply create a import.sql file in src/main/resources and Hibernate will execute it when the schema is created.

Francesco Papagno
  • 617
  • 10
  • 29
10

If you came here and nothing seems to work for you, then it might be the case that you are affected from some changes that were introduced with Spring Boot 2.5 and onwards.

Here is the total set of properties which I use for postgresql.

spring:
  sql.init.mode: always   <-----------------
  datasource:
    url: jdbc:postgresql://localhost:5432/products
    username: 
    password: 
  jpa:
    defer-datasource-initialization: true  <------------------
    hibernate:
      ddl-auto: create-drop   <----------------
    database-platform: org.hibernate.dialect.PostgreSQLDialect

I have also marked with <--- the relevant properties for the current topic in order to achieve the following.

  • ORM vendor will create database schema for you from Java Entities model.
  • After database schema is created, initial data will be loaded to database from the file data.sql

Ps: Don't forget to add the file with initial data, data.sql under src/main/resources

Also as reference: Spring Boot 2.5 release notes

Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47
  • Do not let ORM to create schema/data. Data/schema has longer life than ormlib, so take control of data/schema outside ORM – Espresso Jun 29 '22 at 22:14
  • @Espresso I agree with you however for databases used for testing purposes this is the best way to go. The question also mentions h2 database which normally is used as test database. – Panagiotis Bougioukos Jun 29 '22 at 22:57
  • 1
    `defer-datasource-initialization: true` This is the line I was looking for thanks! It is a good idea for creating a local spring profile with H2 database plus this line. But I agree with others that you should always create/modify (with flyway for example) your schema on production database. – YoloAcc Jul 23 '22 at 13:54
8

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/

adkl
  • 634
  • 7
  • 17
5

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();
    }
}
A-Bag
  • 111
  • 2
  • 3
4

You're almost there!

@Component
public class DataLoader implements CommandLineRunner {

    private UserRepository userRepository;

    public DataLoader(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public void run(String... args) throws Exception {
         LoadUsers()
    }

    private void LoadUsers() {
        userRepository.save(new User("lala", "lala", "lala"));
    }
}
Emmanuel Osimosu
  • 5,625
  • 2
  • 38
  • 39
3

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.

Chandra Sekhar
  • 16,256
  • 10
  • 67
  • 90
Ahmed Ahmed
  • 1,036
  • 11
  • 16
1

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:
Dherik
  • 17,757
  • 11
  • 115
  • 164
1

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

     }
Niraj Sonawane
  • 10,225
  • 10
  • 75
  • 104
1

You can use the below code. In the following code a database insertion occurs during the startup of the spring boot application.

@SpringBootApplication
public class Application implements CommandLineRunner {
    
    @Autowired
    private IService<Car> service;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        for(int i=1; i<=1000; i++) {
            Car car = new Car();
            car.setName("Car Name "+i);
            book.setPrice(50 + i);
            service.saveOrUpdate(car);
        }
    }

}
Senthuran
  • 1,583
  • 2
  • 15
  • 19
1

If you want to do insert quick some queries, you can do with h2 data.sql queries as well

application.properties include:

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

data.sql file include:

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);

P.S.: data.sql file should be inside src/main/resources

Your @Entity include

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

That is it basically. it will be in memory, it means when you restart application data will arese and will be again same as queries show.

But it is easy for quick check

also you can access the path with http://localhost:8080/h2-console/ or you can edit the path from .properties file

ilia
  • 98
  • 1
  • 8
0

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)));
        };
    }
Udara S.S Liyanage
  • 6,189
  • 9
  • 33
  • 34
0

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()));
  }
}
Grigory Kislin
  • 16,647
  • 10
  • 125
  • 197
0

One possibility is using incorrect JDBC URL. make sure it is jdbc:h2:mem:testdb

abshar
  • 467
  • 1
  • 4
  • 8
0

I created a library that facilitates initial/demo data loading in a Spring Boot application. You can find it at https://github.com/piotrpolak/spring-boot-data-fixtures

Once the data fixtures starter is on the classpath, it will automatically try to load DICTIONARY data upon application startup (this behavior can be controlled by properties) - all you need to do is to register a bean implementing DataFixture.

I find loading initial data by code superior to loading it using SQL scripts:

  • the logic of your fixtures lives close to your application logic/domain model and it is subject to refactoring as your domain evolves
  • you benefit from incremental demo data updates - imagine a QA environment with some user data (that needs not to be lost after application deploy) but at the same time you want to add data for the new features you developed

Example data fixture:

/**
 * You can have as many fixture classes as you want.
 * @Order annotation is respected for the fixtures belonging to the same set.
 * You can make your demo database to be incrementally updated with fresh data
 * each time the application is redeployed - all you need to do is to write
 * a good condition in `canBeLoaded()` method.
 */
@Component
public class InitialDataFixture implements DataFixture {

    private final LanguageRepository languageRepository;

    // ...

    @Override
    public DataFixtureSet getSet() {
      return DataFixtureSet.DICTIONARY;
    }

    /**
     * We want to make sure the fixture is applied once and once only.
     * A more sophisticated condition can be used to create incremental demo data
     * over time without the need to reset the QA database (for example).
     */
    @Override
    public boolean canBeLoaded() {
      return languageRepository.size() == 0;
    }

    /**
     * The actual application of the fixture.
     * Assuming that data fixtures are registered as beans, this method can call
     * other services and/or repositories.
     */
    @Override
    public void load() {
      languageRepository.saveAll(Arrays.asList(
          new Language("en-US"), new Language("pl-PL")));
    }
}

The concept is inspired by the Symfony Doctrine Data Fixtures bundle.

Piotr Polak
  • 497
  • 4
  • 6
  • I think - over time - you'll find that you add more and more functionality into your `canBeLoaded()` method and then you might as well have gone with Liquibase or Flyway. One of the troubles that Liquibase solves for you is _concurrency_: What happens if your application is multi-node and several instances of your application start at the same time? And what about rollback if something unforseen happens? In what state is you db left then? These are hard problems to tackle and both Liquibase and Flyway have spent years ironing out the edges. – lbruun Apr 25 '21 at 06:35
0

For those using MysqlDriver, I tried using Init attribute of @bean annotation and it works.

After created the Schema and Data sql file in the path of resources\Scripts

Add the line in application.properties

spring.jpa.hibernate.ddl-auto=none

Edit the Application content:

package com.spring_mvaen.demo;

import org.springframework.boot.CommandLineRunner;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;

@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }
  @Override
  public void run(String... arg0) throws Exception {
    System.out.println("Hello world from Command Line Runner");
  }

  @Bean(name = "dataSource")
  public DriverManagerDataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/db_spring_rest?useUnicode=true&useLegacyDatetimeCode=fa    lse&serverTimezone=UTC&createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false");
    dataSource.setUsername("root");
    dataSource.setPassword("root");

    // schema init
    Resource initSchema = new ClassPathResource("scripts/schema.sql");
    Resource initData = new ClassPathResource("scripts/data.sql");
    DatabasePopulator databasePopulator = new ResourceDatabasePopulator(initSchema, initData);
    DatabasePopulatorUtils.execute(databasePopulator, dataSource);

    return dataSource;
  }


}
W Kenny
  • 1,855
  • 22
  • 33