我正在使用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>
我们可以使用DB级方法为oracle设置sysdate的时间,但我并不热衷于在代码中使用特定于DB的方法进行测试(H2 DB用于测试)
非常感谢任何帮助
由于
答案 0 :(得分:0)
我遇到了同样的问题,问题是:timestamp
表达式被评估为Collection Projection,请检查code here。
所以我的原始查询是这样的
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
语句的结果数相同。因此,如果结果不止一个,则会出现Bad Grammar异常。
我使用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;
你可以注意到我在数组的两个元素中使用相同的表达式避免使用Collection Projection。