美文网首页
简单mybatis游标查询实现

简单mybatis游标查询实现

作者: _Kantin | 来源:发表于2021-09-06 17:23 被阅读0次

背景

  • 在实际的项目开发中,我们经常需要通过某个关联去数据库查询相关的记录。
  • 如果是前端带分页的接口还好,但是也要考虑深度分页带来的问题。
  • 而更多的有时候没有预估到生产的数据量,导致单次查询量太大把程序打到OOM。

问题

  • 笔者在查看生产日志时,发现有个带条件的查询返回了70W+的记录,导致mybaits直接OOM。
  • 相关逻辑是根据一个父ID去查询全部子记录,之后遍历子记录进行相关的业务逻辑操作

相关代码

  • 在项目的Dao层有个方法
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.mapping.ResultSetType;

public interface  xxxDao extends BaseDao{
    #根据父appId查询子记录,使用Options注解来标记是游标查询,每次查询10000条
    @Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 10000)
    List<xxxBean> selectByAppId(@Param("appId") Long appId);
}
  • 在项目的Service层方法
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

public void test1() throws IOException {
        List<xxxBean> list= new ArrayList<>();
        SqlSession sqlSession =sqlSessionTemplate.getSqlSessionFactory().openSession();
        //90137L表示查询的参数
        Cursor<HdfsPathRecord> cursor = sqlSession.selectCursor(xxxDao.class.getName() + ".selectByAppId",90137L);
       Iterator iter = cursor.iterator();
        while (iter.hasNext()) {
          xxxBean obj = (xxxBean) iter.next();
         //TODO:接下来可以根据obj执行实际逻辑或者将obj放到一个list中
        }
        cursor.close();
        sqlSession.close();
}
  • 有任何疑问或提问欢迎留言或私信我

相关文章

网友评论

      本文标题:简单mybatis游标查询实现

      本文链接:https://www.haomeiwen.com/subject/yhfywltx.html