INT-1173: added sql parameter source support
This commit is contained in:
@@ -28,49 +28,81 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||
|
||||
/**
|
||||
* A default implementation of {@link SqlParameterSourceFactory} which creates an {@link SqlParameterSource} according
|
||||
* to the result of the data passed in.
|
||||
* to the type of the data passed in.
|
||||
*
|
||||
* <ul>
|
||||
* <li>
|
||||
* 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} 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 an instance of {@link BeanPropertySqlParameterSource}.
|
||||
* 'id'. The resulting {@link SqlParameterSource} is a map that contains this list under a default key of 'idList'.</li>
|
||||
* <li>
|
||||
* Where the data is a {@link Map}, this is wrapped in an instance of {@link MapSqlParameterSource}.</li>
|
||||
* <li>
|
||||
* Otherwise the result is wrapped in a {@link BeanPropertySqlParameterSource}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Jonas Partner
|
||||
* @author Dave Syer
|
||||
* @since 2.0
|
||||
*/
|
||||
public class DefaultSqlParameterSourceFactory implements SqlParameterSourceFactory {
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final Map<String, Object> staticParameters;
|
||||
private Map<String, Object> staticParameters;
|
||||
|
||||
private final String polledRowIdName = "id";
|
||||
private String rowIdName = "id";
|
||||
|
||||
private final String updateIdsParamName = "idList";
|
||||
private String idsParamName = "idList";
|
||||
|
||||
public DefaultSqlParameterSourceFactory() {
|
||||
this.staticParameters = Collections.unmodifiableMap(new HashMap<String, Object>());
|
||||
}
|
||||
|
||||
public DefaultSqlParameterSourceFactory(Map<String, Object> staticParameters) {
|
||||
this.staticParameters = Collections.unmodifiableMap(staticParameters);
|
||||
/**
|
||||
* 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<String, Object> staticParameters) {
|
||||
this.staticParameters = staticParameters;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public SqlParameterSource createParameterSource(Object resultOfSelect) {
|
||||
public SqlParameterSource createParameterSource(Object input) {
|
||||
SqlParameterSource toReturn;
|
||||
if (resultOfSelect instanceof List) {
|
||||
if (input instanceof List) {
|
||||
List<Object> ids = new ArrayList<Object>();
|
||||
for (Object rowObj : (List) resultOfSelect) {
|
||||
for (Object rowObj : (List) input) {
|
||||
if (rowObj instanceof Map) {
|
||||
ids.add(((Map) rowObj).get(this.polledRowIdName));
|
||||
} else {
|
||||
ids.add(((Map) rowObj).get(this.rowIdName));
|
||||
}
|
||||
else {
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(rowObj);
|
||||
if (accessor.isReadableProperty(this.polledRowIdName)) {
|
||||
ids.add(accessor.getPropertyValue(this.polledRowIdName));
|
||||
} else {
|
||||
logger.warn("No id field named '" + this.polledRowIdName
|
||||
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.");
|
||||
}
|
||||
}
|
||||
@@ -79,15 +111,17 @@ public class DefaultSqlParameterSourceFactory implements SqlParameterSourceFacto
|
||||
if (this.staticParameters != null) {
|
||||
thisParamSource.addValues(this.staticParameters);
|
||||
}
|
||||
thisParamSource.addValue(this.updateIdsParamName, ids);
|
||||
thisParamSource.addValue(this.idsParamName, ids);
|
||||
thisParamSource.getValue("idList");
|
||||
toReturn = thisParamSource;
|
||||
} else if (resultOfSelect instanceof Map) {
|
||||
MapSqlParameterSource mapParameterSource = new MapSqlParameterSource((Map) resultOfSelect);
|
||||
}
|
||||
else if (input instanceof Map) {
|
||||
MapSqlParameterSource mapParameterSource = new MapSqlParameterSource((Map) input);
|
||||
mapParameterSource.addValues(this.staticParameters);
|
||||
toReturn = mapParameterSource;
|
||||
} else {
|
||||
BeanPropertySqlParameterSource beanParameterSource = new BeanPropertySqlParameterSource(resultOfSelect);
|
||||
}
|
||||
else {
|
||||
BeanPropertySqlParameterSource beanParameterSource = new BeanPropertySqlParameterSource(input);
|
||||
toReturn = beanParameterSource;
|
||||
}
|
||||
return toReturn;
|
||||
|
||||
@@ -51,7 +51,7 @@ public class JdbcPollingChannelAdapter implements MessageSource<Object> {
|
||||
|
||||
private volatile String updateSql;
|
||||
|
||||
private volatile SqlParameterSourceFactory sqlParameterSourceFactoryForUpdate = new DefaultSqlParameterSourceFactory();
|
||||
private volatile SqlParameterSourceFactory sqlParameterSourceFactory = new DefaultSqlParameterSourceFactory();
|
||||
|
||||
|
||||
/**
|
||||
@@ -91,8 +91,8 @@ public class JdbcPollingChannelAdapter implements MessageSource<Object> {
|
||||
this.updatePerRow = updatePerRow;
|
||||
}
|
||||
|
||||
public void setSqlParameterSourceFactoryForUpdate(SqlParameterSourceFactory sqlParameterSourceFactoryForUpdate) {
|
||||
this.sqlParameterSourceFactoryForUpdate = sqlParameterSourceFactoryForUpdate;
|
||||
public void setSqlParameterSourceFactory(SqlParameterSourceFactory sqlParameterSourceFactory) {
|
||||
this.sqlParameterSourceFactory = sqlParameterSourceFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,7 +102,7 @@ public class JdbcPollingChannelAdapter implements MessageSource<Object> {
|
||||
* this method will return <code>null</code>.
|
||||
*/
|
||||
public Message<Object> receive() {
|
||||
Object payload = pollAndUpdate();
|
||||
Object payload = poll();
|
||||
if (payload == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -114,7 +114,7 @@ public class JdbcPollingChannelAdapter implements MessageSource<Object> {
|
||||
* Returns the rows returned by the select query. If a RowMapper
|
||||
* has been provided, the mapped results are returned.
|
||||
*/
|
||||
private Object pollAndUpdate() {
|
||||
private Object poll() {
|
||||
List<?> payload;
|
||||
if (this.rowMapper != null) {
|
||||
payload = pollWithRowMapper();
|
||||
@@ -140,8 +140,8 @@ public class JdbcPollingChannelAdapter implements MessageSource<Object> {
|
||||
|
||||
private void executeUpdateQuery(Object obj) {
|
||||
SqlParameterSource updateParamaterSource = null;
|
||||
if (this.sqlParameterSourceFactoryForUpdate != null) {
|
||||
updateParamaterSource = this.sqlParameterSourceFactoryForUpdate.createParameterSource(obj);
|
||||
if (this.sqlParameterSourceFactory != null) {
|
||||
updateParamaterSource = this.sqlParameterSourceFactory.createParameterSource(obj);
|
||||
this.jdbcOperations.update(this.updateSql, updateParamaterSource);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -19,9 +19,8 @@ package org.springframework.integration.jdbc;
|
||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||
|
||||
/**
|
||||
* Collaborator for {@link JdbcPollingChannelAdapter} which allows creation of
|
||||
* instances of {@link SqlParameterSource} for use in updates to be created
|
||||
* according to the result of the poll.
|
||||
* Collaborator for JDBC adapters which allows creation of
|
||||
* instances of {@link SqlParameterSource} for use in update operations.
|
||||
*
|
||||
* @author Jonas Partner
|
||||
* @since 2.0
|
||||
@@ -30,8 +29,8 @@ public interface SqlParameterSourceFactory {
|
||||
|
||||
/**
|
||||
* Return a new {@link SqlParameterSource}.
|
||||
* @param resultOfSelect the result of the preceding poll operation
|
||||
* @param input the raw message or query result to be transformed into a SqlParameterSource
|
||||
*/
|
||||
public SqlParameterSource createParameterSource(Object resultOfSelect);
|
||||
public SqlParameterSource createParameterSource(Object input);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -60,6 +61,7 @@ public class JdbcMessageHandlerParser extends AbstractOutboundChannelAdapterPars
|
||||
} else {
|
||||
builder.addConstructorArgReference(jdbcOperationsRef);
|
||||
}
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "sql-parameter-source-factory");
|
||||
builder.addConstructorArgValue(query);
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ public class JdbcPollingChannelAdapterParser extends AbstractPollingInboundChann
|
||||
}
|
||||
builder.addConstructorArgValue(query);
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "row-mapper");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "sql-parameter-source-factory");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "update", "updateSql");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "update-per-row");
|
||||
return BeanDefinitionReaderUtils.registerWithGeneratedName(
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/integration/jdbc"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
targetNamespace="http://www.springframework.org/schema/integration/jdbc"
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/integration/jdbc" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration" targetNamespace="http://www.springframework.org/schema/integration/jdbc"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/integration"
|
||||
schemaLocation="http://www.springframework.org/schema/integration/spring-integration-2.0.xsd" />
|
||||
<xsd:import namespace="http://www.springframework.org/schema/integration" schemaLocation="http://www.springframework.org/schema/integration/spring-integration-2.0.xsd" />
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
@@ -31,7 +28,8 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Reference to a data source to use to access
|
||||
the database. Either this or the jdbc-operations must be
|
||||
the database. Either this or the jdbc-operations
|
||||
must be
|
||||
specified (but not both).
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
@@ -51,8 +49,7 @@
|
||||
specified (but not both).
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.jdbc.core.JdbcOperations" />
|
||||
<tool:expected-type type="org.springframework.jdbc.core.JdbcOperations" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -62,7 +59,8 @@
|
||||
<xsd:documentation>
|
||||
Unique string to use as a partition for the
|
||||
data in this store, so that
|
||||
multiple instances can share the same
|
||||
multiple instances can
|
||||
share the same
|
||||
database tables. The default
|
||||
is "DEFAULT".
|
||||
</xsd:documentation>
|
||||
@@ -72,7 +70,8 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Prefix for the table names in the database
|
||||
(e.g. so that a schema can be specified, or to avoid a clash
|
||||
(e.g. so that a schema can be specified, or to avoid
|
||||
a clash
|
||||
with
|
||||
other tables). The default is "INT_".
|
||||
</xsd:documentation>
|
||||
@@ -86,8 +85,7 @@
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.jdbc.support.lob.LobHandler" />
|
||||
<tool:expected-type type="org.springframework.jdbc.support.lob.LobHandler" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -105,64 +103,74 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="integration:poller" minOccurs="0"
|
||||
maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="data-source" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Reference to a data source to use to access
|
||||
the
|
||||
database. Either this or the simple-jdbc-operations must be
|
||||
specified (but not both).
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="javax.sql.DataSource" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="jdbc-operations" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a JdbcOperations. Either
|
||||
this or
|
||||
the data-source must be
|
||||
specified (but not both).
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.jdbc.core.JdbcOperations" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="query" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="row-mapper" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jdbc.core.RowMapper" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="update" type="xsd:string" />
|
||||
<xsd:attribute name="update-per-row" type="xsd:boolean"
|
||||
default="false" />
|
||||
<xsd:attribute name="channel" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="jdbcType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="query" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
A select query to execute when a message is polled. In general the query can return multiple
|
||||
rows, because the result will be a List (of type determined by the row mapper).
|
||||
</xsd:documentation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="row-mapper" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a row mapper to use to convert JDBC result set rows to message payloads.
|
||||
Optional
|
||||
with default that maps
|
||||
result set row to a map (column name to column value). Other simple
|
||||
use cases can
|
||||
be handled
|
||||
with out-of-the box implementations from Spring JDBC. Others require a custom row
|
||||
mapper.
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jdbc.core.RowMapper" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="update" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
An update query to execute when a message is polled. If the poll is in a transaction then the
|
||||
update will roll back if the transaction does.
|
||||
</xsd:documentation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="update-per-row" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Flag to indicate whether the update query should be executed per message, or per row (in the
|
||||
case that a message contains multiple rows).
|
||||
</xsd:documentation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="channel" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Channel to which polled messages will be sent.
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -174,59 +182,88 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="data-source" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Reference to a data source to use to access
|
||||
the
|
||||
database. Either this or the simple-jdbc-operations must be
|
||||
specified (but not both).
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="javax.sql.DataSource" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="jdbc-operations" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a JdbcOperations. Either
|
||||
this or
|
||||
the data-source must be
|
||||
specified (but not both).
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="jdbcType">
|
||||
<xsd:attribute name="query" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
An SQL update query to execute (INSERT, UPDATE
|
||||
or DELETE). Bean properties of the outgoing
|
||||
message can be
|
||||
referenced in named parameters, e.g. "INSERT into FOOS (ID, NAME) values (:headers[business.key],
|
||||
:payload)". More complex requirements can be implemented by
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.jdbc.core.JdbcOperations" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="query" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
An SQL update query to execute (INSERT, UPDATE
|
||||
or DELETE). Bean properties of the outgoing message can be
|
||||
referenced in named parameters, e.g. "INSERT into FOOS (ID, NAME) values (:headers[business.key], :payload)"
|
||||
</xsd:documentation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="channel" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="channel" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Channel from which messages will be output. When a message is sent to this channel it will
|
||||
cause the query to be executed.
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.core.MessageChannel" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="jdbcType">
|
||||
<xsd:attribute name="data-source" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Reference to a data source to use to access
|
||||
the
|
||||
database. Either this or the
|
||||
simple-jdbc-operations
|
||||
must be
|
||||
specified (but not both).
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="javax.sql.DataSource" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="jdbc-operations" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a JdbcOperations. Either
|
||||
this or
|
||||
the data-source must be
|
||||
specified (but not both).
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.jdbc.core.JdbcOperations" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="sql-parameter-source-factory" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a SqlParameterSourceFactory. For an inbound adapter the input is the result of the
|
||||
query, and for an outbound adapter the input is the whole outgoing message. The default factory creates a bean
|
||||
property parameter source for a generic input (like a Message), and treats a List in a special way: the List is
|
||||
assumed to contain entities with a field called "id" and these are collected and copied to a field in the
|
||||
parameter source called "idList".
|
||||
</xsd:documentation>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.jdbc.SqlParameterSourceFactory" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -25,7 +25,7 @@ public class JdbcMessageHandlerParserTests {
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void testSimpleInboundChannelAdapter(){
|
||||
public void testSimpleOutboundChannelAdapter(){
|
||||
setUp("handlingWithJdbcOperationsJdbcOutboundChannelAdapterTest.xml", getClass());
|
||||
Message<?> message = MessageBuilder.withPayload("foo").setHeader("business.key", "FOO").build();
|
||||
channel.send(message);
|
||||
@@ -35,7 +35,7 @@ public class JdbcMessageHandlerParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDollarHeaderInboundChannelAdapter(){
|
||||
public void testDollarHeaderOutboundChannelAdapter(){
|
||||
setUp("handlingDollarHeaderJdbcOutboundChannelAdapterTest.xml", getClass());
|
||||
Message<?> message = MessageBuilder.withPayload("foo").build();
|
||||
channel.send(message);
|
||||
@@ -45,13 +45,23 @@ public class JdbcMessageHandlerParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMapPayloadInboundChannelAdapter(){
|
||||
public void testMapPayloadOutboundChannelAdapter(){
|
||||
setUp("handlingMapPayloadJdbcOutboundChannelAdapterTest.xml", getClass());
|
||||
Message<?> message = MessageBuilder.withPayload(Collections.singletonMap("foo", "bar")).build();
|
||||
channel.send(message);
|
||||
Map<String, Object> map = this.jdbcTemplate.queryForMap("SELECT * from FOOS");
|
||||
assertEquals("Wrong id", message.getHeaders().getId().toString(), map.get("ID"));
|
||||
assertEquals("Wrong id", "bar", map.get("name"));
|
||||
assertEquals("Wrong name", "bar", map.get("name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParameterSourceOutboundChannelAdapter(){
|
||||
setUp("handlingParameterSourceJdbcOutboundChannelAdapterTest.xml", getClass());
|
||||
Message<?> message = MessageBuilder.withPayload("foo").build();
|
||||
channel.send(message);
|
||||
Map<String, Object> map = this.jdbcTemplate.queryForMap("SELECT * from FOOS");
|
||||
assertEquals("Wrong id", message.getHeaders().getId().toString(), map.get("ID"));
|
||||
assertEquals("Wrong name", "foo", map.get("name"));
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package org.springframework.integration.jdbc.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@@ -24,18 +26,16 @@ public class JdbcPollingChannelAdapterParserTests {
|
||||
|
||||
final long receiveTimeout = 5000;
|
||||
|
||||
SimpleJdbcTemplate jdbcTemplate;
|
||||
|
||||
MessageChannelTemplate channelTemplate;
|
||||
|
||||
ConfigurableApplicationContext appCtx;
|
||||
|
||||
private SimpleJdbcTemplate jdbcTemplate;
|
||||
|
||||
private MessageChannelTemplate channelTemplate;
|
||||
|
||||
private ConfigurableApplicationContext appCtx;
|
||||
|
||||
@Test
|
||||
public void testSimpleInboundChannelAdapter(){
|
||||
setUp("pollingForMapJdbcInboundChannelAdapterTest.xml", getClass());
|
||||
this.jdbcTemplate.update("insert into item values(1,2)");
|
||||
this.jdbcTemplate.update("insert into item values(1,'',2)");
|
||||
Message<?> message = channelTemplate.receive();
|
||||
assertNotNull("No message found ", message);
|
||||
assertTrue("Wrong payload type expected instance of List", message.getPayload() instanceof List<?>);
|
||||
@@ -45,7 +45,7 @@ public class JdbcPollingChannelAdapterParserTests {
|
||||
@Test
|
||||
public void testSimpleInboundChannelAdapterWithUpdate(){
|
||||
setUp("pollingForMapJdbcInboundChannelAdapterWithUpdateTest.xml", getClass());
|
||||
this.jdbcTemplate.update("insert into item values(1,2)");
|
||||
this.jdbcTemplate.update("insert into item values(1,'',2)");
|
||||
Message<?> message = channelTemplate.receive();
|
||||
assertNotNull(message);
|
||||
message = channelTemplate.receive();
|
||||
@@ -55,11 +55,22 @@ public class JdbcPollingChannelAdapterParserTests {
|
||||
@Test
|
||||
public void testExtendedInboundChannelAdapter(){
|
||||
setUp("pollingWithJdbcOperationsJdbcInboundChannelAdapterTest.xml", getClass());
|
||||
this.jdbcTemplate.update("insert into item values(1,2)");
|
||||
this.jdbcTemplate.update("insert into item values(1,'',2)");
|
||||
Message<?> message = channelTemplate.receive();
|
||||
assertNotNull(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParameterSourceInboundChannelAdapter(){
|
||||
setUp("pollingWithParameterSourceJdbcInboundChannelAdapterTest.xml", getClass());
|
||||
this.jdbcTemplate.update("insert into item values(1,'',2)");
|
||||
Message<?> message = channelTemplate.receive();
|
||||
assertNotNull(message);
|
||||
List<Map<String, Object>> list = jdbcTemplate.queryForList("SELECT * FROM item WHERE status=1");
|
||||
assertEquals(1, list.size());
|
||||
assertEquals("bar", list.get(0).get("NAME"));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown(){
|
||||
if(appCtx != null){
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration/jdbc"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:si="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/jdbc
|
||||
http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd">
|
||||
|
||||
<outbound-channel-adapter query="insert into foos (id, status, name) values (:headers[$id], 0, :payload)"
|
||||
channel="target" data-source="dataSource" sql-parameter-source-factory="sqlParameterSourceFactory"/>
|
||||
|
||||
<beans:import resource="jdbcOutboundChannelAdapterCommonConfig.xml" />
|
||||
|
||||
<beans:bean id="sqlParameterSourceFactory" class="org.springframework.integration.jdbc.DefaultSqlParameterSourceFactory">
|
||||
<beans:property name="staticParameters">
|
||||
<beans:map><beans:entry key="foo" value="bar"/></beans:map>
|
||||
</beans:property>
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
@@ -1 +1 @@
|
||||
create table item(id int,status int);
|
||||
create table item(id int, name varchar(20), status int);
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration/jdbc" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:si="http://www.springframework.org/schema/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/jdbc
|
||||
http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd">
|
||||
|
||||
<inbound-channel-adapter query="select * from item where status=2" channel="target" update="update item set status=1, name=:foo where id in (:idList)"
|
||||
jdbc-operations="jdbcTemplate" sql-parameter-source-factory="sqlParameterSourceFactory" />
|
||||
|
||||
<beans:import resource="jdbcInboundChannelAdapterCommonConfig.xml" />
|
||||
|
||||
<beans:bean id="sqlParameterSourceFactory" class="org.springframework.integration.jdbc.DefaultSqlParameterSourceFactory">
|
||||
<beans:property name="staticParameters">
|
||||
<beans:map><beans:entry key="foo" value="bar"/></beans:map>
|
||||
</beans:property>
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
Reference in New Issue
Block a user