DB2双感叹号!!运算符验证及H2内存数据库JUnit4单元测试实现
问题解答
1 DB2中!!运算符的实际作用
DB2原生默认没有将!!纳入公开官方运算符,你观察到的字符串拼接效果,是因为当前使用的DB2实例开启了MySQL兼容模式(SQL_COMPAT参数值为MYS),该兼容模式下会将!!映射为字符串拼接操作,等效于标准SQL的CONCAT函数、或DB2默认模式下的||拼接运算符。这类兼容扩展语法默认不会在通用官方文档中展示,仅在对应兼容参数开启时生效。
2 基于JUnit4 + H2内存数据库适配DB2特殊语法的实现方案
你不需要修改原有业务查询语句,可以通过H2的自定义运算符、自定义函数能力适配DB2的特殊语法,实现步骤如下:
2.1 准备H2初始化脚本
在测试资源目录下新建h2_init.sql,用于自定义DB2特殊语法对应的实现,此处针对!!运算符的适配语句如下:
-- 自定义!!运算符实现字符串拼接,对齐DB2兼容模式下的行为 CREATE OPERATOR IF NOT EXISTS !! FOR (VARCHAR, VARCHAR) RETURNS VARCHAR AS $$ SELECT CONCAT(?1, ?2) $$;
如果后续有其他DB2特殊语法,也可以在该脚本中通过CREATE OPERATOR(自定义运算符)、CREATE ALIAS(自定义函数)的方式统一适配。
2.2 编写JUnit4测试用例
示例测试代码如下(基础JDBC场景,若使用Spring等框架可对应调整数据源配置即可):
import org.junit.BeforeClass; import org.junit.Test; import java.sql.*; import static org.junit.Assert.assertEquals; public class DB2QueryTest { private static Connection connection; @BeforeClass public static void initH2Database() throws SQLException { // H2连接配置:开启DB2基础兼容,指定初始化脚本执行自定义语法适配 String jdbcUrl = "jdbc:h2:mem:testdb;MODE=DB2;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'classpath:h2_init.sql'"; connection = DriverManager.getConnection(jdbcUrl, "sa", ""); // 初始化测试表与测试数据 try (Statement stmt = connection.createStatement()) { stmt.execute("CREATE TABLE table1 (col1 VARCHAR(20), col2 VARCHAR(20))"); stmt.execute("INSERT INTO table1 VALUES ('test', '123'), ('hello', 'world')"); } } @Test public void testDoubleExclamationConcatQuery() throws SQLException { String originalQuery = "select col1!!col2 as concat_res from table1"; try (Statement stmt = connection.createStatement(); ResultSet resultSet = stmt.executeQuery(originalQuery)) { // 校验拼接结果符合预期 resultSet.next(); assertEquals("test123", resultSet.getString("concat_res")); resultSet.next(); assertEquals("helloworld", resultSet.getString("concat_res")); } } }
内容的提问来源于stack exchange,提问作者geco17
相关产品推荐
相关产品推荐

