如何在Spring Batch中用Item Reader映射MDB文件查询结果
问题分析与解决建议
你的代码核心问题是没有正确配置JdbcCursorItemReader:你手动通过JDBC查询并封装了Order对象列表,但返回的orderReader是未配置任何读取逻辑的空对象,Spring Batch无法通过它获取数据。另外你手动管理数据库连接的方式也不符合Spring Batch的设计规范。
正确实现方式
- 配置MDB数据源:通过
DriverManagerDataSource配置UCanAccess的JDBC数据源,让Spring Batch管理数据库连接。 - 配置
JdbcCursorItemReader:指定SQL语句、数据源,并通过RowMapper实现结果集到Order对象的映射,无需手动遍历ResultSet。
修改后的完整代码
package config; import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.item.database.JdbcCursorItemReader; import org.springframework.batch.item.database.RowMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DriverManagerDataSource; import model.Order; import repository.OrderRepository; import java.sql.ResultSet; import java.sql.SQLException; @Configuration @EnableBatchProcessing public class SpringBatchConfig_ { @Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Autowired private OrderRepository orderRepository; // 配置MDB数据源 @Bean public DriverManagerDataSource mdbDataSource(@Value("#{jobParameters[fullPathFileName]}") String pathToFile) { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("net.ucanaccess.jdbc.UcanaccessDriver"); dataSource.setUrl("jdbc:ucanaccess://" + pathToFile); // UCanAccess默认无需用户名密码,如有需要可添加setUsername/setPassword return dataSource; } // 配置JdbcCursorItemReader @Bean public JdbcCursorItemReader<Order> orderReader(DriverManagerDataSource mdbDataSource) { JdbcCursorItemReader<Order> reader = new JdbcCursorItemReader<>(); reader.setDataSource(mdbDataSource); reader.setSql("SELECT * FROM tblOrder"); reader.setRowMapper(new OrderRowMapper()); // 可选:设置每次读取的数据量 // reader.setFetchSize(100); return reader; } // 实现RowMapper,映射ResultSet到Order对象 private static class OrderRowMapper implements RowMapper<Order> { @Override public Order mapRow(ResultSet rs, int rowNum) throws SQLException { Order order = new Order(); // 注意:这里的列名要和数据库表字段对应,建议使用列名而非索引,避免表结构变更影响 order.setOrderId(rs.getString("OrderId")); order.setDescription(rs.getString("Description")); order.setQuantity(rs.getString("Quantity")); // 修正原代码的拼写错误:OderDate → OrderDate,需和实体类字段名一致 order.setOrderDate(rs.getString("OrderDate")); order.setOrderStatus(rs.getString("OrderStatus")); order.setOrderLocation(rs.getString("OrderLocation")); return order; } } }
额外注意事项
- 检查
Order实体类的字段名:原代码里的OderDate是拼写错误,要修正为OrderDate(对应实体类的setter方法setOrderDate)。 - 确保UCanAccess依赖已正确引入到项目中(Maven/Gradle):
<!-- Maven依赖示例 --> <dependency> <groupId>net.sf.ucanaccess</groupId> <artifactId>ucanaccess</artifactId> <version>5.0.1</version> <!-- 使用最新稳定版 --> </dependency>
内容的提问来源于stack exchange,提问作者Janeth Jackson
相关产品推荐
相关产品推荐

