您好,登錄后才能下訂單哦!
這篇文章主要講解了“Mybatis游標(biāo)查詢大量數(shù)據(jù)的方法是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Mybatis游標(biāo)查詢大量數(shù)據(jù)的方法是什么”吧!
對大量數(shù)據(jù)進(jìn)行處理時,為防止內(nèi)存泄漏情況發(fā)生,所以采用mybatis plus游標(biāo)方式進(jìn)行數(shù)據(jù)查詢處理,當(dāng)查詢百萬級的數(shù)據(jù)的時候,使用游標(biāo)可以節(jié)省內(nèi)存的消耗,不需要一次性取出所有數(shù)據(jù),可以進(jìn)行逐條處理或逐條取出部分批量處理
使用Cursor類型進(jìn)行數(shù)據(jù)接收
@Options,fetchSize設(shè)置為Integer最小值
@Select,寫查詢sql
@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = Integer.MIN_VALUE) @Select("select domain from illegal_domain where icpstatus != #{icpstatus}") Cursor<IllegalDomain> getDayJobDomain(@Param("icpstatus") Integer icpstatus);
Cursor<IllegalDomain> domainList = illegalDomainMapper.getDayJobDomain(1);
數(shù)據(jù)處理
forEach方式
domainList.forEach(illegalDomain -> { //處理邏輯,根據(jù)業(yè)務(wù)需求自行完成 Future<IcpStatusVo> future = checkIcpThreadPool.submit(new IcpCheckThread(illegalDomain.getDomain(), configMap)); results.add(future); });
迭代器
Iterator<IllegalDomain> iter = domainList.iterator(); while (iter.hasNext()) { <!--// Fetch next 10 employees--> <!--for(int i = 0; i<10 && iter.hasNext(); i++) {--> <!-- smallChunk.add(iter.next());--> <!--}--> //處理邏輯,根據(jù)業(yè)務(wù)需求自行完成 Future<IcpStatusVo> future = checkIcpThreadPool.submit(new IcpCheckThread(illegalDomain.getDomain(), configMap)); results.add(future); }
使用完畢后,在finally塊釋放資源,否則游標(biāo)不關(guān)閉也可能會導(dǎo)致內(nèi)存溢出問題
try{ //your code } catch (Exception e) { log.error(e); } finally { if(null != domainList){ try { domainList.close(); } catch (IOException e) { e.printStackTrace(); } } }
當(dāng)查詢百萬級的數(shù)據(jù)的時候,查詢出所有數(shù)據(jù)并放入內(nèi)存中時會發(fā)生OOM(OutOfMemoryException),使用游標(biāo)可以節(jié)省內(nèi)存的消耗,不需要一次性取出所有數(shù)據(jù),可以進(jìn)行逐條處理或逐條取出部分批量處理,在此場景下就可以使用游標(biāo)的概念來解決這個問題。
游標(biāo)(Cursor)是處理數(shù)據(jù)的一種方法,為了查看或者處理結(jié)果集中的數(shù)據(jù),游標(biāo)提供了在結(jié)果集中一次一行或者多行前進(jìn)或向后瀏覽數(shù)據(jù)的能力。
Demo:
// 第一種 @Options(resultSetType = ResultSetType.FORWARD_ONLY) @Select("SELECT * FROM department WHERE status = 0") List<DepartmentEntity> queryDepartmentAll(); // 第二種 在Mybatis-3.4.0版本中,不支持@select注解,在3.4.1版本中已經(jīng)修復(fù): @Options(resultSetType = ResultSetType.FORWARD_ONLY) @Select("SELECT * FROM department WHERE status = 0") Cursor<Employee> cursorQueryDepartmentAll();
@Service public class DepartmentServiceImpl implements DepartmentService { private static final Logger LOG = LoggerFactory.getLogger(DepartmentServiceImpl.class); @Autowired private DepartmentDao departmentDao; @Autowired private SqlSessionTemplate sqlSessionTemplate; public List<DepartmentDTO> getDepartmentList(DepartmentSearchParam param) { Cursor<Object> cursor = null; SqlSession sqlSession = null; try { sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(); cursor = sqlSession.selectCursor(DepartmentDao.class.getName() + ".queryDepartmentAll"); cursor.forEach(e -> { // 處理邏輯 }); // 也可以使用迭代器:Iterator<Object> iterator = cursor.iterator(); } catch (Exception e) { e.printStackTrace(); } finally { if (null != cursor) { try { cursor.close(); } catch (Exception e) { LOG.error(e.getMessage(), e); } } if (null != sqlSession) { try { sqlSession.close(); } catch (Exception e) { LOG.error(e.getMessage(), e); } } } } }
ResultSet.TYPE_FORWORD_ONLY
結(jié)果集的游標(biāo)只能向下滾動。
ResultSet.TYPE_SCROLL_INSENSITIVE
結(jié)果集的游標(biāo)可以上下移動,當(dāng)數(shù)據(jù)庫變化時,當(dāng)前結(jié)果集不變。
ResultSet.TYPE_SCROLL_SENSITIVE
返回可滾動的結(jié)果集,當(dāng)數(shù)據(jù)庫變化時,當(dāng)前結(jié)果集同步改變。
注意:游標(biāo)是可以前后移動的。如果resultSetType = TYPE_SCROLL_INSENSITIVE ,就是設(shè)置游標(biāo)就可以前后移動。
Mybatis為了保證可以前后移動,Mybatis會把之前查詢的數(shù)據(jù)一直保存在內(nèi)存中。
所以并不能根本解決OOM,所以我們這里需要設(shè)置為@Options(resultSetType = ResultSetType.FORWARD_ONLY)(其實默認(rèn)就是ResultSetType.FORWARD_ONLY)
感謝各位的閱讀,以上就是“Mybatis游標(biāo)查詢大量數(shù)據(jù)的方法是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Mybatis游標(biāo)查詢大量數(shù)據(jù)的方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。