最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解mybatis 批量更新數(shù)據(jù)兩種方法效率對比

 更新時間:2019年02月01日 14:42:13   作者:第一小菜鳥  
這篇文章主要介紹了詳解mybatis 批量更新數(shù)據(jù)兩種方法效率對比,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

上節(jié)探討了批量新增數(shù)據(jù),這節(jié)探討批量更新數(shù)據(jù)兩種寫法的效率問題。

實現(xiàn)方式有兩種,

一種用for循環(huán)通過循環(huán)傳過來的參數(shù)集合,循環(huán)出N條sql,

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

下面進行實現(xiàn)。

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

即:  jdbc:mysql://localhost:3306/mysqlTest?characterEncoding=utf-8&allowMultiQueries=true

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

 <!-- 這次用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>
 
 
  <!-- 批量更新第一種方法,通過接收傳進來的參數(shù)list進行循環(huán)著組裝sql -->
  <update id="batchUpdate" parameterType="java.util.Map">
    <!-- 接收list參數(shù),循環(huán)著組裝sql語句,注意for循環(huán)的寫法
       separator=";" 代表著每次循環(huán)完,在sql后面放一個分號
       item="cus" 循環(huán)List的每條的結果集
       collection="list" list 即為 map傳過來的參數(shù)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 這是另一種寫法,這種寫著更專業(yè)的感覺 -->
      <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>

接口

 List<Customer> findByName(String name);
 
  int batchUpdate(Map<String,Object> param);
 
  int batchUpdateCaseWhen(Map<String,Object> param);

實現(xiàn)類

 /**
   * 用于更新時,獲取更新數(shù)據(jù)
   * @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;
  }

測試前準備   首先用上節(jié)的 mybatis學習之路----批量更新數(shù)據(jù) 批量插入,插入10000條數(shù)據(jù)以備下面的批量更新用。

@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("準備數(shù)據(jù)" + 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));
  }

開始進行測試效率問題。

首先進行的是測試十條數(shù)據(jù)。調整查詢數(shù)據(jù)為查詢十條

  <!-- 這次用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>

測試類

  @Test
  public void batchudpate() throws Exception {
    Map<String,Object> param = new HashMap<String,Object>();
 
    param.put("list",getFindByName("準備數(shù)據(jù)","批量更新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","準備數(shù)據(jù)"));
    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("查詢出來的條數(shù) : " + list.size());
    if(null != change && !"".equals(change)){
      for(Customer customer : list){
        customer.setName(change);
      }
    }
 
    return list;
  }

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

第二種case when 耗時情況:


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

下面來加大數(shù)據(jù)量到100條;

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

第二種case when 耗時情況:


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

繼續(xù)加大數(shù)據(jù)量到1000條

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

第二種case when 耗時情況:

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

繼續(xù)加大數(shù)據(jù)量到10000條

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

第二種case when 耗時情況:

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

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

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

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

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

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

相關文章

  • 使用aop實現(xiàn)全局異常處理

    使用aop實現(xiàn)全局異常處理

    這篇文章主要為大家詳細介紹了使用aop實現(xiàn)全局異常處理,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • java枚舉是如何保證線程安全的

    java枚舉是如何保證線程安全的

    這篇文章主要介紹了java枚舉是如何保證線程安全的。Java SE5提供了一種新的類型-Java的枚舉類型,關鍵字enum可以將一組具名的值的有限集合創(chuàng)建為一種新的類型,而這些具名的值可以作為常規(guī)的程序組件使用,這是一種非常有用的功能。,需要的朋友可以參考下
    2019-06-06
  • Java 線程同步詳解

    Java 線程同步詳解

    這篇文章主要給大家詳細介紹的是Java 線程同步的相關問題及代碼示例,有需要的小伙伴可以參考下
    2016-03-03
  • Java多線程編程中synchronized線程同步的教程

    Java多線程編程中synchronized線程同步的教程

    Java的synchronized關鍵字可以修飾方法和對象來構建線程間的同步,這里我們就來共同學習Java多線程編程中synchronized線程同步的教程:
    2016-07-07
  • 淺談JAVA版本號的問題 Java版本號與JDk版本

    淺談JAVA版本號的問題 Java版本號與JDk版本

    這篇文章主要介紹了淺談JAVA版本號的問題 Java版本號與JDk版本,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • java實現(xiàn)學生宿舍系統(tǒng)

    java實現(xiàn)學生宿舍系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)學生宿舍系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 詳解Mybatis核心類SqlSessionFactory的構建

    詳解Mybatis核心類SqlSessionFactory的構建

    這篇文章主要為大家詳細介紹了Mybatis核心類SqlSessionFactory的構建過程,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2022-12-12
  • Java OpenCV4.0.0實現(xiàn)實時人臉識別

    Java OpenCV4.0.0實現(xiàn)實時人臉識別

    這篇文章主要為大家詳細介紹了Java OpenCV4.0.0實現(xiàn)實時人臉識別,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • 深入理解java中的重載和覆蓋

    深入理解java中的重載和覆蓋

    下面小編就為大家?guī)硪黄钊肜斫鈐ava中的重載和覆蓋。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • Kotlin-Coroutines中的async與await異步協(xié)程管理

    Kotlin-Coroutines中的async與await異步協(xié)程管理

    這篇文章主要為大家介紹了Kotlin-Coroutines中的async與await異步協(xié)程管理,提升程序性能解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10

最新評論

句容市| 台湾省| 临洮县| 衡山县| 改则县| 阿坝| 和龙市| 庆阳市| 十堰市| 晋江市| 浦城县| 峨眉山市| 彰化县| 项城市| 准格尔旗| 永宁县| 黄浦区| 吉首市| 九龙城区| 阳新县| 崇州市| 关岭| 长宁县| 阳新县| 乐清市| 北安市| 黎川县| 吉林市| 南投市| 辉南县| 武城县| 清水河县| 军事| 肥城市| 贵南县| 民丰县| 葫芦岛市| 兰考县| 察雅县| 舟曲县| 定兴县|