Mybatis游标查询大量数据方式

网友投稿 2588 2022-11-02

Mybatis游标查询大量数据方式

Mybatis游标查询大量数据方式

目录Mybatis游标查询大量数据mapper层service层 资源释放Mybatis游标使用总结什么是游标

Mybatis游标查询大量数据

对大量数据进行处理时,为防止内存泄漏情况发生,所以采用mybatis plus游标方式进行数据查询处理,当查询百万级的数据的时候,使用游标可以节省内存的消耗,不需要一次性取出所有数据,可以进行逐条处理或逐条取出部分批量处理

mapper层

使用Cursor类型进行数据接收@Options,fetchSize设置为Integer最小值@Select,写查询sql

@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = Integer.MIN_VALUE)

@Select("select domain from illegal_domain where icpstatus != #{icpstatus}")

Cursor getDayJobDomain(@Param("icpstatus") Integer icpstatus);

service层

Cursor domainList = illegalDomainMapper.getDayJobDomain(1);

数据处理

forEach方式

domainList.forEach(illegalDomain -> {

//处理逻辑,根据业务需求自行完成

Future future = checkIcpThreadPool.submit(new IcpCheckThread(illegalDomain.getDomain(), configMap));

results.add(future);

});

迭代器

Iterator iter = domainList.iterator();

while (iter.hasNext()) {

//处理逻辑,根据业务需求自行完成

Future future = checkIcpThreadPool.submit(new IcpCheckThread(illegalDomain.getDomain(), configMap));

results.add(future);

}

资源释放

使用完毕后,在finally块释放资源,否则游标不关闭也可能会导致内存溢出问题

try{

//your code

} catch (Exception e) {

log.error(e);

} finally {

if(null != domainList){

try {

domainList.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

Mybatis游标使用总结

当查询百万级的数据的时候,查询出所有数据并放入内存中时会发生OOM(OutOfMemoryException),使用游标可以节省内存的消耗,不需要一次性取出所有数据,可以进行逐条处理或逐条取出部分批量处理,在此场景下就可以使用游标的概念来解决这个问题。

什么是游标

游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次一行或者多行前进或向后浏览数据的能力。

Demo:

// 第一种

@Options(resultSetType = ResultSetType.FORWARD_ONLY)

@Select("SELECT * FROM department WHERE status = 0")

List queryDepartmentAll();

// 第二种 在Mybatis-3.4.0版本中,不支持@select注解,在3.4.1版本中已经修复:

@Options(resultSetType = ResultSetType.FORWARD_ONLY)

@Select("SELECT * FROM department WHERE status = 0")

Cursor cursorQueryDepartmentAll();

@Service

public class DepartmentServiceImpl implements DepartmentService {

private static final Logger LOG = LoggerFactory.getLogger(DepartmentServichttp://eImpl.class);

@Autowired

private DepartmentDao departmentDao;

@Autowired

private SqlSessionTemplate sqlSessionTemplate;

public List getDepartmentList(DepartmentSearchParam param) {

Cursor cursor = null;

SqlSession sqlSession = null;

try {

sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession();

cursor = sqlSession.selectCursor(DepartmentDao.class.getName() + ".queryDepartmentAll");

cursor.forEach(e -> {

// 处理逻辑

});

// 也可以使用迭代器:Iterator iterator = cursor.iterator();

} catch (Exception e) {

e.printStackTrace();

} finally {

if (null != cursor) {

try {

cursor.close();

} catch (Exception e) {

LOG.erromddCFAjr(e.getMessage(), e);

}

}

if (null != sqlSession) {

try {

sqlSession.close();

} catch (Exception e) {

LOG.error(e.getMessage(), e);

}

}

}

}

}

ResultSet.TYPE_FORWORD_ONLY 结果集的游标只能向下滚动。ResultSet.TYPE_SCROLL_INSENSITIVE 结果集的游标可以上下移动,当数据库变化时,当前结果集不变。ResultSet.TYPE_SCROLL_SENSITIVE 返回可滚动的结果集,当数据库变化时,当前结果集同步改变。

注意:游标是可以前后移动的。如果resultSetType = TYPE_SCROLL_INSENSITIVE ,就是设置游标就可以前后移动。

Mybatis为了保证可以前后移动,Mybatis会把之前查询的数据一直保存在内存中。

所以并不能根本解决OOM,所以我们这里需要设置为@OptmddCFAjions(resultSetType = ResultSetType.FORWARD_ONLY)(其实默认就是ResultSetType.FORWARD_ONLY)

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Fuse Studio是一款可视桌面工具套件,可用于Fuse框架
下一篇:Nightwatch.js - 基于Node.js和Webdriver的自动化测试与持续集成框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~