I have done a great deal of CTFI on this matter, so I hope I'm not asking a completely stupid question.
I need a Map-based implementation of PreparedStatementSetter. Since ListPreparedStatementSetter is in the Spring Batch project, I think this forum is the most appropriate place to pose a question. In my experience with the Spring Framework, if I need it - it probably already exists. So that's why I am curious...
Here would be a usage scenario - feel free to correct this scenario as well.
I went ahead and implemented a solution, based on the source for ListPreparedStatementSetter - keep in mind this is my first go at it... Be nice!Code:<bean id="myReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step"> <property name="dataSource" ref="myDataSource"/> <property name="rowMapper"><bean class="org.springframework.jdbc.core.ColumnMapRowMapper"/></property> <property name="sql"> <bean class="org.apache.commons.io.IOUtils" factory-method="toString"> <constructor-arg type="java.io.InputStream" value="classpath:/my.sql"/> </bean> </property> <property name="preparedStatementSetter"> <bean class="my.MapPreparedStatementSetter"> <property name="parameters"> <map> <entry key="begin" value="#{jobParameters['begin.date']}"/> <entry key="end" value="#{jobParameters['end.date']}"/> </map> </property> </bean> </property> </bean>
Lot's of mutable state there - that implementation is NOT thread safe. That will be in version 2.Code:public class MapPreparedStatementSetter implements PreparedStatementSetter, InitializingBean { private Map<String, ?> parameters; @Override public void setValues(PreparedStatement ps) throws SQLException { int i=0; for (Map.Entry<String, ?> entry : parameters.entrySet()) { StatementCreatorUtils.setParameterValue( ps, ++i, new SqlParameter(entry.getKey(), StatementCreatorUtils.javaTypeToSqlParameterType(entry.getValue().getClass())), entry.getValue() ); } } public void setParameters(Map<String, ?> parameters) { this.parameters = parameters; } @Override public void afterPropertiesSet() throws Exception { Assert.notNull(parameters, "Parameters must be provided"); } }
Is there a different or better way to do this? I see the usage for ListPreparedStatementSetter, but the SQL I have to execute is far too complex to use '?' to bind ordered parameters - it truly needs named parameters.
Thanks!!!



Reply With Quote