JOOQ操作PostgreSQL动态新增列后更新触发语法错误的问题咨询
报错根因
直接传字符串常量给row()方法时,jOOQ会将其识别为待绑定的字符串值,而非数据库列标识符,最终生成的SQL中SET子句的列位置出现了占位符$1,PostgreSQL不支持列名使用动态占位符,因此触发语法错误。
可行性说明
当前实现思路完全可行,无需重新生成jOOQ代码即可正常运行,仅需调整列的引用方式。
调整方案
- 把字符串类型的列名转换为jOOQ的
Field<Double>类型对象,明确标记为数据库字段:
import static org.jooq.impl.DSL.field; final Field<Double> SENTIMENT_NEGATIVE = field("sentiment_negative", DOUBLE); final Field<Double> SENTIMENT_NEUTRAL = field("sentiment_neutral", DOUBLE); final Field<Double> SENTIMENT_POSITIVE = field("sentiment_positive", DOUBLE); final Field<Double> SENTIMENT_COMPOUND = field("sentiment_compound", DOUBLE);
- 原有加列逻辑可以保持不变,更新逻辑中直接传入上述
Field对象即可,修改后的更新代码如下:
for (Record record: tweetsResult) { String tweet = record.get(Tweets.TWEETS.CONTENT); SentimentAnalyzer sentimentAnalyzer = new SentimentAnalyzer(tweet); sentimentAnalyzer.analyze(); log.debug(sentimentAnalyzer.getPolarity() + " | " + tweet); context.update(Tweets.TWEETS) .set( row(SENTIMENT_NEGATIVE, SENTIMENT_NEUTRAL, SENTIMENT_POSITIVE, SENTIMENT_COMPOUND), row(getPolarity(sentimentAnalyzer, SENTIMENT_NEGATIVE.getName()), getPolarity(sentimentAnalyzer, SENTIMENT_NEUTRAL.getName()), getPolarity(sentimentAnalyzer, SENTIMENT_POSITIVE.getName()), getPolarity(sentimentAnalyzer, SENTIMENT_COMPOUND.getName())) ) .where(Tweets.TWEETS.ID.eq(record.get(Tweets.TWEETS.ID))) .execute(); }
- 可选优化:数据量较大时,循环单条执行更新性能较低,可以改用jOOQ的批量更新能力,将所有更新请求攒批后一次性提交,降低数据库IO开销。
内容的提问来源于stack exchange,提问作者Cat-Lord
相关产品推荐
相关产品推荐

