mybatis-plus 提供了根據id批量更新和修改的方法,這個大家都不陌生 但是當表沒有id的時候怎么辦
- 方案一: 手寫SQL
- 方案二: 手動獲取SqlSessionTemplate 就是把mybatis plus 干的事自己干了
- 方案三 : 重寫 executeBatch 方法
- 結論:
mybatis-plus 提供了根據id批量更新和修改的方法,這個大家都不陌生 但是當表沒有id的時候怎么辦)
方案一: 手寫SQL
- 這個就不說了,就是因為不想手寫SQL 所以才有這篇博客
方案二: 手動獲取SqlSessionTemplate 就是把mybatis plus 干的事自己干了
// 這種方法就是把mybatis的活在干一遍,還是一條一條處理的.只是共用一個session連接
@Autowired
private SqlSessionTemplate sqlSessionTemplate;// 新獲取一個模式為BATCH,自動提交為false的session
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);
static final BATCH_SIZE = 1000;
// XxxMapper 為 對應的mapper文件
XxxMapper xxMapper = session.getMapper(XxxMapper.class);
int size = updateList.size();
try {for(int i=0; i < size; i++) {// updateByXxx 寫好的單條數據的方法xxMapper.updateByXxx(updateList.get(i));if(i % BATCH_SIZE == 0 || i == size-1){//手動每1000個一提交,提交后無法回滾session.commit();//清理緩存,防止溢出session.clearCache();}}
}catch (Exception e) {session.rollback();
} finally {session.close();
}
方案三 : 重寫 executeBatch 方法
// mybatis plus 源碼@Transactional(rollbackFor = Exception.class)@Overridepublic boolean updateBatchById(Collection<T> entityList, int batchSize) {String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);return executeBatch(entityList, batchSize, (sqlSession, entity) -> {MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();param.put(Constants.ENTITY, entity);sqlSession.update(sqlStatement, param);});}
- mybatis plus 的 executeBatch
- 參考 mybatis plus 的updateBatchById 方法.
- 調用處:
//刪除方法 deleteList 是要刪除的主鍵list
List<String> deleteList = new ArrayList<>();
dao.batchDelete(deleteList, delete -> new QueryWrapper<String>().eq("xx", delete));// 修改方法 OBJ 代碼表對象
List<OBJ> updateList = new ArrayList<>();
dao.batchUpdate(updateList, update -> new LambdaQueryWrapper<OBJ>().eq(OBJ::getProductId, update.getProductId()));
- 接口
boolean batchUpdate(List<OBJ> updateList, Function<OBJ, LambdaQueryWrapper> queryWrapperFunction);boolean batchDelete(List<String> deleteList, Function<String, QueryWrapper> queryWrapperFunction);
- 重寫方法 實現
@Overridepublic boolean batchUpdate(List<OBJ> entityList, Function<OBJ, LambdaQueryWrapper> function) {return this.executeBatch(entityList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {ParamMap param = new ParamMap();param.put(Constants.ENTITY, entity);param.put(Constants.WRAPPER, function.apply(entity));sqlSession.update(this.getSqlStatement(SqlMethod.UPDATE), param);});}@Overridepublic boolean batchDelete(List<String> deleteList, Function<String, QueryWrapper> function) {return this.executeBatch(deleteList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {ParamMap param = new ParamMap();param.put(Constants.ENTITY, entity);param.put(Constants.WRAPPER, function.apply(entity));sqlSession.delete(this.getSqlStatement(SqlMethod.DELETE), param);});}
結論:
- 這種寫法其實批量的效率還是比較慢的,如果對性能沒有要求,并且還不想手寫SQL的,可以試一試.