Apache Cayenne调用MySQL JSON搜索函数出现解析错误问题
解决Apache Cayenne执行MySQL JSON_EXTRACT时的SQL模板解析错误
问题根源
Cayenne的SQLSelect默认会对SQL语句进行模板解析,JSON_EXTRACT参数里的'$.symbol'被解析器误判:$被当成模板变量的起始标记,后续的.被识别为标识符分隔符,从而触发语法解析错误。
解决方案
1. 关闭SQL模板解析(推荐,纯原生SQL场景)
直接禁用Cayenne的模板解析功能,让SQL以原始形式传递给数据库执行:
String sql = "SELECT data, JSON_EXTRACT(data, '$.symbol') FROM quote;"; List<String> symbols = SQLSelect.scalarQuery(sql, String.class) .noTemplateParsing() // 关闭模板解析,跳过对$符号的处理 .select(DbConn.context);
2. 转义$符号(需保留模板解析时使用)
如果SQL中需要同时使用模板变量和JSON函数,可将$转义为$$,让解析器将其视为普通字符:
String sql = "SELECT data, JSON_EXTRACT(data, '$$.symbol') FROM quote;"; List<String> symbols = SQLSelect.scalarQuery(sql, String.class).select(DbConn.context);
3. 使用Cayenne函数API构建查询(ORM风格)
若项目更倾向于使用ORM而非原生SQL,可通过Cayenne的函数表达式工厂构建JSON_EXTRACT调用:
import org.apache.cayenne.exp.ExpressionFactory; import org.apache.cayenne.exp.FunctionExpressionFactory; import org.apache.cayenne.query.SelectQuery; import java.util.stream.Collectors; // 假设Quote是对应quote表的实体类 SelectQuery<Quote> query = SelectQuery.query(Quote.class); // 添加JSON_EXTRACT函数列 query.addColumn(FunctionExpressionFactory.dbFunction( "JSON_EXTRACT", String.class, ExpressionFactory.columnExp("data"), ExpressionFactory.literalExp("$.symbol") )); // 执行查询并提取结果 List<String> symbols = DbConn.context.select(query) .stream() .map(result -> (String) result.get(0)) .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者Andrea Borgogelli Avveduti
相关产品推荐
相关产品推荐

