第1レベルのキャッシュとは何ですか
MyBatisには非常に強力なクエリキャッシュ機能が含まれており、非常に簡単に構成およびカスタマイズできます。MyBatis 3のキャッシュ実装に多くの改善が実装され、より強力で簡単に構成できるようになりました。Mybatisは、デフォルトで第1レベルのキャッシュ(ローカルセッションキャッシュ)のみをオンにします。
まず、クエリキャッシュとは何かを知る必要がありますか?クエリキャッシュの役割は何ですか?
機能:Mybatisは、データの負荷を軽減し、データベースのパフォーマンスを向上させるためのクエリキャッシュを提供します。
次の図に示すように、各セッションには、部分的な独自のキャッシュがあります。これは、いわゆる第1レベルのキャッシュです。
どのような状況で第1レベルのキャッシュにヒットしますか
- 同じsqlとパラメーター
- セッションに参加している必要があります
- 同じ方法で実行する必要があります
- 同じ名前名である必要があります(同じ名前名->同じマッパーファイル)
- クエリの前にclearCacheを実行できません
- 中級者は更新、削除、挿入を実行できません(SqlSessionではすべてのデータが空になります)
Mybatisのキャッシングメカニズムの詳細な説明
第1レベルのキャッシュは、SqlSessionレベルのキャッシュです。データベースを操作するときにsqlSessionオブジェクトを構築する必要があり、キャッシュされたデータを格納するためのデータ構造(HashMap)がsqlSessionオブジェクトにあることは誰もが知っています。
以下に示すように:
Mybatisのキャッシングメカニズムの詳細な説明
この図から、第1レベルのキャッシュ領域がSqlSessionに従って分割されていることがわかります。各クエリは最初にキャッシュ領域を検索し、データが見つからない場合はデータベースからデータをクエリしてから、クエリされたデータを第1レベルのキャッシュに書き込みます。Mybatis内部ストレージキャッシュはHashMapオブジェクトを使用し、キーはhashCode + sqlId + sqlステートメントです。値の値は、クエリマッピングから生成されたjavaオブジェクトです。ダーティリードを回避するためにキャッシュ内のデータが確実に正確なデータであることを保証するために、データを変更する(追加、削除、および変更操作)たびに、コミット操作を実行してキャッシュ領域をクリアします。
SqlSessionとExecutorはどちらもインターフェイスであり、実装はDefaultSqlSessionとCacheExecutorです。
- クライアントはテストメソッドTest1と同等です
- User @ Proxy動的プロキシ(疑似皇帝に相当し、転送を担当するだけです)==コード内のUserMapper(プロキシオブジェクト)は実際には役に立ちません
- Executorインターフェースは、用事を実行してデータベース内のデータを取得するためのものです
- SqlSessionはインターフェースです
- 第1レベルのキャッシュは、CacheExecutorを介して実装されます
基礎となる実装の詳細な説明!!
selectByIdメソッドにブレークポイントを入力し、基礎となる実装クラスPrepetualCacheにgetObject(オブジェクトキー)を入力します。これ
は、デバッグスタック情報を確認することで確認できます。
- 上の図の緑色のボックスは、動的エージェントの実装です。意味がありません。これは単なる転送であるため、この部分は無視してください。
- 次に、selectOneにクエリを実行しますが、SelectListにクエリを実行してから、DefaultSqlSessionを介して変換します。
キャッシュに本当に関連しているのは、これらの行の実装です
プロセスは次のとおりです
このステップ:
- キャッシュキーに見られるように、メソッドと名前名およびセッションが含まれているため、これらはキャッシュヒットと同じように実行する必要があります。
- キャッシュの一意のキーをカプセル化します
- DefaultSqlSessionにCacheExecutorがあります
- CacheExecutorにはSimpleexexutorがあります
- SimpleexexutorにはLocalCache(PerpetualCacheタイプ)と呼ばれるものがあります
- LocalCacheは、キャッシュを保存する実際の場所です
- LocalCacheにキャッシュがあります(ハッシュマップ<オブジェクト、オブジェクト>タイプ)
第1レベルのキャッシュを通過します!!!
第1レベルのキャッシュのPUTプロセス
最初のいくつかのプロセスは上の図と同じです。
キャッシュのライフサイクルはSqlSessionと同じです。
データの不整合はありますか?
データベース自体にトランザクション分離レベルがあり、デフォルトが繰り返し読み取りであるためではありません。つまり、データベース内の任意のトランザクションによって読み取られるデータは一貫しているため、データの不整合の問題はありません。
Mybatisセカンダリキャッシュ
第2レベルのキャッシュ使用条件は、名前名注釈
putを使用して構成する必要があります。第2レベルのキャッシュの場合、このセッションを閉じて配置する必要があります(クロストランザクション読み取りを行わないと、ダーティ読み取りの問題が発生するため)
どのような状況で第1レベルのキャッシュにヒットしますか
- 同じsqlとパラメーター
- セッションに参加している必要があります
- 同じ方法で実行する必要があります
- 同じ名前名である必要があります(同じ名前名->同じマッパーファイル)
- クエリの前にclearCacheを実行できません
- 中級者は更新、削除、挿入を実行できません(SqlSessionではすべてのデータが空になります)
- 条件セカンダリキャッシュを構成する必要がありますCachenamespaceアノテーション
- 第2レベルのキャッシュを配置する場合、このセッションを閉じて配置する必要があります(クロストランザクション読み取りを行わないと、ダーティ読み取りの問題が発生するため)
2番目のレベルのキャッシュはマッパーレベルのキャッシュです。複数のSqlSessionが同じマッパーのSQLステートメントで動作します。複数のSqlSessionが2番目のレベルのキャッシュを共有できます。2番目のレベルのキャッシュはSqlSessionにまたがることができます。
図:
Mybatisのキャッシングメカニズムの詳細な説明
第2レベルのキャッシュ領域は、マッパーの名前に応じて分割されます。**同じ名前のマッパークエリデータは同じ領域に配置されます。**マッパープロキシ方式を使用する場合、各マッパーの名前は異なり、第2レベルのキャッシュ領域として理解できます。マッパー、つまり名前名に従って分割されます。2つのマッパーファイルの名前名が同じである場合、異なるSqlSessionsがマッパーキャッシュを共有できます。
図:
Mybatisのキャッシングメカニズムの詳細な説明
デフォルトでは、ローカルセッションキャッシュを除いて、第2レベルのキャッシュは有効になっていません。第1レベルのキャッシュでは、異なるSqlSession間の第1レベルのキャッシュが共有されないことも導入しました。したがって、2つのSqlSessionを使用して同じデータをクエリすると、両方がSQLをデータベースに送信します。
第2レベルのキャッシュをオンにすると、SqlSession間のデータを第2レベルのキャッシュで共有できます。第1レベルのキャッシュと同様に、第2レベルのキャッシュ領域は、挿入、更新、削除などの操作が実行され、コミットが送信された後にクリアされます。第1レベルのキャッシュと第2レベルのキャッシュが同時に存在する場合、第2レベルのキャッシュが最初にアクセスされ、次にそれぞれの第1レベルのキャッシュがアクセスされます。必要なデータがない場合、SQLはクエリのためにデータベースに送信されます。