我有一个包含约15万条记录的DB2表。我有另一个具有相同列的SQL Server表。表格列之一-我们称之为代码-是一个唯一值并已建立索引。我正在使用Spring Batch。定期,我得到一个包含代码列表的文件。例如,具有5 K代码的文件。对于文件中的每个代码,我需要从DB2表中读取记录,该表的code列与文件中的代码匹配,并将这些记录中的几列插入SQL Server表中。我想使用SQL而不是JPA,并且认为SQL IN子句中可以有多少个值是有限制的(比如说1000)。这应该是我的块大小吗?
Spring Batch应用程序应如何设计?我考虑过以下策略,但需要帮助来确定哪种(或任何其他)更好。
1)单步作业,其中读取器从文件中读取代码,处理器使用JdbcTemplate获取大量代码行,而编写器使用JdbcBatchItemWriter编写行-似乎JdbcTemplate在整个作业执行过程中将具有开放的DB连接。
2)JdbcPagingItemReader-Spring Batch文档告诫DB2之类的数据库具有悲观的锁定策略,并建议改为使用驱动查询
3)驾驶查询-是否有示例? -处理器如何将密钥转换为完整的对象?连接保持打开状态多长时间?
4)链接阅读器-这可能吗? -第一个读取器将读取文件,然后从DB2读取,然后是处理器和写入器。
答案 0 :(得分:0)
我会选择您的#1。您包含唯一code
的文件将有效地成为您的驾驶查询。
您的ItemReader
将读取文件,并将每个code
发送到您的ItemProcessor
。
ItemProcessor
可以直接使用JdbcTemplate
,也可以在每次调用{{1}时委托给项目中的单独数据访问对象(DAO),但是无论哪种方式}方法将从您的DB2数据库表中提取一条新记录。在为您的process
发出适当的对象之前,您可以执行此处所需的任何其他处理,然后将其插入或更新SQL Server数据库表中的必要记录。
这是一个项目示例,其中我使用ItemWriter
作为驾驶查询来收集需要在其上处理配置数据的设备的ID。然后,我将这些ID数据传递到我的ItemReader<Integer>
上,该数据一次处理一个配置文件:
ItemProcessor
您将用public class DeviceConfigDataProcessor implements ItemProcessor<Integer,DeviceConfig> {
@Autowired
MyJdbcDao myJdbcDao;
@Override
public DeviceConfig process(Integer deviceId) throws Exception {
DeviceConfig deviceConfig = myJdbcDao.getDeviceConfig( deviceId );
// process deviceConfig as needed
return deviceConfig;
}
}
换成deviceId
,用code
换成适合您项目的任何域对象。
如果您使用的是Spring Boot,则应该自动拥有一个DeviceConfig
,并且DAO一次将提取一条记录进行处理,因此您不必担心与数据库的持久连接,悲观锁等。