初始化数据库和导入数据

简介:

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



相关文章
|
12天前
|
SQL 存储 Linux
从配置源到数据库初始化一步步教你在CentOS 7.9上安装SQL Server 2019
【11月更文挑战第8天】本文介绍了在 CentOS 7.9 上安装 SQL Server 2019 的详细步骤,包括系统准备、配置安装源、安装 SQL Server 软件包、运行安装程序、初始化数据库以及配置远程连接。通过这些步骤,您可以顺利地在 CentOS 系统上部署和使用 SQL Server 2019。
|
13天前
|
SQL 存储 Linux
从配置源到数据库初始化一步步教你在CentOS 7.9上安装SQL Server 2019
【11月更文挑战第7天】本文介绍了在 CentOS 7.9 上安装 SQL Server 2019 的详细步骤,包括系统要求检查与准备、配置安装源、安装 SQL Server 2019、配置 SQL Server 以及数据库初始化(可选)。通过这些步骤,你可以成功安装并初步配置 SQL Server 2019,进行简单的数据库操作。
|
1月前
|
数据库连接 数据库 数据安全/隐私保护
网站初始化数据库错误
网站初始化数据库错误
|
1月前
|
SQL Shell 数据库
在TDengine容器中创建初始化数据库的Shell命令实例
以上就是在Docker容器环境中部署并初始化TDengine数据库的全过程,希望对你有所帮助。
65 0
|
3月前
|
存储 Serverless API
Serverless 架构实现弹幕场景问题之在initializer方法中初始化数据库实例如何解决
Serverless 架构实现弹幕场景问题之在initializer方法中初始化数据库实例如何解决
29 0
|
3月前
|
安全 关系型数据库 MySQL
MySQL非root安装-初始化数据库时unknown variable ‘defaults-file=**/my.cnf‘
解决安装过程中出现的问题通常需要仔细地检查错误日志、配置文件和执行命令,保证各项配置设置的精确无误是顺利完成安装的关键。通过上述的步骤分析和解决方案,非root用户安装MySQL时遇到"unknown variable 'defaults-file=**/my.cnf'"的问题应该可以得到妥善的解决。
303 0
|
4月前
|
存储 小程序 数据库
【微信小程序-原生开发】实用教程08 - 开通微信云开发,操作云数据库新增数据(含修改数据权限),初始化云服务(含获取微信云环境 id),获取云数据,滚动公告栏
【微信小程序-原生开发】实用教程08 - 开通微信云开发,操作云数据库新增数据(含修改数据权限),初始化云服务(含获取微信云环境 id),获取云数据,滚动公告栏
73 0
|
12天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
26 1
|
14天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
29 4
|
21天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
102 1