spring 批量 SQL 查询没有准备好的语句
spring batch SQL queries without prepared statement
我读取行,从数据生成 SQL 查询,我需要写入数据库。我的过程没问题,但我无法通过编写器查询数据库。我认为我不能使用 PreparedStatement
因为除了生成的查询和那些查询更改之外我什么都没有,所以我认为它会生成一个错误(无效的批处理命令)。我怎样才能简单地把我的 SQL 放在这里?我可以像这样在 sql 方法中传递属性:.sql(query)
吗?顺便说一句,当我只需要 String
时,我切换到了 StringDTO
。我没有其他方法可以将查询映射到 String
class,什么是最合适的?创建一个对象只是为了在
中创建一个String
似乎很糟糕
这是我的代码:
// tag::readerwriterprocessor[]
@Bean
public FlatFileItemReader<StringDTO> reader() {
return new FlatFileItemReaderBuilder<StringDTO>()
.name("StringDTOItemReader")
.resource(new ClassPathResource("file.edi"))
.delimited()
.delimiter("\n")
.names("query")
.fieldSetMapper(new BeanWrapperFieldSetMapper<StringDTO>() {{
setTargetType(StringDTO.class);
}})
.build();
}
@Bean
public StringDTOItemProcessor processor() {
return new StringDTOItemProcessor();
}
@Bean
public ListUnpackingItemWriter<StringDTO> listItemWriter(DataSource dataSource) {
ListUnpackingItemWriter<StringDTO> writer = new ListUnpackingItemWriter<>();
writer.setDelegate(writer(dataSource));
return writer;
}
@Bean
public ItemPreparedStatementSetter<StringDTO> itemPreparedStatementSetter() {
return new StatementSetterTest();
}
public JdbcBatchItemWriter<StringDTO> writer(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<StringDTO>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql(":query")
.itemPreparedStatementSetter(itemPreparedStatementSetter())
.dataSource(dataSource)
.build();
}
// end::readerwriterprocessor[]
// tag::jobstep[]
@Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.flow(step1)
.end()
.build();
}
@Bean
public Step step1(ItemWriter<List<StringDTO>> writer) {
return stepBuilderFactory.get("step1")
.<StringDTO, List<StringDTO>> chunk(300)
.reader(reader())
.processor(processor())
.writer(writer)
.build();
}
// end::jobstep[]
建议的解决方案:
public class CustomWriter implements ItemWriter<String>{
protected DataSource dataSource;
public CustomWriter(DataSource dataSource){
this.dataSource = dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void write(final List<? extends String> items) throws Exception {
Statement statement = dataSource.getConnection().createStatement();
Iterator<String> it = (Iterator<String>) items.iterator();
while(it.hasNext()){
String s = it.next();
if(s.startsWith("INSERT INTO SQD_SQI2_TKO (change_date,TKO,K991_0992,F2801,F2801,F2802,F1803) VALUES (sysdate,2467"))
System.out.println(s);
statement.addBatch(s);
}
statement.executeBatch();
}
}public class CustomWriter implements ItemWriter<String>{
protected DataSource dataSource;
public CustomWriter(DataSource dataSource){
this.dataSource = dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void write(final List<? extends String> items) throws Exception {
Statement statement = dataSource.getConnection().createStatement();
Iterator<String> it = (Iterator<String>) items.iterator();
while(it.hasNext()){
String s = it.next();
if(s.startsWith("INSERT INTO SQD_SQI2_TKO (change_date,TKO,K991_0992,F2801,F2801,F2802,F1803) VALUES (sysdate,2467"))
System.out.println(s);
statement.addBatch(s);
}
statement.executeBatch();
}
}
与最初的问题无关,但这是我正在使用的映射器,因为我的输出只是一个 String
,不需要映射到实际对象,也不需要映射到 sql输出
@Bean
public FlatFileItemReader<String> reader() {
return new FlatFileItemReaderBuilder<String>()
.name("StringItemReader")
.resource(new ClassPathResource("file.edi"))
.delimited()
.delimiter("\n")
.names("query")
.fieldSetMapper(new FieldSetMapper<String>() {
@Override
public String mapFieldSet(FieldSet arg0) throws BindException {
return arg0.readString(0);
}
})
.build();
}
my processor does return a list of queries - queries concern multiple tables
在这种情况下,您需要使用自定义项目编写器,因为 JdbcBatchItemWriter
接受单个查询。
我读取行,从数据生成 SQL 查询,我需要写入数据库。我的过程没问题,但我无法通过编写器查询数据库。我认为我不能使用 PreparedStatement
因为除了生成的查询和那些查询更改之外我什么都没有,所以我认为它会生成一个错误(无效的批处理命令)。我怎样才能简单地把我的 SQL 放在这里?我可以像这样在 sql 方法中传递属性:.sql(query)
吗?顺便说一句,当我只需要 String
时,我切换到了 StringDTO
。我没有其他方法可以将查询映射到 String
class,什么是最合适的?创建一个对象只是为了在
String
似乎很糟糕
这是我的代码:
// tag::readerwriterprocessor[]
@Bean
public FlatFileItemReader<StringDTO> reader() {
return new FlatFileItemReaderBuilder<StringDTO>()
.name("StringDTOItemReader")
.resource(new ClassPathResource("file.edi"))
.delimited()
.delimiter("\n")
.names("query")
.fieldSetMapper(new BeanWrapperFieldSetMapper<StringDTO>() {{
setTargetType(StringDTO.class);
}})
.build();
}
@Bean
public StringDTOItemProcessor processor() {
return new StringDTOItemProcessor();
}
@Bean
public ListUnpackingItemWriter<StringDTO> listItemWriter(DataSource dataSource) {
ListUnpackingItemWriter<StringDTO> writer = new ListUnpackingItemWriter<>();
writer.setDelegate(writer(dataSource));
return writer;
}
@Bean
public ItemPreparedStatementSetter<StringDTO> itemPreparedStatementSetter() {
return new StatementSetterTest();
}
public JdbcBatchItemWriter<StringDTO> writer(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<StringDTO>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql(":query")
.itemPreparedStatementSetter(itemPreparedStatementSetter())
.dataSource(dataSource)
.build();
}
// end::readerwriterprocessor[]
// tag::jobstep[]
@Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.flow(step1)
.end()
.build();
}
@Bean
public Step step1(ItemWriter<List<StringDTO>> writer) {
return stepBuilderFactory.get("step1")
.<StringDTO, List<StringDTO>> chunk(300)
.reader(reader())
.processor(processor())
.writer(writer)
.build();
}
// end::jobstep[]
建议的解决方案:
public class CustomWriter implements ItemWriter<String>{
protected DataSource dataSource;
public CustomWriter(DataSource dataSource){
this.dataSource = dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void write(final List<? extends String> items) throws Exception {
Statement statement = dataSource.getConnection().createStatement();
Iterator<String> it = (Iterator<String>) items.iterator();
while(it.hasNext()){
String s = it.next();
if(s.startsWith("INSERT INTO SQD_SQI2_TKO (change_date,TKO,K991_0992,F2801,F2801,F2802,F1803) VALUES (sysdate,2467"))
System.out.println(s);
statement.addBatch(s);
}
statement.executeBatch();
}
}public class CustomWriter implements ItemWriter<String>{
protected DataSource dataSource;
public CustomWriter(DataSource dataSource){
this.dataSource = dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void write(final List<? extends String> items) throws Exception {
Statement statement = dataSource.getConnection().createStatement();
Iterator<String> it = (Iterator<String>) items.iterator();
while(it.hasNext()){
String s = it.next();
if(s.startsWith("INSERT INTO SQD_SQI2_TKO (change_date,TKO,K991_0992,F2801,F2801,F2802,F1803) VALUES (sysdate,2467"))
System.out.println(s);
statement.addBatch(s);
}
statement.executeBatch();
}
}
与最初的问题无关,但这是我正在使用的映射器,因为我的输出只是一个 String
,不需要映射到实际对象,也不需要映射到 sql输出
@Bean
public FlatFileItemReader<String> reader() {
return new FlatFileItemReaderBuilder<String>()
.name("StringItemReader")
.resource(new ClassPathResource("file.edi"))
.delimited()
.delimiter("\n")
.names("query")
.fieldSetMapper(new FieldSetMapper<String>() {
@Override
public String mapFieldSet(FieldSet arg0) throws BindException {
return arg0.readString(0);
}
})
.build();
}
my processor does return a list of queries - queries concern multiple tables
在这种情况下,您需要使用自定义项目编写器,因为 JdbcBatchItemWriter
接受单个查询。