聊聊jdbc的batch操作

本文主要研究一下jdbc的batch的使用以及jpa的batch設(shè)置

batch

statement的batch操作,可以批量進行insert或update操作包雀,提升操作性能亲铡,特別是在大數(shù)據(jù)量的insert或update的時候。

使用方式

    @Test
    public void testSqlInjectSafeBatch(){
        String sql = "insert into employee (name, city, phone) values (?, ?, ?)";

        Connection conn = null;
        PreparedStatement pstmt = null;

        try{
            conn = dataSource.getConnection();
            conn.setAutoCommit(false);
            pstmt = conn.prepareStatement(sql);

            for (int i=0;i<3;i++) {
                pstmt.setString(1,"name"+i);
                pstmt.setString(2,"city"+i);
                pstmt.setString(3,"iphone"+i);
                pstmt.addBatch();
            }
            pstmt.executeBatch();

            conn.commit();

        }catch (SQLException e){
            e.printStackTrace();
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }finally {
            DbUtils.closeQuietly(pstmt);
            DbUtils.closeQuietly(conn);
        }
    }

主要就是每條操作參數(shù)設(shè)置完之后赞草,調(diào)用addBatch方法吆鹤,然后再所有操作都pstmt.addBatch()完之后,調(diào)用pstmt.executeBatch()
這種方式有個缺陷就是數(shù)據(jù)量大容易消耗內(nèi)存轰异,因此建議再分批次處理

@Test
    public void testSqlInjectSafeAndOOMSafeBatch(){
        String sql = "insert into employee (name, city, phone) values (?, ?, ?)";

        Connection conn = null;
        PreparedStatement pstmt = null;

        final int batchSize = 1000;
        int count = 0;

        try{
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement(sql);

            for (int i=0;i<10000;i++) {
                pstmt.setString(1,"name"+i);
                pstmt.setString(2,"city"+i);
                pstmt.setString(3,"iphone"+i);
                pstmt.addBatch();

                //小批量提交,避免OOM
                if(++count % batchSize == 0) {
                    pstmt.executeBatch();
                }
            }

            pstmt.executeBatch(); //提交剩余的數(shù)據(jù)

        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            DbUtils.closeQuietly(pstmt);
            DbUtils.closeQuietly(conn);
        }
    }

jpa的batch設(shè)置

spring:
  jpa:
    database-platform: org.hibernate.dialect.PostgreSQLDialect
    hibernate:
      ddl-auto: update
      naming:
        implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
        physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
    show-sql: true
    properties:
      hibernate:
        format_sql: true
        jdbc:
          batch_size: 5000
          batch_versioned_data: true
        order_inserts: true
        order_updates: true

通過設(shè)置spring.jpa.properties.hibernate.jdbc.batch_size來設(shè)置批量

實例測試

    @Test
    public void testJpaBatch() {
        List<DemoUser> demoUsers = new ArrayList<>();
        for(int i=0;i<10;i++){
            DemoUser demoUser = new DemoUser();
            demoUser.setPrincipal("demo");
            demoUser.setAccessToken(UUID.randomUUID().toString());
            demoUser.setAuthType(UUID.randomUUID().toString());
            demoUser.setDeptName(UUID.randomUUID().toString());
            demoUser.setOrgName(UUID.randomUUID().toString());
            demoUsers.add(demoUser);
        }
        StopWatch stopWatch = new StopWatch("jpa batch");
        stopWatch.start();
        demoUserDao.save(demoUsers);
        stopWatch.stop();
        System.out.println(stopWatch.prettyPrint());
    }

調(diào)整batch_size參數(shù)的測試結(jié)果

     沒有設(shè)置批量
     * StopWatch 'jpa batch': running time (millis) = 21383
     -----------------------------------------
     ms     %     Task name
     -----------------------------------------
     21383  100%

     設(shè)置批量500
     StopWatch 'jpa batch': running time (millis) = 16790
     -----------------------------------------
     ms     %     Task name
     -----------------------------------------
     16790  100%

     批量1000
     StopWatch 'jpa batch': running time (millis) = 12317
     -----------------------------------------
     ms     %     Task name
     -----------------------------------------
     12317  100%

     批量5000
     StopWatch 'jpa batch': running time (millis) = 13190
     -----------------------------------------
     ms     %     Task name
     -----------------------------------------
     13190  100%

小結(jié)

jdbc的batch參數(shù)對于大數(shù)據(jù)量的新增/更新操作來說搭独,非常有用廊镜,可以提升批量操作的效率。

doc

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吱雏,隨后出現(xiàn)的幾起案子瘾境,更是在濱河造成了極大的恐慌镰惦,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兑凿,死亡現(xiàn)場離奇詭異茵瘾,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門聘殖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來行瑞,“玉大人奸腺,你說我怎么就攤上這事血久。” “怎么了讹蘑?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵筑舅,是天一觀的道長。 經(jīng)常有香客問我版仔,道長误墓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任然想,我火速辦了婚禮,結(jié)果婚禮上又沾,老公的妹妹穿的比我還像新娘。我一直安慰自己杖刷,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布役听。 她就那樣靜靜地躺著表窘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瘤袖。 梳的紋絲不亂的頭發(fā)上昂验,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音既琴,去河邊找鬼。 笑死逆济,一個胖子當著我的面吹牛磺箕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播松靡,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼涎劈!你這毒婦竟也來了阅茶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蹦浦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后盲镶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡枫吧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年宇色,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片例隆。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡抢蚀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出皿曲,到底是詐尸還是另有隱情,我是刑警寧澤惶我,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布博投,位于F島的核電站盯蝴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏捧挺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一翅睛、第九天 我趴在偏房一處隱蔽的房頂上張望黑竞。 院中可真熱鬧,春花似錦很魂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凡纳。三九已至,卻和暖如春惫企,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丛版。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工偏序, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人研儒。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓端朵,卻偏偏與公主長得像好芭,于是被迫代替她去往敵國和親冲呢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容