初始化数据库和导入数据

摘要:
虽然通过编程添加初始数据既快捷又方便,但从长远来看,这不是一个好方法——尤其是当要添加的数据量很大时。我们最好将数据库准备、数据库修改和数据库配置与要运行的程序代码分开,尽管这仅适用于测试用例。SpringBoot提供了两种方法来定义数据库的表结构和添加数据。

Spring Boot应用的测试一文中,我们在StarterRunner类的run(...)方法中给数据库中添加一些初始数据。尽管通过编程方式添加初始数据比较快捷方便,但长期来看这并不是一个好办法——特别是当需要添加的数据量很大时。我们开发最好把数据库准备、数据库修改和数据库的配置与将要运行的程序代码分离,尽管这仅仅是为测试用例做准备。Spring Boot已经提供了相应的支持来完成这个任务。

我们在之前的应用程序基础上进行实验。Spring Boot提供两种方法来定义数据库的表结构以及添加数据。第一种方法是使用Hibernate提供的工具来创建表结构,该机制会自动搜索@Entity实体对象并创建对应的表,然后使用import.sql文件导入测试数据;第二种方法是利用旧的Spring JDBC,通过schema.sql文件定义数据库的表结构、通过data.sql导入测试数据。

How Do

  • 首先,将现有的“编程式初始化数据”的代码注释掉,因此在StarterRunner中run方法中注释掉下列代码:
    @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());
    }
  • 在resources目录下新建import.sql文件(注意,SQL语句中指定的字段要与Hibernate自动生成的表的字段相同),该文件的内容如下:
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);
  • 现在运行测试用例,发现可以通过;
  • 第二种方法是获取Spring JDBC的支持,需要我们提供schema.sql和data.sql文件。现在可以将import.sql重命名为data.sql,然后再创建新的文件schema.sql。在删除数据表时,需要考虑依赖关系,例如表A依赖表B,则先删除表B。创建数据库关系的内容如下:
-- 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`)
);
  • 我们手动创建了数据库表结构,因此需要关掉Hibernate的自动创建开关,即在application.properties中设置spring.jpa.hibernate.ddl-auto = none
  • 运行测试,发现测试可以正常通过。

Note:个人建议是使用Hibernate的自动创建机制,当然这会少一点可定制性;最近更流行的是Mybatis,mybatis-spring-boot也可以使用,mybatis的可定制性更强。

分析

在Spring社区中常常可以通过使用各种组件,例如Spring JDBC、Spring JPA with Hibernate,或者Flyway、Liquidbase这类数据库迁移工具,都能实现类似的功能。

Note:Flyway和Liquidbase都提供数据库的增量迁移功能。当项目中需要管理数据库的增量变动,并且需要快速切换到指定的数据版本时,非常适合使用Flyway和Liquidbase,更多的信息可以参考http://flywaydb.org/http://www.liquibase.org/

在上文中我们使用了两种不同的方法来初始化数据库和填充测试数据

使用Spring JPA with Hibernate初始化数据库

这种方法中,由Hibernate库完成大部分工作,我们只需要配置合适的配置项,并创建对应的实体类的定义。在这个方案中我们主要使用以下配置项:

  • spring.jpa.hibernate.ddl-auto=create-drop配置项告诉Hibernate通过@Entity模型的定义自动推断数据库定义并创建合适的表。在程序启动时,经由Hibernate计算出的schema会用来创建表结构,在程序结束时这些表也被删除。即使程序强制退出或者奔溃,在重新启动的时候也会先把之前的表删除,并重新创建——因此"create-drop"这种配置不适合生产环境。PS:如果程序没有显式配置spring.jpa.hibernate.ddl-auto属性,Spring Boot会给H2这类的嵌入式数据库配置create-drop,因此需要仔细斟酌这个配置项。

  • 在classpath下创建import.sql文件供Hibernate使用,该文件中的内容是一些SQL语句,将会在应用程序启动时运行。尽管该文件中可以写任何有效的SQL语句,不过建议只写数据操作语句,例如INSERT、UPDATE等等。

使用Spring JDBC初始化数据库

如果项目中没有用JPA或者你不想依赖Hibernate库,Spring提供另外一种方法来设置数据库,当然,首先需要提供spring-boot-starter-jdbc依赖。

  • spring.jpa.hibernate.ddl-auto=none表示Hibernate不会自动创建数据库表结构。在生产环境中最好用这个设置,能够避免你不小心将数据库全部删除(那一定是一个噩梦)。

  • schema.sql文件包含创建数据库表结构的SQL语句,在应用程序启动过程中,需要创建数据库表结构时,执行该文件中的DDL语句。Hibernate会自动删除已经存在的表,如果我们希望只有某个表不存在的时候才创建它,可以在这个文件开头最好先使用DROP TABLE IF EXISTS删除可能存在的表,再使用CREATE TABLE IF NOT EXISTS创建表。这种用法可以灵活得定义数据库中的表结构,因此在生产环境中用更安全。

  • data.sql的作用跟上一个方法的import.sql一样,用于存放数据导入的SQL语句。

考虑到这是Spring的特性,我们可以不只是全局定义数据库定义文件,还可以针对不同的数据库定义不同的文件。例如,可以定义给Oracle数据库使用的schema-oracle.sql,给MySQL数据库用的schema-mysql.sql文件;对于data.sql文件,则可以由不同数据库共用。如果你希望覆盖Spring Boot的自动推断,可以配置spring.datasource.platform属性。

Tip:如果你希望使用别的名字代替schema.sql或者data.sql,Spring Boot也提供了对应的配置属性,即spring.datasource.schemaspring.datasource.data


链接:https://www.jianshu.com/p/468a8fa752a7
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处

免责声明:文章转载自《初始化数据库和导入数据》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mybatis.mapper-locations 配置多个mapper路径c#web中定义全局变量,传递变量下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

JPA学习(二、JPA_基本注解)

框架学习之JPA(二)JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。 Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。 学习...

JAVA调用数据库存储过程

1.首相给数据库创建一个简单的存储过程:(在这里我是创建的Oracle数据库的存储过程) create or replace procedure stu_upd(nname varchar2,npassword varchar2) isbegin update student set name=nname where password=npassword;...

linux安装mysql8.0.25

一、安装 准备工作 官网下载链接:https://dev.mysql.com/downloads/mysql/ cd /usr/local # 创建mysql目录 mkdir mysql # 进入目录 cd mysql 将下载之后的包(mysql-8.0.25-linux-glibc2.12-x86_64.tar.xz) 上传到/usr/local/m...

浅析vue实例的生命周期(生命周期钩子)

“每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等” ,在不同的生命周期内会经历不同的钩子函数(生命周期函数),这就提供了将我们自己的代码写入的机会。如果将生命周期比作人的话,生命周期就是一个人的一生,生命钩子函数就相当于人的不同年龄段(幼年、青年、中年、老年)...

【Oracle】Oracle安装配置、创建数据库实例及用户和连接

https://blog.csdn.net/wudiyong22/article/details/78904361 参考资料:https://www.cnblogs.com/hoobey/p/6010804.html 一、Oracle下载 注意Oracle分成两个文件,下载完后,将两个文件解压到同一目录下即可。 路径名称中,最好不要出现中文,也不要出现空格...

禅道数据库

一、准备 已经在linux上搭建好禅道系统 二、添加数据库用户 禅道数据库管理用的是adminer,但是为了安全,访问adminer的时候需要身份验证,需要在服务器运行/opt/zbox/auth/adduser.sh来添加用户首先确保服务是启动的(mysql和apache启动状态),先 cd /opt/zbox/auth/,然后执行 ./adduser....