Spring 批量 | MongoItemReader |如何将 JobParameters 传递给 mongo 查询?
Spring Batch | MongoItemReader | How to pass JobParameters to mongo query?
如何将 JobParameters
传递给 MongoItemReader
查询?
我的 ItemReader 看起来像:-
@Bean
public ItemReader<Person> PersonTenantBasedItemReader() {
MongoItemReader<Person> reader = new MongoItemReader<Person>();
reader.setTemplate(mongoTemplate);
reader.setTargetType((Class<? extends Person>) Person.class);
reader.setQuery("{status:'XYZ',nextCheckpointDate:{$gte:?fromDate,$lte:?toDate}"); // !!!!I want to pass fromDate and toDate as job parameters. !!!!
Map<String, Direction> sorts = new HashMap<String, Sort.Direction>(1);
sorts.put("status", Sort.Direction.ASC);
reader.setSort(sorts);
return reader;
}
这就是我启动作业的方式:-
@Test
public void test() throws Exception {
Map<String, JobParameter> map = new HashMap<String, JobParameter>(2);
map.put("fromDate", new JobParameter(new Date()));
map.put("toDate", new JobParameter(//some future date comes here);
JobParameters jobParameters = new JobParameters(map);
JobExecution run = launcher.run(job, jobParameters);
Assert.assertNotNull(run);
}
我遇到了这个异常:-
com.mongodb.util.JSONParseException:
{status:'DELINQUENT',nextCheckpointDate:{$gte:?fromDate,$lte:?toDate}
^
at com.mongodb.util.JSONParser.parse(JSON.java:216)
at com.mongodb.util.JSONParser.parseObject(JSON.java:249)
at com.mongodb.util.JSONParser.parse(JSON.java:213)
at com.mongodb.util.JSONParser.parseObject(JSON.java:249)
at com.mongodb.util.JSONParser.parse(JSON.java:213)
at com.mongodb.util.JSONParser.parse(JSON.java:163)
at com.mongodb.util.JSON.parse(JSON.java:99)
at com.mongodb.util.JSON.parse(JSON.java:79)
at org.springframework.data.mongodb.core.query.BasicQuery.<init>(BasicQuery.java:39)
at org.springframework.batch.item.data.MongoItemReader.doPageRead(MongoItemReader.java:176)
at org.springframework.batch.item.data.AbstractPaginatedDataItemReader.doRead(AbstractPaginatedDataItemReader.java:59)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:88)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:91)
at org.springframework.batch.core.step.item.SimpleChunkProvider.read(SimpleChunkProvider.java:155)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doInIteration(SimpleChunkProvider.java:114)
我发现您的配置存在两个问题:
- 为了注入
JobParameter
值,您需要使用 Step 作用域。您的 bean 当前配置为使用单例范围(默认)。
- 您实际上并没有将参数注入到您的方法中。
试试下面的方法:
@Bean
@StepScope
public MongoItemReader<Person> PersonTenantBasedItemReader(@Value("#{jobParameters[fromDate]}") String fromDate, @Value("#{jobParameters[toDate]}") String toDate) {
MongoItemReader<Person> reader = new MongoItemReader<Person>();
reader.setTemplate(mongoTemplate);
reader.setTargetType((Class<? extends Person>) Person.class);
reader.setQuery(String.format("{status:'XYZ',nextCheckpointDate:{ %s ? %s }", fromDate, toDate));
Map<String, Direction> sorts = new HashMap<String, Sort.Direction>(1);
sorts.put("status", Sort.Direction.ASC);
reader.setSort(sorts);
return reader;
}
List<Object> param = new ArrayList<Object>();
param.add(fromDate);
param.add(toDate)
reader.setQuery("{status:'XYZ',nextCheckpointDate:{$gte:?0,$lte:?1}");
如何将 JobParameters
传递给 MongoItemReader
查询?
我的 ItemReader 看起来像:-
@Bean
public ItemReader<Person> PersonTenantBasedItemReader() {
MongoItemReader<Person> reader = new MongoItemReader<Person>();
reader.setTemplate(mongoTemplate);
reader.setTargetType((Class<? extends Person>) Person.class);
reader.setQuery("{status:'XYZ',nextCheckpointDate:{$gte:?fromDate,$lte:?toDate}"); // !!!!I want to pass fromDate and toDate as job parameters. !!!!
Map<String, Direction> sorts = new HashMap<String, Sort.Direction>(1);
sorts.put("status", Sort.Direction.ASC);
reader.setSort(sorts);
return reader;
}
这就是我启动作业的方式:-
@Test
public void test() throws Exception {
Map<String, JobParameter> map = new HashMap<String, JobParameter>(2);
map.put("fromDate", new JobParameter(new Date()));
map.put("toDate", new JobParameter(//some future date comes here);
JobParameters jobParameters = new JobParameters(map);
JobExecution run = launcher.run(job, jobParameters);
Assert.assertNotNull(run);
}
我遇到了这个异常:-
com.mongodb.util.JSONParseException:
{status:'DELINQUENT',nextCheckpointDate:{$gte:?fromDate,$lte:?toDate}
^
at com.mongodb.util.JSONParser.parse(JSON.java:216)
at com.mongodb.util.JSONParser.parseObject(JSON.java:249)
at com.mongodb.util.JSONParser.parse(JSON.java:213)
at com.mongodb.util.JSONParser.parseObject(JSON.java:249)
at com.mongodb.util.JSONParser.parse(JSON.java:213)
at com.mongodb.util.JSONParser.parse(JSON.java:163)
at com.mongodb.util.JSON.parse(JSON.java:99)
at com.mongodb.util.JSON.parse(JSON.java:79)
at org.springframework.data.mongodb.core.query.BasicQuery.<init>(BasicQuery.java:39)
at org.springframework.batch.item.data.MongoItemReader.doPageRead(MongoItemReader.java:176)
at org.springframework.batch.item.data.AbstractPaginatedDataItemReader.doRead(AbstractPaginatedDataItemReader.java:59)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:88)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:91)
at org.springframework.batch.core.step.item.SimpleChunkProvider.read(SimpleChunkProvider.java:155)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doInIteration(SimpleChunkProvider.java:114)
我发现您的配置存在两个问题:
- 为了注入
JobParameter
值,您需要使用 Step 作用域。您的 bean 当前配置为使用单例范围(默认)。 - 您实际上并没有将参数注入到您的方法中。
试试下面的方法:
@Bean
@StepScope
public MongoItemReader<Person> PersonTenantBasedItemReader(@Value("#{jobParameters[fromDate]}") String fromDate, @Value("#{jobParameters[toDate]}") String toDate) {
MongoItemReader<Person> reader = new MongoItemReader<Person>();
reader.setTemplate(mongoTemplate);
reader.setTargetType((Class<? extends Person>) Person.class);
reader.setQuery(String.format("{status:'XYZ',nextCheckpointDate:{ %s ? %s }", fromDate, toDate));
Map<String, Direction> sorts = new HashMap<String, Sort.Direction>(1);
sorts.put("status", Sort.Direction.ASC);
reader.setSort(sorts);
return reader;
}
List<Object> param = new ArrayList<Object>();
param.add(fromDate);
param.add(toDate)
reader.setQuery("{status:'XYZ',nextCheckpointDate:{$gte:?0,$lte:?1}");