mybatisクエリー大量データメモリオーバーフロー解決方法
4933 ワード
通常mybatisを使用する場合はメモリの問題は考慮されていませんが、今日はクエリーが必要なデータ量が多く、システムoomを直接招くことがあります.そのため、クエリーが大量に必要なsqlについて以下のように修正しました.
ダイレクトコード
ここではmybatisのフロークエリを使用しています.具体的な原理は、内部でResultContextを直接操作してデータを1つずつ取得し、handlerをコールバックするhandleResultメソッド処理です.
原理:
結果の比較:
図は上ではなく、非フロークエリを用いるメモリの使用時に線形に増加し、フロークエリを用いるメモリの使用は安定している.回避に成功しました.
また、mybatisフロークエリには、検証なしでbeanを注入し、springbootで@Configration方式を使用する方法もあります.
mapperでxmlのsqlにfetchSize="-21748483648",Integer.MIN_VALUE=-2147483648
リファレンス
jdbcのフロークエリhttp://ifeve.com/mysq-stream-search/
ダイレクトコード
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
@Test
public void test() {
MerchantOrderPushExample merchantOrderPushExample = new MerchantOrderPushExample();
MerchantOrderPushExample.Criteria criteria = merchantOrderPushExample.createCriteria();
criteria.andIdIsNotNull();
merchantOrderPushExample.setOrderByClause(" id desc");
HashMap param = new HashMap<>();
param.put("oredCriteria", merchantOrderPushExample.getOredCriteria());
param.put("orderByClause", merchantOrderPushExample.getOrderByClause());
// param.put("limit",20);
sqlSessionTemplate.select("com.xws.business.mapper.MerchantOrderPushMapper.selectByExample", param, resultContext -> {
MerchantOrderPush resultObject = (MerchantOrderPush) resultContext.getResultObject();
System.out.println(JSON.toJSONString(resultObject));
});
}
ここではmybatisのフロークエリを使用しています.具体的な原理は、内部でResultContextを直接操作してデータを1つずつ取得し、handlerをコールバックするhandleResultメソッド処理です.
原理:
private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler> resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
throws SQLException {
DefaultResultContext
結果の比較:
図は上ではなく、非フロークエリを用いるメモリの使用時に線形に増加し、フロークエリを用いるメモリの使用は安定している.回避に成功しました.
また、mybatisフロークエリには、検証なしでbeanを注入し、springbootで@Configration方式を使用する方法もあります.
mapperでxmlのsqlにfetchSize="-21748483648",Integer.MIN_VALUE=-2147483648
static void testCursor1() throws UnexpectedInputException, ParseException, Exception {
try {
Map param = new HashMap();
AccsDeviceInfoDAOExample accsDeviceInfoDAOExample = new AccsDeviceInfoDAOExample();
accsDeviceInfoDAOExample.createCriteria().andAppKeyEqualTo("12345").andAppVersionEqualTo("5.7.2.4.5")
.andPackageNameEqualTo("com.test.zlx");
param.put("oredCriteria", accsDeviceInfoDAOExample.getOredCriteria());
//
myMyBatisCursorItemReader.setParameterValues(param);
//
myMyBatisCursorItemReader.open(new ExecutionContext());
//
Long count = 0L;
AccsDeviceInfoDAO accsDeviceInfoDAO;
while ((accsDeviceInfoDAO = myMyBatisCursorItemReader.read()) != null) {
System.out.println(JSON.toJSONString(accsDeviceInfoDAO));
++count;
System.out.println(count);
}
} catch (Exception e) {
System.out.println("error:" + e.getLocalizedMessage());
} finally {
// do some
myMyBatisCursorItemReader.close();
}
}
リファレンス
jdbcのフロークエリhttp://ifeve.com/mysq-stream-search/