我正在使用Spring集成的"int-jdbc:inbound-channel-adapter"从数据库中获取记录。但是在我获取记录后,我还需要更新 2 列 1) 状态列 2) 时间戳列
更新状态列不是问题,因为我可以在下面的 xml 代码段中使用
<int-jdbc:inbound-channel-adapter query="select * from item where status=2"
channel="target" data-source="dataSource"
update="update item set status=10 where id in (:id)" />
但是当我尝试更新时间戳时,它不起作用
<int-jdbc:inbound-channel-adapter query="select * from item where status=2"
channel="target" data-source="dataSource"
update="update item set status=10,timestamp=:timestamp where id in (:id)"
update-sql-parameter-source-actory="timestampUpdaterSqlParameterSourceFactory">
<int-jdbc:inbound-channel-adapter>
<bean id="timestampUpdaterSqlParameterSourceFactory"
class="org.springframework.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory" >
<property name="parameterExpressions">
<map>
<entry key="timestamp" value="@now"/>
</map>
</property>
</bean>
<bean id="now" scope="prototype" class="java.sql.Timestamp">
<constructor-arg value="#{ T(java.lang.System).currentTimeMillis()}" />
</bean>
我们可以使用数据库级别的方法来设置时间,例如 oracle 的 sysdate,但我不热衷于在代码中使用特定于数据库的方法进行测试(H2 DB 用于测试)
任何帮助都非常感谢
谢谢
我遇到了同样的问题,问题是:timestamp
表达式被计算为集合投影,请检查此处的代码。所以我的原始查询是这样的
update table set status = 1, published_at = :now where id_event in (:id)
解析后是这样的
update table set status = 1, published_at = ?, ?, ? where id_event in (?, ?, ?)
?
数与 select
语句的结果数相同。因此,如果结果不止一个,则会出现语法异常错误。
我使用spring-integration-java-dsl
做了一个不太好的解决方案(侵入性)
protected void addNotCollectionProjectionExpression(
ExpressionEvaluatingSqlParameterSourceFactory factory,
String key, String expression) {
try {
Field parameterExpressionsField = factory.getClass().getDeclaredField("parameterExpressions");
parameterExpressionsField.setAccessible(true);
Map<String, Expression[]> parameterExpressions = (Map<String, Expression[]>) parameterExpressionsField
.get(factory);
Field parserField = factory.getClass().getDeclaredField("PARSER");
parserField.setAccessible(true);
ExpressionParser parser = (ExpressionParser) parserField.get(factory);
Expression compiledExpression = parser.parseExpression(expression);
Expression[] expressions = new Expression[]{
compiledExpression,
compiledExpression
};
parameterExpressions.put(key, expressions);
} catch (NoSuchFieldException | IllegalAccessException e) {
logger.error("Field parameterExpressions | PARSER can not be obtained", e);
}
}
....
//how to use it
ExpressionEvaluatingSqlParameterSourceFactory factory =
new ExpressionEvaluatingSqlParameterSourceFactory();
addNotCollectionProjectionExpression(factory, "now",
"T(com.example.MyClass).staticMethod()");
return factory;
您可以注意到,我避免在数组的两个元素中使用相同的表达式使用集合投影。