初始化数据库和导入数据

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

时间: 2024-10-31 22:40:49

初始化数据库和导入数据的相关文章

《R语言数据分析》——1.4 从数据库中导入数据

1.4 从数据库中导入数据 使用一个专用的数据库测试平台比根据需要从磁盘中导入文件效率要高很多,这是由数据库本身特性决定的: 对大数据表的访问速度更快 在数据导入R前,提供了更快更有效的数据聚集和筛选方法 相比电子表格以及R对象实现的传统矩阵模型,能够提供更加结构化的关系 数据模型来存储数据 提供对数据的连接及合并操作 在同一时间支持对多个客户端的并发远程访问 提供了安全和有限的访问 提供可扩展及可配置的数据存储后台 DBI包提供了数据库操作的接口,可以作为R和不同关系数据管理系统(Relati

使用navicat 8实现创建数据库和导入数据 管理用户与权限[图文方法]_Mysql

下面看图使用该工具创建数据库和导入数据.navicat 8 下载地址 1 2 3 4 5 6 7 8 9 10 11 12.教程完毕.  2,管理建立用户和分配用户权限       在这里,我们可以发现root是MySQL最高级别权限的用户,它拥有查看.修改和删除MySQL软件中所有数据库的权限.当需要有多个数据库,并且分配给不同的用户使用,多个用户之间只有查看自己对应数据库的权限,不相互干扰,那么需要怎么做呢?       答案很简单,建立多个数据库和用户,给用户设置管理指定数据库的权限.操作

ASP安装SQL数据库和导入数据和建立用户

导入数据|数据库 <%'on error resume next action=request("action")IF action<>"install" THEN%><BR><center><form method="POST" action="install.asp?action=install" name="form1">填写安装信息<

不同字符集的数据库之间导入数据的方法

以US7ASCII的库中导出的数据导入到字符集为ZHS16GBK的库为例子: 假设US7ASCII的库是A机,字符集为ZHS16GBK的库为B机 1.确定你A机上的oracle用户的.profile文件中的NLS_LANG是US7ASCII,正常的导出所有数据. 2.然后传到B机上,bin模式,然后在B机上设定好oracle用户的设定环境变量NLS_LANG=AMERICAN_AMERICA.US7ASCII 以sys用户执行update props$ set values$='US7ASCII

在不同字符集的数据库之间导入数据的方法

以US7ASCII的库中导出的数据导入到字符集为ZHS16GBK的库为例子: 假设US7ASCII的库是A机,字符集为ZHS16GBK的库为B机 1.确定你A机上的oracle用户的.profile文件中的NLS_LANG是US7ASCII,正常的导出所有数据. 2.然后传到B机上,bin模式,然后在B机上设定好oracle用户的设定环境变量NLS_LANG=AMERICAN_AMERICA.US7ASCII 以sys用户执行update props$ set values$='US7ASCII

导入数据时遇见ORA-00054

今天应开发人员要求对一个表进行导入.发现如下错误: ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired ORA-00955: name is already used by an existing object 经过查看锁的使用情况,发现有开发人员对要导入的表进行dml操作. 下面模拟一下环境:. session 1: yang@rac1>update t set b=1 where a=4;

kettle java 内存溢出-java调用kettle导入数据内存溢出!!!!!

问题描述 java调用kettle导入数据内存溢出!!!!! 现在用java调用kettle的ktr模板往数据库中导入数据.kettle版本为4.2.0,oracle版本为11g. 无论jvm设置多大,只要文件数量比较多,内存会一直涨到溢出.调用过程就创建多个ktr对象TranMete,然后放在Trans里面运行. 求大神解决问题. 解决方案 提交数量改小点试试?

sqlite-如何将导入到数据库表中的数据保存在程序中,而不用每次换调试机时还得重新导入数据

问题描述 如何将导入到数据库表中的数据保存在程序中,而不用每次换调试机时还得重新导入数据 如题:我有一张excel的表,我将其存为.csv文件,然后通过dos命令下的sqlite3命令导入到了数据库表中,问题是如果不换机子,导入到该数据库表中的数据永久有效.如果我换机子调试的话,该数据库表中的数据就不存在了,会报错,请问有没有解决办法?谢谢! 解决方案 最好存入远程数据库每次启动同步下来数据就可以了,sqlite是系统自带的数据库具体的就是http://blog.csdn.net/tianyit

Excel2007教程:导入数据与链接数据库

Excel 2007拥 有强大的数据整理.分析能力,能够帮助我们完成日常工作中大部分的数据处理任务.要整理.分析数据,首先必须把数据装进Excel里面.除了逐一录入而 外,导入.连接数据库也是让Excel获得数据信息的重要方法.今天的专题主要以最新的Excel 2007为对象,介绍如何快速把各种数据导入Excel中,以及如何与外部数据库进行连接.另外,我们还推荐一些与Excel数据处理的相关内容. Excel工作簿连接(导入)外部数据的方法 Excel连接外部数据的主要好处是可以在Excel中定