带有 Spring 引导的 MyBatis 游标
MyBatis Cursor with Spring Boot
我正在尝试使用带有 Spring 引导的 MyBatis 游标来迭代大型查询:
映射器:
@Mapper
@Repository
interface UserMapper {
@Select("SELECT * FROM huge_user_table")
Cursor<User> getUsers();
消费者:
@Component
public class UserProcessor {
@Autowired private UserMapper userMapper;
public boolean process() throws IOException {
Cursor<User> users = userMapper.getUsers();
//users.isOpen() == false
for (User user : users) {
//Never iterates
System.out.println(user.getId());
}
当我恢复光标时,虽然它已关闭,但没有返回任何记录。
我错过了什么吗?
问题很可能是您尝试在事务之外使用 Cursor
。这是不支持的。
Cursor
基本上是 JDBC ResultSet
的包装。为了从 Cursor
获取值,应打开底层 ResultSet
。如果您在整个循环期间都没有事务,那么 spring 将在执行查询时打开连接(在您的情况下是 getUsers
方法的持续时间)。该方法完成后,连接将关闭,因此 Cursor
使用的 ResultSet
也将关闭。
将 @Transactional
添加到 process
,这应该可以解决问题。
我正在尝试使用带有 Spring 引导的 MyBatis 游标来迭代大型查询:
映射器:
@Mapper
@Repository
interface UserMapper {
@Select("SELECT * FROM huge_user_table")
Cursor<User> getUsers();
消费者:
@Component
public class UserProcessor {
@Autowired private UserMapper userMapper;
public boolean process() throws IOException {
Cursor<User> users = userMapper.getUsers();
//users.isOpen() == false
for (User user : users) {
//Never iterates
System.out.println(user.getId());
}
当我恢复光标时,虽然它已关闭,但没有返回任何记录。
我错过了什么吗?
问题很可能是您尝试在事务之外使用 Cursor
。这是不支持的。
Cursor
基本上是 JDBC ResultSet
的包装。为了从 Cursor
获取值,应打开底层 ResultSet
。如果您在整个循环期间都没有事务,那么 spring 将在执行查询时打开连接(在您的情况下是 getUsers
方法的持续时间)。该方法完成后,连接将关闭,因此 Cursor
使用的 ResultSet
也将关闭。
将 @Transactional
添加到 process
,这应该可以解决问题。