[24] springbootはEasyExcelとスレッドプールを使用してExcelデータのマルチスレッドインポートを実現します

  Springboot の章の全体的なコラム: 


[1] springboot は Swagger を統合します (非常に詳細な

[2] springboot は swagger (カスタム) を統合します (非常に詳細)

[3] springboot 統合トークン (超詳細)

[4] springboot は mybatis-plus を統合します (非常に詳細) (オン)

[5] springboot は mybatis-plus を統合します (非常に詳細) (下記)

[6] springboot はカスタムのグローバル例外処理を統合します

[7] springboot は redis を統合します (非常に詳細)

[8] springbootはAOPを統合してログ操作を実現します(超詳細)

[9] springboot 統合タイミング タスク (超詳細)

[10] springboot は redis を統合してスタートアップ サービスを実現します。つまり、ホットスポット データをグローバルと redis に保存します (超詳細)

[イレブン] スプリングブートはクォーツを統合してタイミングタスクの最適化を実現します(超詳細)

[12] springboot はスレッド プールを統合して高い同時実行性を解決します (非常に詳細で、理解が容易です)

【その13】springbootは非同期呼び出しを統合して戻り値を取得する(超詳細)

[14] springboot は WebService を統合します (超詳細)

[15] springboot は WebService を統合します (パラメーターの受け渡しについて) (超詳細)

[16] springboot は WebSocket を統合します (超詳細)

[Seventeen] springboot が WebSocket を統合してチャット ルームを実現 (超詳細)

[18] springboot はカスタムのグローバル例外処理を実装します

[Nineteen] springboot は ElasticSearch の実戦を統合します (1 万文字)

[Twenty] スプリングブート統合フィルター戦闘

[21] springboot は実戦でのインターセプターを統合し、フィルターを比較します

[22] springboot統合活動7 (1) 実践的なデモンストレーション

【23】springboot統合スプリングビジネスの詳細説明と実戦

[24] springbootはEasyExcelとスレッドプールを使用してExcelデータのマルチスレッドインポートを実現します

[25] springboot は、キャッシュの侵入を処理するために jedis および redisson Bloom フィルターを統合します

[26] springboot はマルチスレッド トランザクション処理を実装します_springboot マルチスレッド トランザクション

[27] springbootはthreadLocal+パラメータパーサーを通じて現在のログイン情報をセッションと同様に保存する機能を実現します


        会社の開発中に、Excel ファイルをインポートするという非常に一般的なインポート機能の要件に遭遇したため、顧客から大量のインポートをサポートする必要があるという要望を受け、Alibaba のEasyExcelという便利なツールを思いつきました。データベースへのインポート操作をスレッドプールを使用してマルチスレッド化することを考えました。したがって、この章ではこの操作を記録します。

QQ 交換グループ ナビゲーション ——> 231378628

        まず、全体的なおおよそのプロセスは次のようになります。

34cc7eb9e0db4a23b467436114ef46d8.png

効果:

bcb80b85bff7401eb0e44e8c0b3925d2.png

7c9eab447858456b8048c675428d2dcf.png

13ba40214d094da5821ca2a2364e9229.png


実際のプロジェクトは、同社がパッケージ化した RPC フレームワークであり、このデモは、 mybatis-plus        を統合する以前のデモを使用して直接作成されています。

        まずディレクトリ構造を見てください。

1b7fa035b0d04f50bce78e6e27225e8d.png

        図中の枠で囲んだ部分がこの章で修正新規作成する必要のあるファイルであり、後で一つずつ解釈していきますが、この図中のクラス名をマークする場合は以下の記述が使用できます。

        次に、この章で行う必要がある準備作業を紹介します。

  • データベーステーブル
  • アプリケーション構成ファイルを変更し、Tomcat の最大ファイルアップロード制限を変更します (そうしないと Excel ファイルが大きすぎるため、アップロードでエラーが報告されます)
  • mybatis-plus のバッチ挿入機能を有効にします。mybatis-plus には、デフォルトで insert という単一の挿入機能しかありません (独自のプロジェクトがこれを使用しない場合は、必要ありません。これは、バッチ挿入メソッドがないだけです)私のデモで)
  • Excelのマルチスレッドインポートインターフェースに必要な各種クラスを作成する

目次

1. データベースとExcelファイルを準備する

2. 必要な依存関係を導入する

