如何使用带有 Spring JDBC 的 MERGE 语句插入/更新单个记录
Posted
技术标签:
【中文标题】如何使用带有 Spring JDBC 的 MERGE 语句插入/更新单个记录【英文标题】:How to insert/update a single record using a MERGE statement with Spring JDBC 【发布时间】:2018-08-06 16:03:43 【问题描述】:我有一个使用 MERGE 语句创建的更新/插入 SQL 查询。使用 JdbcTemplate 或 NamedParameterJdbcTemplate,Spring 是否提供了一种我可以用来更新单个记录的方法,而不是批量更新?
由于此查询将用于通过 JMS 侦听器从队列中持久化数据,因此我一次只将一条记录出列,并且不需要批量更新的开销。
如果批处理是通过 Spring JDBC 执行此操作的唯一方法,那很好......我只是想确保我没有遗漏一些更简单的东西。
【问题讨论】:
只需使用update
方法,例如这个:JdbcTemplate#update 而不是BatchUpdate。 Update
更新单条记录,batchUpdate
使用JDBC批量更新多条记录。
@krokodiko:谢谢!这正是我需要知道的。你是第一个,所以如果你提供一个正式的答案,我会投票给你的答案。每个人都乐于助人。我最初尝试了 Spring 的更新方法,但由于我的参数化列表有问题,我误解了异常并确定 UPDATE 不是正确的方法。我没有意识到使用 Spring JDBC,它只是一个单一的或批量的更新。我寻找了一种更具体的方法,但找不到,所以你的简短回答给了我解决问题所需的洞察力。谢谢你的回答!
【参考方案1】:
您可以使用 SQL MERGE
语句,只使用包含您的参数的单行查询。
例如,如果您有一个表 COMPANY
containg ID
作为键,NAME
作为属性,MERGE
语句将是:
merge into company c
using (select ? id, ? name from dual) d
on (c.id = d.id)
when matched then update
set c.name = d.name
when not matched then insert (c.id, c.name)
values(d.id, d.name)
如果您的目标表包含参数化键,name
将被更新,否则将插入一条新记录。
使用 JDBCTemplate,您可以使用 update
方法调用 MERGE
语句,如下图所示(使用 Groovy 脚本)
def id = 1
def name = 'NewName'
String mergeStmt = """merge into company c
using (select ? id, ? name from dual) d
on (c.id = d.id)
when matched then update
set c.name = d.name
when not matched then insert (c.id, c.name)
values(d.id, d.name)""";
def updCnt = jdbcTemplate.update(mergeStmt, id, name);
println "merging $id, name $name, merged rows $updCnt"
【讨论】:
我用过Java,但你的回答绝对正确。感谢您分享这个例子。尽管我已经使用 Spring JDBC 中的 update 方法多年,但我对 MERGE 语句还是新手,并没有意识到 update 方法足够通用,可以处理更新和插入的 SQL 语句。我实际上已经简单地尝试过,但是我的参数化列表有问题。在那之后,我一直在寻找一种更具体的方法,也许是为执行 MERGE 而构建的。谢谢你的例子!【参考方案2】:只需使用update
方法之一,例如:JdbcTemplate#update 而不是 BatchUpdate。 Update
更新单条记录,batchUpdate
使用JDBC批量更新多条记录
【讨论】:
以上是关于如何使用带有 Spring JDBC 的 MERGE 语句插入/更新单个记录的主要内容,如果未能解决你的问题,请参考以下文章
带有 JDBC 配置的 Spring-Session:表 'test.spring_session' 不存在
带有 JDBC 身份验证的 Spring Security 5:UserDetailsService bean 仍然在内存中,而不是 JDBC