<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MyBatis 三種批量插入方式的比較,我推薦第3個(gè)!

          共 1450字,需瀏覽 3分鐘

           ·

          2021-11-28 14:45

          往期熱門文章:

          1、有了 for (;;) ,為什么還需要while (true) ?到底哪個(gè)更快?

          2、名企公開(kāi)掛“加班真好”標(biāo)語(yǔ),員工稱一年被免費(fèi)“白嫖”600多小時(shí)!網(wǎng)友看不下去了,稽查部門展開(kāi)調(diào)查...

          3、面試官:為什么 Java 不把基本類型放在堆中?我竟然答不上來(lái)。。

          4、IDEA 注釋模板這樣搞!

          5、后端開(kāi)掛:3行代碼寫出8個(gè)接口!

          來(lái)源:jianshu.com/p/cce617be9f9e

          數(shù)據(jù)庫(kù)使用的是SQLServer,JDK版本1.8,運(yùn)行在SpringBoot環(huán)境下 對(duì)比3種可用的方式

          • 反復(fù)執(zhí)行單條插入語(yǔ)句
          • xml拼接sql
          • 批處理執(zhí)行

          先說(shuō)結(jié)論:少量插入請(qǐng)使用反復(fù)插入單條數(shù)據(jù),方便。數(shù)量較多請(qǐng)使用批處理方式。(可以考慮以有需求的插入數(shù)據(jù)量20條左右為界吧,在我的測(cè)試和數(shù)據(jù)庫(kù)環(huán)境下耗時(shí)都是百毫秒級(jí)的,方便最重要)無(wú)論何時(shí)都不用xml拼接sql的方式。


          拼接SQL的xml

          newId()是sqlserver生成UUID的函數(shù),與本文內(nèi)容無(wú)關(guān)

          "insertByBatch"?parameterType="java.util.List">
          ????INSERT?INTO?tb_item?VALUES
          ????"list"?item="item"?index="index"?separator=",">
          ????????(newId(),#{item.uniqueCode},#{item.projectId},#{item.name},#{item.type},#{item.packageUnique},
          ????????#{item.isPackage},#{item.factoryId},#{item.projectName},#{item.spec},#{item.length},#{item.weight},
          ????????#{item.material},#{item.setupPosition},#{item.areaPosition},#{item.bottomHeight},#{item.topHeight},
          ????????#{item.serialNumber},#{item.createTime}

          Mapper接口Mapper?是?mybatis插件tk.Mapper?的接口,與本文內(nèi)容關(guān)系不大

          public?interface?ItemMapper?extends?Mapper<Item>?{
          ????int?insertByBatch(List?itemList);
          }

          Service類

          @Service
          public?class?ItemService?{
          ????@Autowired
          ????private?ItemMapper?itemMapper;
          ????@Autowired
          ????private?SqlSessionFactory?sqlSessionFactory;
          ????//批處理
          ????@Transactional
          ????public?void?add(List?itemList)?{
          ????????SqlSession?session?=?sqlSessionFactory.openSession(ExecutorType.BATCH,false);
          ????????ItemMapper?mapper?=?session.getMapper(ItemMapper.class);
          ????????for?(int?i?=?0;?i?????????????mapper.insertSelective(itemList.get(i));
          ????????????if(i%1000==999){//每1000條提交一次防止內(nèi)存溢出
          ????????????????session.commit();
          ????????????????session.clearCache();
          ????????????}
          ????????}
          ????????session.commit();
          ????????session.clearCache();
          ????}
          ????//拼接sql
          ????@Transactional
          ????public?void?add1(List?itemList)?{
          ????????itemList.insertByBatch(itemMapper::insertSelective);
          ????}
          ????//循環(huán)插入
          ????@Transactional
          ????public?void?add2(List?itemList)?{
          ????????itemList.forEach(itemMapper::insertSelective);
          ????}
          }

          測(cè)試類

          @RunWith(SpringRunner.class)
          @SpringBootTest(webEnvironment?
          =?SpringBootTest.WebEnvironment.RANDOM_PORT,?classes?=?ApplicationBoot.class)
          public?class?ItemServiceTest?
          {
          ????@Autowired
          ????ItemService?itemService;

          ????private?List?itemList?=?new?ArrayList<>();
          ????//生成測(cè)試List
          ????@Before?
          ????public?void?createList(){
          ????????String?json?="{\n"?+
          ????????????????"????????\"areaPosition\":?\"TEST\",\n"?+
          ????????????????"????????\"bottomHeight\":?5,\n"?+
          ????????????????"????????\"factoryId\":?\"0\",\n"?+
          ????????????????"????????\"length\":?233.233,\n"?+
          ????????????????"????????\"material\":?\"Q345B\",\n"?+
          ????????????????"????????\"name\":?\"TEST\",\n"?+
          ????????????????"????????\"package\":?false,\n"?+
          ????????????????"????????\"packageUnique\":?\"45f8a0ba0bf048839df85f32ebe5bb81\",\n"?+
          ????????????????"????????\"projectId\":?\"094b5eb5e0384bb1aaa822880a428b6d\",\n"?+
          ????????????????"????????\"projectName\":?\"項(xiàng)目_TEST1\",\n"?+
          ????????????????"????????\"serialNumber\":?\"1/2\",\n"?+
          ????????????????"????????\"setupPosition\":?\"1B柱\",\n"?+
          ????????????????"????????\"spec\":?\"200X200X200\",\n"?+
          ????????????????"????????\"topHeight\":?10,\n"?+
          ????????????????"????????\"type\":?\"Steel\",\n"?+
          ????????????????"????????\"uniqueCode\":?\"12344312\",\n"?+
          ????????????????"????????\"weight\":?100\n"?+
          ????????????????"????}";
          ????????Item?test1?=?JSON.parseObject(json,Item.class);
          ????????test1.setCreateTime(new?Date());
          ????????for?(int?i?=?0;?i?1000;?i++)?{//測(cè)試會(huì)修改此數(shù)量
          ????????????itemList.add(test1);
          ????????}
          ????}
          ?????//批處理
          ????@Test
          ????@Transactional
          ????public?void?tesInsert()?{
          ????????itemService.add(itemList);
          ????}
          ????//拼接字符串
          ????@Test
          ????@Transactional
          ????public?void?testInsert1(){
          ????????itemService.add1(itemList);
          ????}
          ????//循環(huán)插入
          ????@Test
          ????@Transactional
          ????public?void?testInsert2(){
          ????????itemService.add2(itemList);
          ????}
          }

          測(cè)試結(jié)果:

          10條 25條數(shù)據(jù)插入經(jīng)多次測(cè)試,波動(dòng)性較大,但基本都在百毫秒級(jí)別

          其中 拼接sql方式在插入500條和1000條時(shí)報(bào)錯(cuò)(似乎是因?yàn)閟ql語(yǔ)句過(guò)長(zhǎng),此條跟數(shù)據(jù)庫(kù)類型有關(guān),未做其他數(shù)據(jù)庫(kù)的測(cè)試):com.microsoft.sqlserver.jdbc.SQLServerException: 傳入的表格格式數(shù)據(jù)流(TDS)遠(yuǎn)程過(guò)程調(diào)用(RPC)協(xié)議流不正確,此RPC請(qǐng)求中提供了過(guò)多的參數(shù),最多應(yīng)為2100

          可以發(fā)現(xiàn)

          • 循環(huán)插入的時(shí)間復(fù)雜度是 O(n),并且常數(shù)C很大
          • 拼接SQL插入的時(shí)間復(fù)雜度(應(yīng)該)是 O(logn),但是成功完成次數(shù)不多,不確定
          • 批處理的效率的時(shí)間復(fù)雜度是 O(logn),并且常數(shù)C也比較小

          結(jié)論

          循環(huán)插入單條數(shù)據(jù)雖然效率極低,但是代碼量極少,在使用tk.Mapper的插件情況下,僅需代碼,:

          @Transactional
          public?void?add1(List?itemList)?{
          ????itemList.forEach(itemMapper::insertSelective);
          }

          因此,在需求插入數(shù)據(jù)數(shù)量不多的情況下肯定用它了。

          xml拼接sql是最不推薦的方式,使用時(shí)有大段的xml和sql語(yǔ)句要寫,很容易出錯(cuò),工作效率很低。更關(guān)鍵點(diǎn)是,雖然效率尚可,但是真正需要效率的時(shí)候你掛了,要你何用?

          批處理執(zhí)行是有大數(shù)據(jù)量插入時(shí)推薦的做法,使用起來(lái)也比較方便。

          最近熱文閱讀:

          1、有了 for (;;) ,為什么還需要while (true) ?到底哪個(gè)更快?
          2、名企公開(kāi)掛“加班真好”標(biāo)語(yǔ),員工稱一年被免費(fèi)“白嫖”600多小時(shí)!網(wǎng)友看不下去了,稽查部門展開(kāi)調(diào)查...
          3、面試官:為什么 Java 不把基本類型放在堆中?我竟然答不上來(lái)。。
          4、IDEA 注釋模板這樣搞!
          5、后端開(kāi)掛:3行代碼寫出8個(gè)接口!
          6、推薦一款可視化配置 Nginx 的神器
          7、一款性能調(diào)優(yōu)利器 — 火焰圖
          8、Redis 實(shí)現(xiàn)限流的三種方式
          9、推薦 15 款常用開(kāi)發(fā)工具
          10、一次 QPS 翻倍的 Java 服務(wù)性能優(yōu)化
          關(guān)注公眾號(hào),你想要的Java都在這里

          瀏覽 82
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月天色度导航 | 欧美成人三级网站 | 黄片免费视频在线观看 | 国产 在线观看免费视频今夜 | 天天综合三区 |