3. 構成ファイルを変更し、デフォルトのファイル サイズ制限を変更します。

4.mybatis-plusの一括保存機能を開く

5. 必要なツールクラスを作成する

6. ビジネスの各層にコードを作成する

7. easyExcel イベントリスナーを作成する

8. カスタム スレッド クラスを作成します

9、シングルスレッド処理とマルチスレッド処理の効率をテストする


1. データベースとExcelファイルを準備する

CREATE TABLE `deadman` (
  `uid` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '主键',
  `idCard` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '身份证号',
  `userName` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '死者姓名',
  `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '死者性别',
  `age` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '死者年龄',
  `reason` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '死因',
  `house` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '安排地狱层数',
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;

5449633b604548adb4549857dc1bbb11.png

a6336d9ee76f4d55be580182117ef7aa.png


2. 必要な依存関係を導入する

        easyExcel のインポートに関係する主な依存関係は次のとおりです。

a53da7f8bc5c4756a79ff7df845b3692.png


3. 構成ファイルを変更し、デフォルトのファイル サイズ制限を変更します。

        これを変更する必要があります。変更しないと、後続のインターフェイスが入力できなくなります。デフォルトの Tomcat サーバーは、アップロードされるファイルのサイズを制限します。

スプリング:
  サーブレット:
    マルチパート:
      最大ファイルサイズ: 100MB
      最大リクエストサイズ: 100MB
サーバー: 
  tomcat:
    最大スワローサイズ: 100MB

4.mybatis-plusの一括保存機能を開く

        このデモに統合されている rpc フレームワークは Mybatis-plus なので、次のようにバッチ保存を実現する方法を見つけました。

1. 新しい SpiceSqlInjector クラスを作成します

ab951363527446bc8ca94c4c8cc3e816.png

PS: クラス名のボックス選択部分に注意してください。

2. SpiceBaseMapperインターフェースクラスを作成します。

4520d0f72e1d479eb73fcb13f31ba43e.png

PS: 本来、ビジネスのインターフェイス層は BaseMapper を継承しますが、ここでは BaseMapper を継承し、上図に示すようにメソッドを追加します。名前はこれでなければならないことに注意してください。そうしないと、後でこのメソッドを呼び出すときにエラーが報告されます。 。

3. ビジネスに必要なマッパー層を作成する

26dfc9a9780e49f0beef6d79552b17f0.png

カスタマイズしたインターフェイス クラスを継承します。

このことから、DeadManMapperをインジェクションして上記メソッドを呼び出すことで一括挿入が実現できます。

次のように:

e25b87b64dc34bf5989d7ed358c24e7f.png


5. 必要なツールクラスを作成する

        EasyExcel を介してインポートする場合、入力パラメーターを満たさないいくつかのデータ型が含まれます。このデモには次のツール クラスが含まれます。

1、MultipartFileToFileUtils

        受信した MultipartFile タイプを File タイプに変換すると、コントローラーは MultipartFile タイプを受け取り、EasyExcel.read メソッドにはその File タイプが必要になります。

328b218fac654016b26bea8cc85bea59.png

2、SpringJobBeanFactory

        リスナー クラスがマップに挿入されると、null ポインターが報告され、次のツール クラスを使用して ApplicationContextAware を継承し、Bean オブジェクトを取得します。

5331c336ca794d11a20893c3ea2cad44.png


6. ビジネスの各層にコードを作成する

1. コントローラー層

5cc57717177c4ba591da40dff13f2b89.png

2. データベースのエンティティクラスのマッピング

41e177686af84d949d72f64066f9254d.png

        mybatis-plusに関するコメントは前回の記事をご覧ください。 

3. easyExcelのエンティティクラス

d7a7fdd6a0f94d51a4362943c9f9a146.png

        インデックスは、Excel シートの上の行番号を指します。たとえば、

f3142fff64f14c3bb068db491dcb982f.png

4. サービス層

87a1ae11359f45b4a2b6f84b2441e7b5.png

5. サービスの実装クラス層

ab55f46c075945edb4c0392225184873.png

        上記のメソッドはマルチスレッド イベント リスナーであり、次のメソッドはシングルスレッド イベント リスナーであり、2 つのメソッドを比較します。 


7. easyExcel イベントリスナーを作成する

1. シングルスレッドのイベントリスナー

eb0563f8dc6c4b0b87f5b9900bb1524c.png

        分析: リスナーは AnalysisEventListener クラスを継承し、ジェネリック型は上記 easyExcel で指定したエンティティ クラスのオブジェクト クラスとして指定されます。このクラスの 2 つのメソッド (invoke および doAfterAllAnalysed) をオーバーライドします。 

invoke(): このメソッドは Excel シートの 2 行目からデータの読み取りを開始します。

doAfterAllAnalysed(): このメソッドは、invoke がすべての Excel データを分析した後に実行されるため、このクラスにデータを格納するだけで十分です。

        この時点で、シングルスレッドのインポートは完了しました。最後に、2 つのリスナーの効率を比較してテストし、マルチスレッドのイベント リスナーを作成します。 

2. マルチスレッドイベントリスナー

81f5004243134ddb844b91fc1cc8fcf5.png

        分析: 上記の 2 つのメソッドを書き直すことでもあります。invoke メソッドの処理はそのままで、doAfterAllAnalysed メソッドの処理が変更され、作成されたスレッドタスクがスレッド プールの作成メソッドを通じてスレッド プールに投入され、スレッド プールが実行できるようになります。マルチスレッドタスク実行により、マルチスレッド実行インポート操作を実現します。

プロセス: スレッド プールを作成します——「各スレッドが処理する必要があるデータを計算します——」CountDownLatch オブジェクトを作成します (各スレッドが最後にメイン スレッドに戻るようにするため)——「スレッドの数を循環させ、スレッド タスクをスレッド プールに送信します—「CountDownLatch オブジェクトの await メソッドを実行します。これにより、現在のスレッドは待機状態になり、CountDownLatch が 1 に減らされた後に現在のスレッドが起動されます—」各スレッドは、そのスレッドを処理します。独自のデータを取得し、処理後にCountDownLatchオブジェクトのcountDownメソッドを実行することで、CountDownLatchオブジェクトの値から1を引いた値――「CountDownLatchの値が0の場合(スレッドプールクラスのスレッドタスクと実行が完了したことを示す)」 、メインスレッドのコードを実行します—「スレッドプールを閉じます」

cc0635be4ccd458cae9d00bc2a8f5404.png


8. カスタム スレッド クラスを作成します

        このステップでは、上で説明したスレッド化されたタスク クラスを作成します。

dea0cbadd1a543329fa2c75d443e87ed.png

        Callable または Runable を実装するか、Thread を継承します。ここでは Runable を実装し、run メソッドを書き換えます。

        割り当てられた受信データ間隔に応じて、subListメソッドでその間隔内のデータを取り出した後、上記で実装した一括挿入メソッドを実行してデータを格納します。coutDown メソッドが実行されないことによるコードの問題を防ぐために、このコードをfinallyに記述します。

PS: CountDownLatch の 2 つのメソッド (countDown、await) は、各スレッドのコードが実行されるときにメイン スレッドが待機状態に入り、各スレッド タスクの実行後にメイン スレッドに戻って実行されるようにするために一緒に使用されます。


9、シングルスレッド処理とマルチスレッド処理の効率をテストする

        シングルスレッドとマルチスレッドのイベント リスナーの準備は上記で完了しました。以下では 2 つの効率をテストします。

1. シングルスレッドのイベントリスナーを使用する

d146d90712f345f4b82c2ec8ef9564af.png

40dc9b181abe4e1d8e8b9ab0389966f4.png

84069e3a0f994a2b80fc63688f0b6118.png

c3c6ff95f3bc48b78036e08fe8ad35b0.png

a8ecd2e1f3f449689d7d4ef08ae6b9e9.png​  

acd43a125b7343618a4ef399abd9dc31.png

        結果: 100033 個のデータ、データは正しいです。 

2. マルチスレッドのイベントリスナーを使用する

7be678b60b9f419e951318d446c54514.png

1070455afae046dbac229c7f78c77fed.png

d2620d7b776f410e9b5b9409b5641851.png

        結果: 100033 個のデータ、データは正しく、確かにはるかに高速です。


        単純なマルチスレッドのビジネスシナリオであれば、このデモを使用して修正できると思います。問題がある場合は、ご指摘いただきありがとうございます。レスビー。

QQ 交換グループ ナビゲーション ——> 231378628

おすすめ

転載: blog.csdn.net/weixin_56995925/article/details/125944749
おすすめ