专栏首页软件测试那些事H2试镜记录-扮演ORACLE

H2试镜记录-扮演ORACLE

在利用H2推广实施单元测试的过程中,遇到和解决了一些问题,在此记录一下。

项目背景

金融行业传统的业务系统,重度使用ORACLE 数据库,包括很多业务逻辑是采用存储过程(SP)实现的。目前正在进行去SP化,采用的是SSM的技术栈。

Oracle数据库->H2数据库

1 数据库删表出错

原因:由于早期DDL 编写不规范,在drop 表时没有加上if exists 的判断 drop table if exists users; 导致DDL导入执行时出错。 结果办法: 考虑到与线上DDL一致性,只能采取修改如下配置的方式进行: spring.datasource.continue-on-error=true 在初始化数据库时,遇到错误是否继续,默认false

2 多个DDL/DCL/DDL文件导入

在我们的项目中,数据结构是如下的约定的 02-table/.sql //建表 03-interface/.sql //数据库接口 04-grant/.sql //授权 99-init/.sql //初始化数据 因此,需要按照顺序依次进行导入。

因此,需要修改Spring的配置文件如下:

spring.datasource.schema=classpath:/db/02table/schema*.sql
spring.datasource.data=classpath:/db/99init/data.sql,classpath:/db/99init/data2.sql

笔者采用了以下项目作为demo https://github.com/xhuanlee/spring-boot-junit-example.git 假设分别有两个*.sql文件在02-table和99init目录,执行结果如下:

2018-07-28 21:09:19.801  INFO 21256 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from file [D:\repo\spring-boot-junit-example-master\target\test-classes\db\02table\schema.sql] in 19 ms.
2018-07-28 21:09:19.801  INFO 21256 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from file [D:\repo\spring-boot-junit-example-master\target\test-classes\db\02table\schema2.sql]
2018-07-28 21:09:19.802  INFO 21256 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from file [D:\repo\spring-boot-junit-example-master\target\test-classes\db\02table\schema2.sql] in 1 ms.
2018-07-28 21:09:19.804  INFO 21256 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [db/99init/data.sql]
2018-07-28 21:09:19.808  INFO 21256 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [db/99init/data.sql] in 3 ms.
2018-07-28 21:09:19.808  INFO 21256 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [db/99init/data2.sql]
2018-07-28 21:09:19.809  INFO 21256 --- [           main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [db/99init/data2.sql] in 1 ms.

DML(data manipulation language): 它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言 DDL(data definition language): DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用 DCL(Data Control Language): 是数据库控制功能。是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。在默认状态下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人员才有权力执行DCL

3 sequence

曾经遇到过一个奇葩的Oracle sequence

CREATE SEQUENCE customers_seq
 START WITH     1000
 INCREMENT BY   1
 MAXVALUE   999999999......(这里有28个9)
 NOCACHE
 NOCYCLE;

问题:根据Oracle 官方文档,oracle数据库sequence最大支持28位。 Specify the maximum value the sequence can generate. This integer value can have 28 or fewer digits. MAXVALUE must be equal to or greater than START WITH and must be greater than MINVALUE. 而H2数据库的定义中sequence是一个long型, Long numbers are between -9223372036854775808 and 9223372036854775807. 很明显,这个28个9的sequence是无法导入h2的 解决办法:和开发同学协商是否有必要用28个9。不行的化,退而求其次,在测试环境下用不同的sql。

4 Web Console

在与开发同学沟通的过程中,有开发同学指出,在他们的开发过程中,一般都是通过pl/sql等连接ORACLE数据库进行数据表的相关开发工作,这部分DDL/DML的操作也是在开发的最后才作为版本的内容提交进代码库。 如果改用H2内存数据库进行开发/测试,则希望提供一个console,便于查看数据库结构和数据库中的内容。 H2是提供了web console 以及TCP连接的。

conncct_h2.JPG

h2_webconsole.JPG

如果是Srpingboot的话,需要在application.properties文件中增加两个配置项目

spring.h2.console.enabled=true
spring.h2.console.path=/console
server.port=8888

然后就可以通过http://localhost:8888/console来访问H2的数据库了。 当然笔者并不认为这是一个好的解决方案。由于最终的线上数据库还是Oracle,笔者还是建议开发人员通过PL/SQL连接ORACLE进行数据库相关的开发工作。需要变化的是,像随时提交代码一样,提交数据库的代码到代码库中。也就是将Oracle数据库导出成的DDL/DML的文件,然后再通过H2编写和执行单元测试用例。

多层嵌套临时表

在H2推广的过程中发现,某些开发人员编写了特别复杂的SQL,尤其是重度使用临时表进行嵌套。当嵌套层数超过4层时,H2的不能支持了,虽然H2在其官方文档中表示其支持临时表。 作为临时的解决方案,也只能是把这种类型的用例请出单元测试的范围了。

本文分享自微信公众号 - 软件测试那些事(antony-not-available),作者:风月同天测试人

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • DataBaseRider实现跨多个数据库的操作

    本文介绍如何在SpringBoot项目中,使用Junit5 + DataBaseRider实现跨多个数据库的操作。

    Antony
  • DataSet导入三个坑

    外键是一个常见的保证数据库内容完整性的一种方式。当然现在出于性能考虑,在互联网企业中比较少甚至禁止使用外键。在DBRider中,提供了以下的与外键相关的功能 1...

    Antony
  • 数据库测试的新选择Database-Rider

    本文重点安利Database-Rider这个基于DBUnit的新轮子,着急的读者可以直接拉到最底下去了解。想看笔者唠嗑的可以顺序往下看,了解DBUnit以及Ut...

    Antony
  • 为了给你们讲清楚数据库中间件有哪些,我也是拼了!

    卖羊肉串首先就得有羊肉,于是我就联系了很多养殖场,我又是一个比较负责任的人,为了保证羊肉的质量,我就去考察了一家又一家养殖场,同时我也是个“小气”的人,所以我考...

    Java技术江湖
  • 数据库减负的八个思路 轻松应对海量存储难题

    传统的企业级应用,其实很少会有海量应用,因为企业的规模本身就摆在那里,能有多少数据?高并发?海量数据?不存在的! 不过在互联网公司中,因为应用大多是面向广大人...

    数据和云01
  • laravel使用数据库测试注意事项

    相对于其它测试,数据库测试可以说是相对复杂繁琐的,因为数据库测试不可避免地会涉及到数据库的增删改查,而这些操作会影响数据库的数据,而我们测试最忌讳的就是修改了数...

    砸漏
  • 给数据库减负的八个思路,盘它!

    传统的企业级应用,其实很少会有海量应用,因为企业的规模本身就摆在那里,能有多少数据?高并发?海量数据?不存在的!

    数据和云
  • Django学习之旅(六)

    本文是 Django 学习之旅的完结篇,主要是讲述 model 层。model 层是与数据库打交道的,其中包括 怎么连接数据库、怎么对数据库进行增删改查等。主要...

    猴哥yuri
  • 智能时代,企业如何“聚数为智”加速数字化转型?

    墨墨导读:2020年11月20日,一年一度的数据技术嘉年华(DTC)如约而至,今年正值DTC举办的第十个年头,大会以“自研·智能·新基建——云和数据促创新 生态...

    数据和云
  • 无需数据迁移的水平分库方案

    在工作中,曾经做过一个项目,采用了哈希取模的方法进行水平分库,这种方法简单高效,但是在数据库规模有所变动的时候,需要做数据迁移。本文介绍一个自己拍脑袋想出来的一...

    Venyo

扫码关注云+社区

领取腾讯云代金券