Initialize the database and import data

In the Spring Boot application testing article, we add some initial data to the database in the run(...) method of the StarterRunner class . While adding initial data programmatically is quick and convenient, it's not a good idea in the long run -- especially if the amount of data that needs to be added is large. We develop it best to separate database preparation, database modification, and database configuration from the program code that will be run, although this is only in preparation for test cases. Spring Boot already provides corresponding support to accomplish this task.

We conduct experiments on the basis of the previous application. Spring Boot provides two ways to define the table structure of the database and add data. The first method is to use the tools provided by Hibernate to create the table structure, the mechanism will automatically search for @Entity entity objects and create the corresponding table, and then use the import.sql file to import the test data; the second method is to use the old Spring JDBC , define the table structure of the database through the schema.sql file, and import the test data through data.sql.

How Do

  • First, comment out the existing "programmatic initialization data" code, so comment out the following code in the run method of StarterRunner:
    @Override
    public void run(String... strings) throws Exception {
//        Author author = new Author("du", "qi");
//        authorRepository.save(author);
//        Publisher publisher = new Publisher("中文测试");
//        publisherRepository.save(publisher);
//        Book book = new Book(author, "9876-5432-1111", publisher, "瞅啥");
//        book.setDescription("23333333,这是一本有趣的书");
//        bookRepository.save(book);
        logger.info("Number of books: " + bookRepository.count());
    }
  • Create a new import.sql file in the resources directory (note that the fields specified in the SQL statement must be the same as the fields of the table automatically generated by Hibernate), the content of the file is as follows:
INSERT INTO author (id, first_name, last_name) VALUES (1, 'Alex', 'Antonov');
INSERT INTO publisher (id, name) VALUES (1, 'Packt');
INSERT INTO book (isbn, title, author, publisher) VALUES ('9876-5432-1111', 'Spring Boot Recipes', 1,1);
  • Now run the test case and find that it passes;
  • The second method is to get Spring JDBC support, which requires us to provide schema.sql and data.sql files. You can now rename import.sql to data.sql and then create a new file schema.sql. When deleting data tables, you need to consider dependencies. For example, if table A depends on table B, then delete table B first. The content of creating a database relationship is as follows:
-- clear context
DROP TABLE IF EXISTS `book_reviewers`;
DROP TABLE IF EXISTS `reviewer`;
DROP TABLE IF EXISTS `book`;
DROP TABLE IF EXISTS `author`;
DROP TABLE IF EXISTS `publisher`;

-- Create syntax for TABLE 'author'
CREATE TABLE `author` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `first_name` VARCHAR(255) DEFAULT NULL ,
  `last_name` VARCHAR(255) DEFAULT NULL ,
  PRIMARY KEY (`id`)
);

-- Create syntax for TABLE 'publisher'
CREATE TABLE `publisher` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) DEFAULT NULL ,
  PRIMARY KEY (`id`)
);

-- Create syntax for TABLE 'book'
CREATE TABLE `book` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `description` VARCHAR(255) DEFAULT NULL ,
  `isbn` VARCHAR(255) DEFAULT NULL ,
  `title` VARCHAR(255) DEFAULT NULL ,
  `author` BIGINT(20) DEFAULT NULL ,
  `publisher` BIGINT(20) DEFAULT NULL ,
  PRIMARY KEY (`id`),
  CONSTRAINT `FK_publisher` FOREIGN KEY (`publisher`) REFERENCES `publisher` (`id`),
  CONSTRAINT `FK_author` FOREIGN KEY (`author`) REFERENCES `author` (`id`)
);

-- Create syntax for TABLE 'reviewer'
CREATE TABLE `reviewer` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `first_name` VARCHAR(255) DEFAULT NULL ,
  `last_name` VARCHAR(255) DEFAULT NULL ,
  PRIMARY KEY (`id`)
);

