一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - 詳解mybatis 批量更新數據兩種方法效率對比

詳解mybatis 批量更新數據兩種方法效率對比

2021-07-14 15:31第一小菜鳥 Java教程

這篇文章主要介紹了詳解mybatis 批量更新數據兩種方法效率對比,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

上節探討了批量新增數據,這節探討批量更新數據兩種寫法的效率問題。

實現方式有兩種,

一種用for循環通過循環傳過來的參數集合,循環出n條sql,

另一種 用mysql的case when 條件判斷變相的進行批量更新  

下面進行實現。

注意第一種方法要想成功,需要在db鏈接url后面帶一個參數  &allowmultiqueries=true

即:  jdbc:mysql://localhost:3306/mysqltest?characterencoding=utf-8&allowmultiqueries=true

其實這種東西寫過來寫過去就是差不多一樣的代碼,不做重復的贅述,直接上代碼。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!-- 這次用resultmap接收輸出結果 -->
 <select id="findbyname" parametertype="string" resultmap="customermap">
   select * from t_customer where c_name like concat('%', #{name},'%') order by c_cerono limit 0,100
 </select>
 
 
 <!-- 批量更新第一種方法,通過接收傳進來的參數list進行循環著組裝sql -->
 <update id="batchupdate" parametertype="java.util.map">
   <!-- 接收list參數,循環著組裝sql語句,注意for循環的寫法
      separator=";" 代表著每次循環完,在sql后面放一個分號
      item="cus" 循環list的每條的結果集
      collection="list" list 即為 map傳過來的參數key -->
   <foreach collection="list" separator=";" item="cus">
     update t_customer set
     c_name = #{cus.name},
     c_age = #{cus.age},
     c_sex = #{cus.sex},
     c_cerono = #{cus.cerono},
     c_cerotype = #{cus.cerotype}
     where id = #{cus.id}
   </foreach>
 </update>
 
 <!-- 批量更新第二種方法,通過 case when語句變相的進行批量更新 -->
 <update id="batchupdatecasewhen" parametertype="java.util.map">
   update t_customer
   <trim prefix="set" suffixoverrides=",">
     <!-- 拼接case when 這是一種寫法 -->
     <!--<foreach collection="list" separator="" item="cus" open="c_age = case id" close="end, ">-->
     <!--when #{cus.id} then #{cus.age}-->
     <!--</foreach>-->
 
     <!-- 拼接case when 這是另一種寫法,這種寫著更專業的感覺 -->
     <trim prefix="c_name =case" suffix="end,">
       <foreach collection="list" item="cus">
         <if test="cus.name!=null">
           when id=#{cus.id} then #{cus.name}
         </if>
       </foreach>
     </trim>
     <trim prefix="c_age =case" suffix="end,">
       <foreach collection="list" item="cus">
         <if test="cus.age!=null">
           when id=#{cus.id} then #{cus.age}
         </if>
       </foreach>
     </trim>
     <trim prefix="c_sex =case" suffix="end,">
       <foreach collection="list" item="cus">
         <if test="cus.sex!=null">
           when id=#{cus.id} then #{cus.sex}
         </if>
       </foreach>
     </trim>
     <trim prefix="c_cerono =case" suffix="end,">
       <foreach collection="list" item="cus">
         <if test="cus.cerono!=null">
           when id=#{cus.id} then #{cus.cerono}
         </if>
       </foreach>
     </trim>
     <trim prefix="c_cerotype =case" suffix="end,">
       <foreach collection="list" item="cus">
         <if test="cus.cerotype!=null">
           when id=#{cus.id} then #{cus.cerotype}
         </if>
       </foreach>
     </trim>
   </trim>
   <where>
     <foreach collection="list" separator="or" item="cus">
       id = #{cus.id}
     </foreach>
   </where>
 </update>

接口

?
1
2
3
4
5
list<customer> findbyname(string name);
 
 int batchupdate(map<string,object> param);
 
 int batchupdatecasewhen(map<string,object> param);

實現類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
  * 用于更新時,獲取更新數據
  * @param name
  * @return
  */
 public list<customer> findbyname(string name) {
   sqlsession sqlsession = null;
   try {
     sqlsession = sqlsessionutil.getsqlsession();
     return sqlsession.selectlist("customer.findbyname", name);
   } catch (exception e) {
     e.printstacktrace();
   } finally {
     sqlsessionutil.closesession(sqlsession);
   }
   return new arraylist<customer>();
 }
 
 
 /**
  * 批量更新第一種方式
  * @param param
  * @return
  */
 public int batchupdate(map<string,object> param) {
   return bathupdate("customer.batchupdate",param);
 }
 
 /**
  * 批量更新第二種方式
  * @param param
  * @return
  */
 public int batchupdatecasewhen(map<string,object> param) {
   return bathupdate("customer.batchupdatecasewhen",param);
 }
 
 /**
  * 公共部分提出
  * @param statementid
  * @param param
  * @return
  */
 private int bathupdate(string statementid,map param){
   sqlsession sqlsession = null;
   try {
     sqlsession = sqlsessionutil.getsqlsession();
     int key = sqlsession.update(statementid, param);
     // commit
     sqlsession.commit();
     return key;
   } catch (exception e) {
     sqlsession.rollback();
     e.printstacktrace();
   } finally {
     sqlsessionutil.closesession(sqlsession);
   }
   return 0;
 }

測試前準備   首先用上節的 批量插入,插入10000條數據以備下面的批量更新用。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@test
  public void batchinsert() throws exception {
    map<string,object> param = new hashmap<string,object>();
    list<customer> list = new arraylist<customer>();
    for(int i=0;i<10000;i++){
      customer customer = new customer();
      customer.setname("準備數據" + i);
      customer.setage(15);
      customer.setcerono("111111111111"+i);
      customer.setcerotype(2);
      customer.setsex(1);
      list.add(customer);
    }
    param.put("list",list);
    long start = system.currenttimemillis();
    int result = customerdao.batchinsert(param);
    system.out.println("耗時 : "+(system.currenttimemillis() - start));
  }

開始進行測試效率問題。

首先進行的是測試十條數據。調整查詢數據為查詢十條

?
1
2
3
4
<!-- 這次用resultmap接收輸出結果 -->
<select id="findbyname" parametertype="string" resultmap="customermap">
  select * from t_customer where c_name like concat('%', #{name},'%') order by c_cerono limit 0,10
</select>

測試類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@test
public void batchudpate() throws exception {
  map<string,object> param = new hashmap<string,object>();
 
  param.put("list",getfindbyname("準備數據","批量更新01"));
  long start = system.currenttimemillis();
  customerdao.batchupdate(param);
  system.out.println("耗時 : "+(system.currenttimemillis() - start));
}
 
@test
public void batchudpatecasewhen() throws exception {
  map<string,object> param = new hashmap<string,object>();
  param.put("list",getfindbyname("批量更新01","準備數據"));
  long start = system.currenttimemillis();
  customerdao.batchupdatecasewhen(param);
  system.out.println("耗時 : "+(system.currenttimemillis() - start));
}
 
private list<customer> getfindbyname(string name, string change){
  list<customer> list = customerdao.findbyname(name);
  system.out.println("查詢出來的條數 : " + list.size());
  if(null != change && !"".equals(change)){
    for(customer customer : list){
      customer.setname(change);
    }
  }
 
  return list;
}

第一種拼完整sql的方式耗時:

詳解mybatis 批量更新數據兩種方法效率對比

第二種case when 耗時情況:

詳解mybatis 批量更新數據兩種方法效率對比

結果可以看出,其實case when 耗時比較多。

下面來加大數據量到100條;

第一種拼完整sql的方式耗時:

詳解mybatis 批量更新數據兩種方法效率對比

第二種case when 耗時情況:

詳解mybatis 批量更新數據兩種方法效率對比

結果可以看出,其實case when 耗時仍然比第一種多。

繼續加大數據量到1000條

第一種拼完整sql的方式耗時:

詳解mybatis 批量更新數據兩種方法效率對比

第二種case when 耗時情況:

詳解mybatis 批量更新數據兩種方法效率對比

結果可以看出,其實case when 耗時仍然比第一種多。

繼續加大數據量到10000條

第一種拼完整sql的方式耗時:

詳解mybatis 批量更新數據兩種方法效率對比

第二種case when 耗時情況:

詳解mybatis 批量更新數據兩種方法效率對比

結果可以看出,兩種方式進行批量更新,效率已經不在一個數量級了。case when明顯的慢的多。

看網上有人說第一種的效率跟用代碼循環著一條一條的循環著插入的效率差不多,通過測試我就有疑問了,他是怎么做到的。難道我的代碼有問題?明明第一種的效率很高嘛。

第一種效率其實相當高的,因為它僅僅有一個循環體,只不過最后update語句比較多,量大了就有可能造成sql阻塞。

第二種雖然最后只會有一條更新語句,但是xml中的循環體有點多,每一個case when 都要循環一遍list集合,所以大批量拼sql的時候會比較慢,所以效率問題嚴重。使用的時候建議分批插入。

根據效率,安全方面綜合考慮,選擇適合的很重要。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/xu1916659422/article/details/77971696/

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 19+韩国女主播激情vip视频在线 | 91网站入口 | 99精品网站| 久久福利影院 | 免费看男人使劲躁女人小说 | 国产在线欧美日韩精品一区二区 | 色欲麻豆国产福利精品 | 美女的隐私脱裤子无遮挡 | 无颜之月全集免费观看 | 236宅宅2021最新理论 | 好姑娘在线视频观看免费 | 无敌在线视频观看免费 | 国产在线视频自拍 | 美女视频黄a | a级毛片毛片免费很很综合 a级黄色视屏 | 黑人性xxxⅹxxbbbbb | 亚洲国产精品无码中文字幕 | chinses台湾男同志hd | 成人榴莲视频 | 国产清纯女高中生在线观看 | 乌克兰肥熟 | 人人澡人| 日韩高清在线观看 | eeuss18影院www国产 | 日本不卡视频免费的 | 免费99精品国产自在现线 | 青青色在线观看 | 免费看又黄又爽又猛的视频软件- | 91tv在线| 91大神第九部红酒气质女 | 暖暖视频免费观看视频中国.韩剧 | 日本亚洲娇小与黑人tube | 日韩精品视频在线播放 | 91探花在线观看 | 国产农村一级特黄α真人毛片 | 美女69xx | 日本大尺度动漫在线观看缘之空 | 国产成人综合网亚洲欧美在线 | 全彩成人18h漫画 | 国产成人欧美视频在线 | 日本乱中文字幕系列在线观看 |