如何在测试中让H2支持JSONB

news/2024/7/9 19:38:39 标签: 数据库, postgresql, java, H2, 类型别名

如今在开发系统时,有各种各样的数据库供我们选择。之前我们在博客基于MariaDB4j实现持久层单元测试介绍了使用MariaD4j代替作为MySQL的替身执行单元测试,但是并不是所有的数据库都能找到合适的替身来执行单元测试。

今天作者在写测试的过程中就遇到了一个这样的问题。我们使用的数据库是PostgreSQL,Migration框架是Liquibase,单元测试过程中使用的数据库H2,并且数据表中用到了PostgreSQL的扩展类型JSONB。在执行测试过程时,报了未知数据类型异常:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.LiquibaseException: liquibase.exception.MigrationFailedException: Migration failed for change set liquibase/db.changelog-20230506.xml::modify_column_data_type::developer:
     Reason: liquibase.exception.DatabaseException: Unknown data type: "JSONB"; SQL statement:

请添加图片描述
映入脑中的第一个想法是重新写一套schema,并用这套schema初始化H2数据库,但这种方法会带来:

  • 额外的工作量
  • 每次修改schema都要同时修改两个地方

是否有更简单的办法来解决这个问题?我们知道H2支持很多中类型1
在这里插入图片描述
而JSONB和JSON两中类型非常相似(主要差别在存储格式和搜索性能上),能否通过为JSON定义一个JSONB的别名。于是通过搜索相关的SQL语法,果然找到了如下SQL语法2

CREATE TYPE metric_meter AS DOUBLE;
CREATE TYPE imperial_foot AS DOUBLE;

结合H2在建立链接是可以执行一下SQL语句3,瞬间让我找到了解决方法。

String url = "jdbc:h2:mem:test;INIT=runscript from '~/create.sql'\\;runscript from '~/init.sql'";

请添加图片描述
说了这么多,让我总结一下最终的解决方案吧!

首先:创建一个H2数据库的初始脚本init.sql(笔者是放在spring boot工程的test/resources目录下)。

#CREATE TYPE "JSONB" AS json;

然后:更改数据源链接配置(application-test.yml)。

spring:
  datasource:
    url: jdbc:h2:mem:test;INIT=runscript from 'classpath:init.sql'
    username: sa
    password: password
    driver-class-name: org.h2.Driver
  jpa:
    database-platform: org.hibernate.dialect.PostgreSQL95Dialect

有了【别名大法】,是不是以后就可以用H2作为很多关系型数据库的替身了,毕竟H2提供了几乎我们常用的所有数据类型。


  1. H2 DataTypes ↩︎

  2. SQL Standard User Defined Types and Routines ↩︎

  3. execute_sql_on_connection ↩︎


http://www.niftyadmin.cn/n/296213.html

相关文章

工业界NER

一、背景 由于工业界,比如搜索领域,文本领域实体识别往往除了在各个label下f1-score达到更高的要求以外,还需要考虑成本,效率,以及ner抽取出实体的下游应用场景的配合使用等情况。query-ner问题一般具有以下特点&…

d答复引用等问题

原文 :让ref成为TypeCtor,不是更简单地解决问题吗? 技术上,答案是肯定的,但现实是,答案不仅是否定的,而是:绝对不行. :虽然使用()是消除两个不同结构歧义的自然方法,但似乎导致问题的唯一情况是,无法在函数类型中表达"按引用返回". 这是开场白.我研究了可表达的各…

单片机GD32F303RCT6开发(二)—— systick的配置

systick的配置 1、GD官方F303系统的固件库中只提供ms的延时函数,采用的是中断的方式。 2、我们采用poll mode实现us、ms延时 RCU通过AHB时钟(HCLK)8分频后作为Cortex系统定 时器(SysTick)的外部时钟。通过对SysTick控制和状态寄存器的设置,可选择上述时…

请跟着我的思路来学习-->Android Handler机制

Handler简要使用说明: Handler往往使用在android中线程的通信,常见的使用是子线程给主线程发消息,然后更新UI。 但其实Handler还可以使用在任意俩个线程间的通信。 1.子线程向主线程发消息: private Handler mHandler new Handl…

细谈抽象类

目录 抽象类 1.抽象类是被abstract修饰的类 2.抽象类中的抽象方法 3.抽象类中可以有和普通类一样的成员变量和成员方法 4.抽象类不能被实例化 5.那么抽象类不能被实例化要它有何用??? 6.注意: 抽象类 如果一个类中没有包含足…

推荐一个免费的刷题网站

推荐一个免费的刷题网站 在学习编程的过程中,刷题是非常重要的一部分。而随着互联网的发展,许多刷题网站应运而生。今天,我想向大家推荐一个免费的刷题网站:LeetCode。 LeetCode是什么? LeetCode是一个致力于帮助程…

【软考-中级】系统集成项目管理工程师-计算题

系统集成项目管理工程师 二、计算题题型一:EMV(预期货币价值)题型二:加权系统题型三:自制和外贸决策——采购管理题型四:沟通渠道——沟通管理题型五:投资回收期、回收率题型六:进度…

推开“任意门”,华为全屋智能正在实现一代科幻迷的童年梦想

科幻作家亚瑟查理斯克拉克有句名言,“任何足够先进的科技,都和魔法无异”。 提到空间魔法,很多科技爱好者或科幻迷会想到哆啦A梦的“任意门”。通过那扇门,可以进入全新的世界,去任何想去的地方,是不少人在…