-- Create syntax for TABLE 'book_reviewers'
CREATE TABLE `book_reviewers` (
  `books` BIGINT(20) NOT NULL ,
  `reviewers` BIGINT(20) NOT NULL ,
  CONSTRAINT `FK_book` FOREIGN KEY (`books`) REFERENCES `book` (`id`),
  CONSTRAINT `FK_reviewer` FOREIGN KEY (`reviewers`) REFERENCES `reviewer` (`id`)
);
  • We manually created the database table structure, so we need to turn off Hibernate's automatic creation switch, that is , set spring.jpa.hibernate.ddl-auto = none in application.properties
  • Run the test and find that the test passes normally.

Note: My personal suggestion is to use Hibernate's automatic creation mechanism, which of course will be less customizable; Mybatis is more popular recently, mybatis-spring-boot can also be used, and mybatis is more customizable.

analyze

Similar functions can often be achieved in the Spring community by using various components, such as Spring JDBC, Spring JPA with Hibernate, or database migration tools such as Flyway and Liquidbase.

Note: Both Flyway and Liquidbase provide incremental migration of databases. When the project needs to manage the incremental changes of the database and needs to quickly switch to the specified data version, it is very suitable to use Flyway and Liquidbase. For more information, please refer to http://flywaydb.org/ and http://www. liquibase.org/ .

In the above we used two different methods to initialize the database and populate the test data

Initialize the database using Spring JPA with Hibernate

In this method, the Hibernate library does most of the work, we only need to configure the appropriate configuration items and create the definition of the corresponding entity class. In this scheme, we mainly use the following configuration items:

  • The spring.jpa.hibernate.ddl-auto=create-drop configuration item tells Hibernate to automatically infer the database definition and create the appropriate table from the @Entity model definition. When the program starts, the schema calculated by Hibernate is used to create the table structure, and these tables are also deleted at the end of the program. Even if the program is forced to quit or crashes, the previous table will be deleted and recreated when it is restarted - so the "create-drop" configuration is not suitable for production environments. PS: If the program does not explicitly configure the spring.jpa.hibernate.ddl-auto property, Spring Boot will configure create-drop for embedded databases such as H2, so this configuration item needs to be carefully considered.

  • Create an import.sql file under the classpath for Hibernate to use. The contents of this file are some SQL statements that will be run when the application starts. Although any valid SQL statement can be written in this file, it is recommended to write only data manipulation statements, such as INSERT, UPDATE, etc.

Initialize the database with Spring JDBC

If JPA is not used in the project or you don't want to depend on the Hibernate library, Spring provides another way to set up the database, of course, you need to provide the spring-boot-starter-jdbc dependency first.

  • spring.jpa.hibernate.ddl-auto=none means that Hibernate will not automatically create the database table structure. It's best to use this setting in a production environment, to avoid you accidentally deleting the entire database (which must be a nightmare).

  • The schema.sql file contains the SQL statement for creating the database table structure. During the application startup process, when the database table structure needs to be created, the DDL statement in this file is executed. Hibernate will automatically delete the existing table. If we want to create a table only when it does not exist, it is best to DROP TABLE IF EXISTSdelete the table that may exist at the beginning of this file, and then use the CREATE TABLE IF NOT EXISTScreate table. This usage allows the flexibility to define the table structure in the database, so it is safer to use in a production environment.

  • The function of data.sql is the same as import.sql of the previous method , which is used to store the SQL statement for data import.

Considering this is a feature of Spring, we can not only define the database definition file globally, but also define different files for different databases. For example, schema-oracle.sql for Oracle database and schema-mysql.sql file for MySQL database can be defined; for data.sql file, it can be shared by different databases. If you wish to override Spring Boot's automatic inference, you can configure the spring.datasource.platform property.

Tip: If you want to use another name instead of schema.sql or data.sql, Spring Boot also provides corresponding configuration properties, namely spring.datasource.schema and spring.datasource.data .


Link: https://www.jianshu.com/p/468a8fa752a7
Source: Jianshu The
copyright belongs to the author. For commercial reprints, please contact the author for authorization, and for non-commercial reprints, please indicate the source

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324724762&siteId=291194637