在 jdbc:入站通道适配器从数据库读取记录后更新时间戳



我正在使用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;

您可以注意到,我避免在数组的两个元素中使用相同的表达式使用集合投影。

最新更新