Hibernate批量處理:

          Hibernate批量處理其實(shí)從性能上考慮,它是很不可取的,浪費(fèi)了很大的內(nèi)存。從它的機(jī)制上講,Hibernate它是先把符合條件的數(shù)據(jù)查出來,放到內(nèi)存當(dāng)中,然后再進(jìn)行操作。實(shí)際使用下來性能非常不理想,在筆者的實(shí)際
          使用中采用下面的第三種優(yōu)化方案的數(shù)據(jù)是:100000條數(shù)據(jù)插入數(shù)據(jù)庫(kù),主流臺(tái)式機(jī)的配置,需要約30分鐘,呵呵,暈倒.

          總結(jié)下來有三種來處理以解決性能問題:

          1:繞過Hibernate API ,直接通過 JDBC API 來做,這個(gè)方法性能上是比較好的。也是最快的.

          2:運(yùn)用存儲(chǔ)過程。

          3:還是用Hibernate API 來進(jìn)行常規(guī)的批量處理,可以也有變,變就變?cè)冢覀兛梢栽诓檎页鲆欢ǖ牧康臅r(shí)候,及時(shí)的將這些數(shù)據(jù)做完操作就

          刪掉,session.flush();session.evict(XX對(duì)象集); 這樣也可以挽救一點(diǎn)性能損失。這個(gè)“一定的量”要就要根據(jù)實(shí)際情況做定量參考了。一般為30-60左右,但效果仍然不理想.

          ?

          ?

          1:繞過Hibernate API ,直接通過 JDBC API 來做,這個(gè)方法性能上是比較好的,也是最快的。(實(shí)例為 更新操作)

          ?

          Transaction tx=session.beginTransaction(); //注意用的是hibernate事務(wù)處理邊界

          Connection conn=session.connection();

          PreparedStatement stmt=conn.preparedStatement("update CUSTOMER as C set C.sarlary=c.sarlary+1 where c.sarlary>1000");

          stmt.excuteUpdate();

          tx.commit(); //注意用的是hibernate事務(wù)處理邊界

          這小程序中,采用的是直接調(diào)用JDBC 的API 來訪問數(shù)據(jù)庫(kù),效率很高。避免了Hibernate 先查詢出來加載到內(nèi)存,再進(jìn)行操作引發(fā)的性能問題

          2:運(yùn)用存儲(chǔ)過程。但這種方式考慮到易植和程序部署的方便性,不建議使用.(實(shí)例為 更新操作)

          如果底層數(shù)據(jù)庫(kù)(如Oracle)支持存儲(chǔ)過程,也可以通過存儲(chǔ)過程來執(zhí)行批量更新。存儲(chǔ)過程直接在數(shù)據(jù)庫(kù)中運(yùn)行,速度更加快。在Oracle數(shù)

          據(jù)庫(kù)中可以定義一個(gè)名為batchUpdateCustomer()的存儲(chǔ)過程,代碼如下:


          代碼內(nèi)容
          create or replace procedure batchUpdateCustomer(p_age in number) as
          begin
          update CUSTOMERS set AGE=AGE+1 where AGE>p_age;
          end;?


          以上存儲(chǔ)過程有一個(gè)參數(shù)p_age,代表客戶的年齡,應(yīng)用程序可按照以下方式調(diào)用存儲(chǔ)過程:

          代碼內(nèi)容
          tx = session.beginTransaction();
          Connection con=session.connection();
          String procedure = "{call batchUpdateCustomer(?) }";
          CallableStatement cstmt = con.prepareCall(procedure);
          cstmt.setInt(1,0); //把年齡參數(shù)設(shè)為0
          cstmt.executeUpdate();
          tx.commit();?


          從上面程序看出,應(yīng)用程序也必須繞過Hibernate API,直接通過JDBC API來調(diào)用存儲(chǔ)過程。

          3:還是用Hibernate API 來進(jìn)行常規(guī)的批量處理,可以也有變,變就變?cè)冢覀兛梢栽诓檎页鲆欢ǖ牧康臅r(shí)候,及時(shí)的將這些數(shù)據(jù)做完操作就

          刪掉,session.flush();session.evict(XX對(duì)象集); 這樣也可以挽救一點(diǎn)性能損失。這個(gè)“一定的量”要就要根據(jù)實(shí)際情況做定量參考了。。

          (實(shí)例為 保存操作)

          業(yè)務(wù)邏輯為:我們要想數(shù)據(jù)庫(kù)插入10 0000 條數(shù)據(jù)

          tx=session.beginTransaction();

          for(int i=0;i<100000;i++)

          {

          Customer custom=new Customer();

          custom.setName("user"+i);

          session.save(custom);

          if(i%50==0) // 以每50個(gè)數(shù)據(jù)作為一個(gè)處理單元,也就是我上面說的“一定的量”,這個(gè)量是要酌情考慮的

          {

          session.flush();

          session.clear();

          }

          }

          這樣可以把系統(tǒng)維持在一個(gè)穩(wěn)定的范圍....

          posts - 41, comments - 7, trackbacks - 0, articles - 0

          Copyright © weibogao

          主站蜘蛛池模板: 共和县| 竹溪县| 连平县| 横山县| 云龙县| 屏东市| 云和县| 新竹市| 昌乐县| 荔浦县| 五指山市| 邹城市| 西畴县| 同心县| 河津市| 鞍山市| 宝丰县| 上饶市| 望奎县| 定陶县| 鸡西市| 高密市| 漾濞| 大关县| 惠州市| 海门市| 剑阁县| 泰兴市| 裕民县| 绍兴市| 德江县| 航空| 丰顺县| 大埔区| 怀安县| 会昌县| 拉孜县| 德令哈市| 平塘县| 伊宁县| 财经|