ORM とは何ですか? (推奨される学習: java インタビューの質問 )
オブジェクト リレーショナル マッピング (オブジェクト リレーショナル マッピング、略して ORM) は、オブジェクト指向の問題を解決するために使用されるリレーショナル モデルです。プログラムとデータベースのモデル 不一致問題に対するテクノロジー;
簡単に言うと、ORM は、オブジェクトとデータベース (Java では XML または注釈を使用できます) の間のマッピングを記述するメタデータを使用して、プログラム内のオブジェクトを自動的に永続化します。リレーショナル データベースに変換するか、リレーショナル データベース テーブル内の行を Java オブジェクトに変換します。これは本質的にデータをある形式から別の形式に変換することです。
Hibernate の SessionFactory はスレッドセーフですか?セッションはスレッドセーフですか (2 つのスレッドが同じセッションを共有できますか)?
SessionFactory は Hibernate のデータ ストレージ概念に対応しており、スレッドセーフであり、複数のスレッドから同時にアクセスできます。通常、SessionFactory は起動時にのみ構築されます。アプリケーションの場合、簡単にアクセスできるように、シングルトン モードで SessionFactory をカプセル化するのが最善です。
Session は軽量の非スレッドセーフ オブジェクト (セッションはスレッド間で共有できません) であり、データベースと対話する作業単位を表します。セッションは SessionFactory によって作成され、タスクが完了すると閉じられます。セッションは、永続化レイヤー サービスによって提供されるメイン インターフェイスです。
セッションにより、データベース接続の取得が遅れます (つまり、必要な場合にのみ接続が取得されます)。作成されるセッションが多すぎることを避けるために、ThreadLocal を使用してセッションを現在のスレッドにバインドし、同じスレッドが常に同じセッションを取得できるようにします。
Hibernate 3 の SessionFactory の getCurrentSession() メソッドでこれを行うことができます。
Session の save()、update()、merge()、lock()、saveOrUpdate()、persist() メソッドは何をしますか?違いは何ですか?
Hibernate オブジェクトには、一時的、永続的、切り離されたという 3 つの状態があります。
一時的なインスタンスは、save()、persist()、または saveOrUpdate() メソッドを呼び出すことで永続化できます。
無料インスタンスは、update()、saveOrUpdate()、lock を呼び出すことで永続化できます。 () または replicate() は永続的になります。 save() とpersist() は SQL INSERT ステートメントをトリガーし、update() または merge() は UPDATE ステートメントをトリガーします。
save() と update() の違いは、一方は一時オブジェクトを永続状態に変換し、他方は自由オブジェクトを永続状態に変換することです。 merge() メソッドは、save() メソッドと update() メソッドの機能を完了できます。その目的は、新しい状態を既存の永続オブジェクトにマージするか、新しい永続オブジェクトを作成することです。
persist() メソッドについては、公式ドキュメントの指示に従ってください:
1.persist() メソッドは一時的なインスタンスを永続化しますが、識別は保証されません識別子はすぐに永続インスタンスに入力され、識別子の入力はフラッシュ時間まで遅れる場合があります;
2.persist() メソッドは、呼び出されたときにトリガーされないことを保証します。トランザクションの外部。INSERT ステートメントが長いセッション プロセスをカプセル化する必要がある場合、persist() メソッドが必要です。
3. save() メソッドは項目 2 を保証しません。識別子を返す必要があるため、 INSERT ステートメントは、トランザクションの内部または外部に関係なく、すぐに実行されます。
lock() メソッドと update() メソッドの違いについては、update() メソッドはデタッチ状態で変更されたオブジェクトを永続状態に変更し、lock() メソッドは変更します。変更されていないオブジェクト 切り離された状態のオブジェクトは永続的な状態になります。
セッションごとにエンティティ オブジェクトを読み込むプロセスについて説明します。
1. データベース クエリ関数を呼び出す前に、Session は最初に 1 次キャッシュ内のエンティティ タイプと主キーを検索します。1 次キャッシュの検索がヒットし、データ ステータスが正当であれば、
2. 1 次キャッシュにヒットがない場合、セッションは現在の NonExists レコード (クエリ ブラックリストに相当します。無効なクエリが繰り返された場合は、判定が行われます) を検索します。パフォーマンスを向上させるためにすばやく作成できます)。NonExists に同じクエリ条件が存在する場合、null が返されます。
3. 1 次キャッシュのクエリが失敗した場合は、2 次キャッシュをクエリします。 -レベル キャッシュ ヒット、直接返す;
4. If before どのクエリもヒットしなかった場合、SQL ステートメントが発行されます。対応するレコードがクエリ内に見つからない場合、クエリは追加されます。記録するセッションのNonExists、nullが返される;
5. マッピング設定とSQL文のResultSetに従って取得し、対応するエンティティオブジェクトを作成する;
6. 組み込みオブジェクトをセッションの管理 (レベル 1 キャッシュ) に追加します;
7. 対応するインターセプターがある場合は、インターセプター メソッドの onLoad を実行します;
8. 有効になっていて設定されている場合2 次キャッシュを使用するには、データ オブジェクトが 2 次キャッシュに含まれます;
9. データ オブジェクトを返します。
# 受信データを文字列として扱い、自動的に受信データに引用符を追加します;
$ は、入力されたデータを直接SQLで表示および生成されます。
注: $ プレースホルダーを使用すると、SQL インジェクション攻撃につながる可能性があります。# が使用できる場所には $ を使用しないでください。order by 句を記述するときは、# の代わりに $ を使用する必要があります。
MyBatis における名前空間の役割を説明します。
大規模なプロジェクトでは、多数の SQL ステートメントが存在する可能性がありますが、現時点では、各 SQL ステートメントに一意の識別 (ID) を与えるのは簡単ではありません。
この問題を解決するために、MyBatis では、マッピング ファイルごとに一意のネームスペースを作成し、このマッピング ファイルで定義された各 SQL ステートメントがこのネームスペースで定義されるようにすることができます。
この ID が各ネームスペースで一意であることが保証できれば、たとえ異なるマッピング ファイル内のステートメント ID が同じであっても、競合は発生しなくなります。
MyBatis の動的 SQL とはどういう意味ですか?
一部の複雑なクエリでは、複数のクエリ条件を指定することがありますが、これらの条件は存在する場合と存在しない場合があります。永続層フレームワークを使用しない場合は、SQL ステートメントを自分で組み立てる必要がある場合があります。しかし、MyBatis はこの問題を解決するために動的 SQL 機能を提供します。 MyBatis で動的 SQL を実装するために使用される要素は主に次のとおりです:
- if - choose / when / otherwise - trim - where - set - foreach
使用例:
<select id="foo" parameterType="Blog" resultType="Blog"> select * from t_blog where 1 = 1 <if test="title != null"> and title = #{title} </if> <if test="content != null"> and content = #{content} </if> <if test="owner != null"> and owner = #{owner} </if> </select>
JDBC プログラミングの欠点と MyBatis がそれらをどのように解決するかこういった質問は?
1. JDBC: データベース リンクの頻繁な作成と解放は、システム リソースの無駄を引き起こし、システム パフォーマンスに影響を与えますが、この問題はデータベース接続プールを使用することで解決できます。
MyBatis: SqlMapConfig.xml でデータ リンク プールを構成し、接続プールを使用してデータベース リンクを管理します。
2. JDBC: SQL ステートメントはコード内に記述されるため、コードの保守が困難になります。SQL の実際のアプリケーションは大幅に変更される可能性があり、SQL の変更には Java コードの変更が必要です。
MyBatis: XXXXmapper.xml ファイルで SQL ステートメントを構成し、Java コードから分離します。
3. JDBC: SQL ステートメントの where 条件は必ずしも確実ではなく、多かれ少なかれ一定である可能性があり、プレースホルダーはパラメーターに対応する必要があるため、SQL ステートメントにパラメーターを渡すのは面倒です。 1対1。
MyBatis: Mybatis は Java オブジェクトを SQL ステートメントに自動的にマップします。
4, JDBC: 結果セットを解析するのは面倒です。SQL の変更により解析コードも変更されるため、解析する前にコードを走査する必要があります。データベース レコードを pojo に解析すると便利です。オブジェクト。
MyBatis: Mybatis は SQL 実行結果を Java オブジェクトに自動的にマップします。
MyBatis と Hibernate の違いは何ですか?
1. Mybatis は Hibernate とは異なります。MyBatis はプログラマ自身が SQL ステートメントを記述する必要があるため、完全な ORM フレームワークではありません。ただし、mybatis は、XML またはアノテーションを通じて SQL ステートメントを実行するように柔軟に設定できます。そして、Java オブジェクトと SQL ステートメントをマップして最終的に実行される SQL を生成し、最後に SQL の実行結果をマップして Java オブジェクトを生成します。
2. Mybatis は学習閾値が低く習得が容易であり、プログラマーが独自の SQL を直接記述することができるため、SQL の実行パフォーマンスを厳密に制御することができ、柔軟性が高く、必要なソフトウェア開発に非常に適しています。インターネットなどのリレーショナル データ モデルに対する高い要件 ソフトウェア、エンタープライズ オペレーション ソフトウェアなど この種のソフトウェアのニーズは頻繁に変化するため、ニーズが変化したら結果を迅速に出力する必要があります。
ただし、柔軟性の前提として、mybatis はデータベースに依存できないということです。複数のデータベースをサポートするソフトウェアを実装する必要がある場合は、複数の SQL マッピング ファイルのセットをカスタマイズする必要があり、これは大きな作業負荷になります。
3. Hibernate には、強力なオブジェクト/リレーショナル マッピング機能と優れたデータベース独立性があります。リレーショナル モデルに対する要件が高いソフトウェア (要件が固定されたカスタマイズされたソフトウェアなど) の場合、Hibernate を使用して開発すると、コストを節約できます。多くのコードを作成し、効率を向上させます。
ただし、Hibernate の欠点は、学習の閾値が高く、習得の閾値がさらに高いことです。さらに、O/R マッピングの設計方法、パフォーマンスとオブジェクト モデルのトレードオフの方法、およびHibernate をうまく使用するには、豊富な経験と能力が必要です。
要するに、限られたリソース環境でユーザーのニーズに合わせて保守性と拡張性の良いソフトウェアアーキテクチャを作ることができれば、それは良いアーキテクチャなのであり、最良のフレームワークはそれだけです。適切な。
(ここでは、自分の理解と組み合わせても構いません。遠慮しないでください)
MyBatis の一次キャッシュと二次キャッシュについて簡単に説明してください。
Mybatis は、まずキャッシュ内の結果セットをクエリします。結果セットがない場合は、データベースにクエリします。存在する場合は、キャッシュから結果セットを取得し、データベースにアクセスせずに返します。データベース。 Mybatis の内部ストレージ キャッシュは HashMap を使用し、キーは hashCode sqlId SQL ステートメントです。 value はクエリからのマッピングによって生成された Java オブジェクトです。
Mybatis の 2 次キャッシュはクエリ キャッシュです。そのスコープはマッパーの名前空間です。つまり、同じ名前空間で SQL をクエリすると、次のクエリからデータを取得できます。キャッシュ。 2 次キャッシュは SqlSession にまたがることができます。
以上がJava 永続層の面接での質問の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。