這篇文章主要介紹了如何使用Mybatis的Batch Insert Support實現批量插入的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇如何使用Mybatis的Batch Insert Support實現批量插入文章都會有所收獲,下面我們一起來看看吧。
在開發中如果遇到需要批量insert的需求,可以使用Mybatis 的 Batch Insert Support 提高插入效率。
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
public int insertFolder(List<IpsCatalogFolderDetail> ips) {
//獲取sql會話
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
//通過新的session獲取mapper,而不是常規的spring管理注入
IipsCatalogFolderDetailDao folderDetailDao = session.getMapper(IipsCatalogFolderDetailDao.class);
int size = ips.size();
//如果有父類子類兩層都需要批量插入也可
try {
//外層循環
for (int i = 0; i < size; i++) {
ips.get(i).setType("folder");
//用上面在session中獲取的mapper進行插入操作
folderDetailDao.insertFolder(ips.get(i));
//內層循環
String cs = ips.get(i).getContentIds();
if (StringUtils.isNotBlank(cs)){
List<String> con = JSON.parseArray(cs,String.class);
if (cs != null && con.size() > 0) {
for (int j = 0; j < con.size(); j++) {
IpsCatalogFolderDetail ifd = new IpsCatalogFolderDetail();
ifd.setParentCode(ips.get(i).getCode());
ifd.setContentId(con.get(j));
ifd.setType("contents");
//同樣用上面在session中獲取的mapper進行插入操作
folderDetailDao.insertFolder(ifd);
}
}
}
//最后批量提交
if (i % 200 == 0 || i == size - 1) {
session.commit();//200個提交一次,手動提交,提交后無法回滾
session.clearCache(); //清理緩存,防止溢出
}
}
}catch (Exception e) {
System.out.println(e.toString());
session.rollback(); //沒有提交的數據可以回滾
} finally {
session.close();
}
return 0;
}另外有時我們在插入的時候需要先查詢數據是否已存在,如果也需要批量操作可將insert和update語句合并,然后就可以繼續使用Batch Insert了
@Insert("merge into ips_catalog_folder_detail fd " +
"using(select #{code,jdbcType=VARCHAR} c from dual)t " +
"on(fd.FOLDERID = t.c)" +
"when matched then"+
"update set "+
...(省略)...
"where ..."+
"when not matched then insert(" +
"fd.PROD_LINE," +
"fd.TYPE," +
"fd.PARENTFOLDERCODE," +
"fd.FOLDERID," +
"fd.FOLDERCODE," +
"fd.FOLDERNAME," +
"fd.COLUMN_SORTINDEX," +
"fd.DESCRIPTION," +
"fd.CONTENTID," +
"fd.CREATETIME" +
")" +
"VALUES" +
"(" +
"#{prod_line}," +
"#{type,jdbcType=VARCHAR}," +
"#{parentCode,jdbcType=VARCHAR}," +
"#{code,jdbcType=VARCHAR}," +
"#{aliasCode,jdbcType=VARCHAR}," +
"#{name,jdbcType=VARCHAR}," +
"#{sortIndex,jdbcType=VARCHAR}," +
"#{desc,jdbcType=VARCHAR}," +
"#{contentId,jdbcType=VARCHAR}," +
"#{createTime,jdbcType=VARCHAR}" +
")")
int insertFolder(IpsCatalogFolderDetail fd);MYSQL示例:
REPLACE INTO users (id,name,age) VALUES(1, '張雨綺', 32);
經排查發現,主要時間消耗在往MyBatis中批量插入數據。mapper configuration是用foreach循環做的,差不多是這樣。
<insert id="batchInsert" parameterType="java.util.List">
insert into USER (id, name) values
<foreach collection="list" item="model" index="index" separator=",">
(#{model.id}, #{model.name})
</foreach>
</insert>可以看 http://www.mybatis.org/mybatis-dynamic-sql/docs/insert.html 中 Batch Insert Support 標題里的內容)
SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
SimpleTableMapper mapper = session.getMapper(SimpleTableMapper.class);
List<SimpleTableRecord> records = getRecordsToInsert(); // not shown
BatchInsert<SimpleTableRecord> batchInsert = insert(records)
.into(simpleTable)
.map(id).toProperty("id")
.map(firstName).toProperty("firstName")
.map(lastName).toProperty("lastName")
.map(birthDate).toProperty("birthDate")
.map(employed).toProperty("employed")
.map(occupation).toProperty("occupation")
.build()
.render(RenderingStrategy.MYBATIS3);
batchInsert.insertStatements().stream().forEach(mapper::insert);
session.commit();
} finally {
session.close();
}總結一下,如果MyBatis需要進行批量插入,推薦使用 ExecutorType.BATCH 的插入方式,如果非要使用 <foreach>的插入的話,需要將每次插入的記錄控制在 20~50 左右
關于“如何使用Mybatis的Batch Insert Support實現批量插入”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“如何使用Mybatis的Batch Insert Support實現批量插入”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。