[英]Testing: Incompatibility between MySQL and H2
我正在尝试使用 H2 测试我的 JPA 原生 @Query。 我的原生查询如下:
@Query(
value = "SELECT * FROM accounts " +
" WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
countQuery = "SELECT count(*) FROM accounts " +
" WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
nativeQuery = true
)
在编写单元测试时,我收到以下 H2 错误:
引起:org.h2.jdbc.JdbcSQLException:找不到表“ACCOUNTS”; SQL 语句:SELECT * FROM accounts WHERE 'aws_account_name' LIKE LOWER(CONCAT('%', COALESCE(?, ''), '%')) limit ? [42102-197]
我可以通过更改我的 SQL 语法将表名放在双引号中来修复 H2 错误:
@Query(
value = "SELECT * FROM \"accounts\" " +
" WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
countQuery = "SELECT count(*) FROM \"accounts\" " +
" WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
nativeQuery = true
)
但是,然后我的 MySQL(实际非测试环境)抱怨:
引起:java.sql.SQLSyntaxErrorException:你的SQL语法有错误; 检查与您的 MySQL 服务器版本相对应的手册,以获取在“帐户”附近使用的正确语法 WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE('ab', ''), ' at line 1
如何使用 MySQL 和 H2 测试此本机查询?
我使用本机查询而不是 JPQL 的原因是因为我需要在不区分大小写的情况下进行搜索并允许“包含”匹配。
默认情况下,MySQL 将双引号括起来的标记识别为字符串文字,而不是标识符(即表名或列名)。
如果我们修改 MySQL sql_mode
以包含ANSI_QUOTES
,那么用双引号括起来的标记将被视为标识符。 但这会在 SQL 中引起问题,其中字符串文字被双引号括起来,而不是 SQL 标准单引号。
如果 H2 兼容模式设置为 MySQL,那么我们应该可以使用正常的 MySQL 反引号字符来转义标识符。 例如
SELECT *
FROM `accounts`
^ ^
此外,MySQL 不会反对这种结构:
WHERE 'aws_account_name' LIKE
^ ^
但是用单引号括起来,MySQL 将此处的标记'aws_account_name'
视为字符串文字,而不是对列的引用。
如果那应该是列名,我们可以在列引用周围使用 MySQL 反引号字符。
为了减少混淆并使未来的读者更容易,我们通常喜欢限定列引用,即使它不是严格要求的。 例如,使用短表别名:
SELECT t.*
FROM `accounts` t
WHERE t.`aws_account_name` LIKE ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.