diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/AbstractExpressionEvaluator.java b/spring-integration-core/src/main/java/org/springframework/integration/util/AbstractExpressionEvaluator.java index fc92b2a60b..d0689f23b3 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/AbstractExpressionEvaluator.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/util/AbstractExpressionEvaluator.java @@ -18,9 +18,12 @@ package org.springframework.integration.util; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.context.expression.MapAccessor; import org.springframework.core.convert.ConversionService; import org.springframework.expression.EvaluationException; import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.integration.Message; import org.springframework.integration.MessageHandlingException; @@ -28,16 +31,21 @@ import org.springframework.integration.context.SimpleBeanResolver; /** * @author Mark Fisher + * @author Dave Syer + * * @since 2.0 */ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware { private final StandardEvaluationContext evaluationContext = new StandardEvaluationContext(); + private final ExpressionParser expressionParser = new SpelExpressionParser(); + private final BeanFactoryTypeConverter typeConverter = new BeanFactoryTypeConverter(); public AbstractExpressionEvaluator() { evaluationContext.setTypeConverter(typeConverter); + evaluationContext.addPropertyAccessor(new MapAccessor()); } /** @@ -76,8 +84,20 @@ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware { } } - protected T evaluateExpression(Expression expression, Object message, Class expectedType) { - return expression.getValue(this.evaluationContext, message, expectedType); + protected T evaluateExpression(String expression, Object input) { + return evaluateExpression(expression, input, null); + } + + protected T evaluateExpression(String expression, Object input, Class expectedType) { + return expressionParser.parseExpression(expression).getValue(this.evaluationContext, input, expectedType); + } + + protected T evaluateExpression(Expression expression, Object input) { + return evaluateExpression(expression, input, null); + } + + protected T evaluateExpression(Expression expression, Object input, Class expectedType) { + return expression.getValue(this.evaluationContext, input, expectedType); } } diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/BeanPropertySqlParameterSourceFactory.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/BeanPropertySqlParameterSourceFactory.java new file mode 100644 index 0000000000..4573bf7d5e --- /dev/null +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/BeanPropertySqlParameterSourceFactory.java @@ -0,0 +1,77 @@ +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.springframework.integration.jdbc; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.jdbc.core.namedparam.AbstractSqlParameterSource; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; + +/** + * A default implementation of {@link SqlParameterSourceFactory} which creates an {@link SqlParameterSource} to + * reference bean properties in its input. + * + * @author Dave Syer + * @since 2.0 + */ +public class BeanPropertySqlParameterSourceFactory implements SqlParameterSourceFactory { + + private Map staticParameters; + + public BeanPropertySqlParameterSourceFactory() { + this.staticParameters = Collections.unmodifiableMap(new HashMap()); + } + + /** + * If the input is a List or a Map, the output is a map parameter source, and in that case some static parameters + * can be added (default is empty). If the input is not a List or a Map then this value is ignored. + * + * @param staticParameters the static parameters to set + */ + public void setStaticParameters(Map staticParameters) { + this.staticParameters = staticParameters; + } + + public SqlParameterSource createParameterSource(Object input) { + SqlParameterSource toReturn = new StaticBeanPropertySqlParameterSource(input, staticParameters); + return toReturn; + } + + private static class StaticBeanPropertySqlParameterSource extends AbstractSqlParameterSource implements + SqlParameterSource { + + private final BeanPropertySqlParameterSource input; + + private final Map staticParameters; + + public StaticBeanPropertySqlParameterSource(Object input, Map staticParameters) { + this.input = new BeanPropertySqlParameterSource(input); + this.staticParameters = staticParameters; + } + + public Object getValue(String paramName) throws IllegalArgumentException { + return staticParameters.containsKey(paramName) ? staticParameters.get(paramName) : input + .getValue(paramName); + } + + public boolean hasValue(String paramName) { + return staticParameters.containsKey(paramName) || input.hasValue(paramName); + } + + } + +} diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/DefaultSqlParameterSourceFactory.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/DefaultSqlParameterSourceFactory.java deleted file mode 100644 index 81f53c9912..0000000000 --- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/DefaultSqlParameterSourceFactory.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package org.springframework.integration.jdbc; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.DirectFieldAccessor; -import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.SqlParameterSource; - -/** - * A default implementation of {@link SqlParameterSourceFactory} which creates an {@link SqlParameterSource} according - * to the type of the data passed in. - * - *
    - *
  • - * Where the data is a List, a list of ids is generated by looking for a map entry or bean property named by default - * 'id'. The resulting {@link SqlParameterSource} is a map that contains this list under a default key of 'idList'.
  • - *
  • - * Where the data is a {@link Map}, this is wrapped in an instance of {@link MapSqlParameterSource}.
  • - *
  • - * Otherwise the result is wrapped in a {@link BeanPropertySqlParameterSource}.
  • - *
- * - * @author Jonas Partner - * @author Dave Syer - * @since 2.0 - */ -public class DefaultSqlParameterSourceFactory implements SqlParameterSourceFactory { - - private final Log logger = LogFactory.getLog(getClass()); - - private Map staticParameters; - - private String rowIdName = "id"; - - private String idsParamName = "idList"; - - public DefaultSqlParameterSourceFactory() { - this.staticParameters = Collections.unmodifiableMap(new HashMap()); - } - - /** - * Name of the id property in the input elements when the input data is List. Defaults to "id". - * If the input is not a List then this value is ignored. - * @param rowIdName the name to set - */ - public void setRowIdName(String rowIdName) { - this.rowIdName = rowIdName; - } - - /** - * Name of the id list in the output parameters if the input is a List (default "idList"). If the input is not a - * List then this value is ignored. - * - * @param idsParamName the name to set - */ - public void setIdsParameterName(String idsParamName) { - this.idsParamName = idsParamName; - } - - /** - * If the input is a List or a Map, the output is a map parameter source, and in that case some static parameters - * can be added (default is empty). If the input is not a List or a Map then this value is ignored. - * - * @param staticParameters the static parameters to set - */ - public void setStaticParameters(Map staticParameters) { - this.staticParameters = staticParameters; - } - - @SuppressWarnings("unchecked") - public SqlParameterSource createParameterSource(Object input) { - SqlParameterSource toReturn; - if (input instanceof List) { - List ids = new ArrayList(); - for (Object rowObj : (List) input) { - if (rowObj instanceof Map) { - ids.add(((Map) rowObj).get(this.rowIdName)); - } - else { - DirectFieldAccessor accessor = new DirectFieldAccessor(rowObj); - if (accessor.isReadableProperty(this.rowIdName)) { - ids.add(accessor.getPropertyValue(this.rowIdName)); - } - else { - logger.warn("No id field named '" + this.rowIdName - + "' found for result of polled row. Update may not include all rows."); - } - } - } - MapSqlParameterSource thisParamSource = new MapSqlParameterSource(); - if (this.staticParameters != null) { - thisParamSource.addValues(this.staticParameters); - } - thisParamSource.addValue(this.idsParamName, ids); - thisParamSource.getValue("idList"); - toReturn = thisParamSource; - } - else if (input instanceof Map) { - MapSqlParameterSource mapParameterSource = new MapSqlParameterSource((Map) input); - mapParameterSource.addValues(this.staticParameters); - toReturn = mapParameterSource; - } - else { - BeanPropertySqlParameterSource beanParameterSource = new BeanPropertySqlParameterSource(input); - toReturn = beanParameterSource; - } - return toReturn; - } - -} diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/ExpressionEvaluatingSqlParameterSourceFactory.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/ExpressionEvaluatingSqlParameterSourceFactory.java new file mode 100644 index 0000000000..3ad92ddd5e --- /dev/null +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/ExpressionEvaluatingSqlParameterSourceFactory.java @@ -0,0 +1,104 @@ +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package org.springframework.integration.jdbc; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.expression.ExpressionException; +import org.springframework.integration.util.AbstractExpressionEvaluator; +import org.springframework.jdbc.core.namedparam.AbstractSqlParameterSource; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; + +/** + * An implementation of {@link SqlParameterSourceFactory} which creates an {@link SqlParameterSource} that evaluates + * Spring EL expressions. In addition the user can supply static parameters that always take precedence. + * + * @author Dave Syer + * @since 2.0 + */ +public class ExpressionEvaluatingSqlParameterSourceFactory extends AbstractExpressionEvaluator implements SqlParameterSourceFactory { + + private final static Log logger = LogFactory.getLog(ExpressionEvaluatingSqlParameterSourceFactory.class); + + private static final Object ERROR = new Object(); + + private Map staticParameters; + + public ExpressionEvaluatingSqlParameterSourceFactory() { + this.staticParameters = Collections.unmodifiableMap(new HashMap()); + } + + /** + * If the input is a List or a Map, the output is a map parameter source, and in that case some static parameters + * can be added (default is empty). If the input is not a List or a Map then this value is ignored. + * + * @param staticParameters the static parameters to set + */ + public void setStaticParameters(Map staticParameters) { + this.staticParameters = staticParameters; + } + + public SqlParameterSource createParameterSource(final Object input) { + SqlParameterSource toReturn = new ExpressionEvaluatingSqlParameterSource(input, staticParameters); + return toReturn; + } + + private class ExpressionEvaluatingSqlParameterSource extends AbstractSqlParameterSource { + + private final Object input; + + private Map values = new ConcurrentHashMap(); + + private ExpressionEvaluatingSqlParameterSource(Object input, Map staticParameters) { + this.input = input; + this.values.putAll(staticParameters); + } + + public Object getValue(String paramName) throws IllegalArgumentException { + if (values.containsKey(paramName)) { + return values.get(paramName); + } + String expression = paramName; + if (input instanceof Collection) { + expression = "#root.!["+paramName+"]"; + } + Object value = evaluateExpression(expression, input); + values.put(paramName, value); + return value; + } + + public boolean hasValue(String paramName) { + try { + Object value = getValue(paramName); + if (value==ERROR) { + return false; + } + } catch (ExpressionException e) { + if (logger.isDebugEnabled()) { + logger.debug("Could not evaluate expression", e); + } + values.put(paramName, ERROR); + return false; + } + return true; + } + } + +} diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/JdbcMessageHandler.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/JdbcMessageHandler.java index 3661d354f8..9176a9a265 100644 --- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/JdbcMessageHandler.java +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/JdbcMessageHandler.java @@ -46,7 +46,7 @@ public class JdbcMessageHandler extends AbstractMessageHandler { private volatile String updateSql; - private volatile SqlParameterSourceFactory sqlParameterSourceFactory = new DefaultSqlParameterSourceFactory(); + private volatile SqlParameterSourceFactory sqlParameterSourceFactory = new BeanPropertySqlParameterSourceFactory(); /** * Constructor taking {@link DataSource} from which the DB Connection can be obtained and the select query to diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/JdbcPollingChannelAdapter.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/JdbcPollingChannelAdapter.java index 35853163d9..7703d637b6 100644 --- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/JdbcPollingChannelAdapter.java +++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/JdbcPollingChannelAdapter.java @@ -59,7 +59,7 @@ public class JdbcPollingChannelAdapter implements MessageSource { private volatile String updateSql; - private volatile SqlParameterSourceFactory sqlParameterSourceFactory = new DefaultSqlParameterSourceFactory(); + private volatile SqlParameterSourceFactory sqlParameterSourceFactory = new ExpressionEvaluatingSqlParameterSourceFactory(); private int maxRowsPerPoll = 0; diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/ExpressionEvaluatingSqlParameterSourceFactoryTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/ExpressionEvaluatingSqlParameterSourceFactoryTests.java new file mode 100644 index 0000000000..ef55c09b7f --- /dev/null +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/ExpressionEvaluatingSqlParameterSourceFactoryTests.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.jdbc; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Test; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; + +/** + * @author Dave Syer + * + */ +public class ExpressionEvaluatingSqlParameterSourceFactoryTests { + + private ExpressionEvaluatingSqlParameterSourceFactory factory = new ExpressionEvaluatingSqlParameterSourceFactory(); + + @Test + public void testSetStaticParameters() { + factory.setStaticParameters(Collections.singletonMap("foo", "bar")); + SqlParameterSource source = factory.createParameterSource(null); + assertTrue(source.hasValue("foo")); + assertEquals("bar", source.getValue("foo")); + } + + @Test + public void testMapInput() { + SqlParameterSource source = factory.createParameterSource(Collections.singletonMap("foo", "bar")); + assertTrue(source.hasValue("foo")); + assertEquals("bar", source.getValue("foo")); + } + + @Test + public void testListOfMapsInput() { + @SuppressWarnings("unchecked") + SqlParameterSource source = factory.createParameterSource(Arrays.asList(Collections.singletonMap("foo", "bar"), + Collections.singletonMap("foo", "bucket"))); + String expression = "foo"; + assertTrue(source.hasValue(expression)); + assertEquals("[bar, bucket]", source.getValue(expression).toString()); + } + + @Test + public void testMapInputWithExpression() { + SqlParameterSource source = factory.createParameterSource(Collections.singletonMap("foo", "bar")); + assertTrue(source.hasValue("foo.toUpperCase()")); + assertEquals("BAR", source.getValue("foo.toUpperCase()")); + } + +} diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcPollingChannelAdapterIntegrationTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcPollingChannelAdapterIntegrationTests.java index f8031ad1a4..3ce97ce50c 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcPollingChannelAdapterIntegrationTests.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcPollingChannelAdapterIntegrationTests.java @@ -141,7 +141,7 @@ public class JdbcPollingChannelAdapterIntegrationTests { JdbcPollingChannelAdapter adapter = new JdbcPollingChannelAdapter( this.embeddedDatabase, "select * from item where status=2"); adapter - .setUpdateSql("update item set status = 10 where id in (:idList)"); + .setUpdateSql("update item set status = 10 where id in (:id)"); adapter.setRowMapper(new ItemRowMapper()); this.jdbcTemplate.update("insert into item values(1,2)"); diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParserTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParserTests.java index 502e715d7d..bde2171dc0 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParserTests.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParserTests.java @@ -71,7 +71,7 @@ public class JdbcMessageHandlerParserTests { channel.send(message); Map map = this.jdbcTemplate.queryForMap("SELECT * from FOOS"); assertEquals("Wrong id", message.getHeaders().getId().toString(), map.get("ID")); - assertEquals("Wrong name", "foo", map.get("name")); + assertEquals("Wrong name", "bar", map.get("name")); } @After diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/handlingParameterSourceJdbcOutboundChannelAdapterTest.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/handlingParameterSourceJdbcOutboundChannelAdapterTest.xml index 9273f9228d..883fca5f20 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/handlingParameterSourceJdbcOutboundChannelAdapterTest.xml +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/handlingParameterSourceJdbcOutboundChannelAdapterTest.xml @@ -9,12 +9,12 @@ http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd"> - - + diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingForMapJdbcInboundChannelAdapterWithNestedUpdateTest.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingForMapJdbcInboundChannelAdapterWithNestedUpdateTest.xml index c91e34ca0d..2fad9c6c8b 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingForMapJdbcInboundChannelAdapterWithNestedUpdateTest.xml +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingForMapJdbcInboundChannelAdapterWithNestedUpdateTest.xml @@ -12,7 +12,7 @@ select * from item where status=2 - update item set status=10 where id in (:idList) + update item set status=10 where id in (:id) diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingForMapJdbcInboundChannelAdapterWithUpdateTest.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingForMapJdbcInboundChannelAdapterWithUpdateTest.xml index 764e696ac7..9624a3f507 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingForMapJdbcInboundChannelAdapterWithUpdateTest.xml +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingForMapJdbcInboundChannelAdapterWithUpdateTest.xml @@ -11,7 +11,7 @@ http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd"> + data-source="dataSource" update="update item set status=10 where id in (:id)" /> diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingWithMaxRowsJdbcInboundChannelAdapterTest.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingWithMaxRowsJdbcInboundChannelAdapterTest.xml index 2ddf63cef3..de513871f8 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingWithMaxRowsJdbcInboundChannelAdapterTest.xml +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingWithMaxRowsJdbcInboundChannelAdapterTest.xml @@ -11,7 +11,7 @@ + update="update item set status=10 where id in (:id)" /> diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingWithParameterSourceJdbcInboundChannelAdapterTest.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingWithParameterSourceJdbcInboundChannelAdapterTest.xml index fbe763a5af..721d98bcc6 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingWithParameterSourceJdbcInboundChannelAdapterTest.xml +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/pollingWithParameterSourceJdbcInboundChannelAdapterTest.xml @@ -9,14 +9,17 @@ http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd"> - + - + - + + + diff --git a/src/docbkx/jdbc.xml b/src/docbkx/jdbc.xml index f44f2272f5..ac4ab9cfd0 100644 --- a/src/docbkx/jdbc.xml +++ b/src/docbkx/jdbc.xml @@ -28,22 +28,23 @@ The inbound adapter also requires a reference to either JdbcTemplate instance or - DataSource. The following example defines - an inbound Channel Adapter with a DataSource - reference. ]]> - - The parameters in the update query are specified with a colon (:) prefix to the name of a map key. This is a standard feature of the named parameter JDBC support in Spring JDBC. - + DataSource. As well as the SELECT statement to generate the messages, the adapter above also has an UPDATE statement that is being used to mark the records as processed, so they don't show up in - the next poll. The update is parameterised by the list of ids from the + the next poll. The update can be parameterised by the list of ids from the original select. This is done through a naming convention by default (a column in the input result set called "id" is translated into a list in - the parameter map for the update called "idList"). To change the parameter + the parameter map for the update called "id"). The following example defines + an inbound Channel Adapter with an update query and a DataSource + reference. ]]> + + The parameters in the update query are specified with a colon (:) prefix to the name of a parameter (which in this case is an expression to be applied to each of the rows in the polled result set). This is a standard feature of the named parameter JDBC support in Spring JDBC combined with a convention (projection onto the polled result list) adopted in Spring Integration. The underlying Spring JDBC features limit the available expressions (e.g. most special characters other than period are disallowed), but since the target is usually a list of or an individual object addressable by simple bean paths this isn't unduly restrictive. + + To change the parameter generation strategy you can inject a SqlParameterSourceFactory into the adapter to override the default behaviour (the adapter has a @@ -92,15 +93,11 @@ example above, messages arriving on the channel "input" have a payload of a map with key "foo", so the [] operator dereferences that value from the map. The headers are also accessed as a map. - The parameters in the query above are bean paths in the incoming message (they are not Spring EL expressions). This behaviour is part of the - - MapSqlParameterSource - - in Spring JDBC, which is the default source created by the outbound adapter. Other behaviour is possible in the adapter, and only requires the user to inject a different - - SqlParameterSourceFactory - - . + The parameters in the query above are bean property expressions on the incoming message (not Spring EL expressions). This behaviour is part of the + SqlParameterSource which is the default + source created by the outbound adapter. Other behaviour is possible + in the adapter, and requires the user to inject a different + SqlParameterSourceFactory. The outbound adapter requires a reference to either a DataSource or