001package com.mybatisflex.spring.batch;
002
003import com.mybatisflex.core.BaseMapper;
004import com.mybatisflex.core.query.QueryWrapper;
005import org.apache.ibatis.cursor.Cursor;
006import org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader;
007import org.springframework.beans.factory.InitializingBean;
008
009import java.util.*;
010
011import static org.springframework.util.Assert.notNull;
012import static org.springframework.util.ClassUtils.getShortName;
013
014/**
015 * 游标模式读取
016 * @author zhangjian
017 */
018public class MyBatisFlexCursorItemReader<T> extends AbstractItemCountingItemStreamItemReader<T>
019    implements InitializingBean {
020
021  /**
022   * 当前的mapper
023   */
024  private BaseMapper<T> mapper;
025
026  /**
027   * 拼接的入参列表
028   */
029  private QueryWrapper queryWrapper;
030
031  /**
032   *
033   */
034  private Cursor<T> cursor;
035
036  /**
037   *
038   */
039  private Iterator<T> cursorIterator;
040
041  public MyBatisFlexCursorItemReader() {
042    setName(getShortName(MyBatisFlexCursorItemReader.class));
043  }
044
045  /**
046   * 当前的mapper对象
047   * @param mapper
048   */
049  public void setMapper(BaseMapper<T> mapper) {
050    this.mapper = mapper;
051  }
052
053  /**
054   * 当前的参数对象
055   * @param queryWrapper
056   */
057  public void setQueryWrapper(QueryWrapper queryWrapper) {
058    this.queryWrapper = queryWrapper;
059  }
060
061  @Override
062  protected T doRead() throws Exception {
063    T next = null;
064    if (cursorIterator.hasNext()) {
065      next = cursorIterator.next();
066    }
067    return next;
068  }
069
070  @Override
071  protected void doOpen() {
072    if (Objects.isNull(this.mapper) || Objects.isNull(this.queryWrapper)) {
073      throw new IllegalArgumentException("mapper or queryWrapper is required.");
074    }
075    this.cursor = this.mapper.selectCursorByQuery(queryWrapper);
076    cursorIterator = cursor.iterator();
077  }
078
079  @Override
080  protected void doClose() throws Exception {
081    if (cursor != null) {
082      cursor.close();
083    }
084    cursorIterator = null;
085  }
086
087  /**
088   * Check mandatory properties.
089   *
090   * @see InitializingBean#afterPropertiesSet()
091   */
092  @Override
093  public void afterPropertiesSet() {
094    notNull(mapper, "A BaseMapper is required.");
095    notNull(queryWrapper, "A queryWrapper is required.");
096  }
097
098}