English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

mybatisの一对一查询機能

一对一クエリとは、特定のテーブルのデータをクエリする際に、他のテーブルのデータを関連クエリすることを意味します。

 要件

    まず、一对一クエリを使用する小さな要件について説明しましょう:例えば、特定の注文の情報をクエリする際に、この注文を作成したユーザーの情報を関連クエリする必要がある場合、テーブルモデルは以下のようです(

 ResultType

  sql文の書き方

    まず、私たちの要件を分析する必要があります。1この要件を満たすために、どのテーブルが関与し、どちらが主テーブル、どちらが関連テーブルであるかを決定する必要があります。具体的にはどう決定するかは、要件に依存します——私たちの要件は、注文をクエリする際に、この注文を作成したユーザーを同時にクエリすることです。これは明らかです。私たちの主テーブルは注文テーブル(orders)であり、関連テーブルはユーザーテーブル(user)です。

    この時点で、以下のようなSQLクエリを書くことができます:

select * from orders

    この時点で、私たちはこの問題に注意を払うべきです:関連クエリの際に内結合を使用するべきか、外結合を使用するべきか、内結合と外結合の違いがわからない人にとっては、ここで簡単に説明し、以降に時間があるときには詳細なブログを書きます:内結合は条件を満たすものだけを表示します。外結合は左外結合と右外結合に分けられます:左結合は左側のすべてを表示し、右側と左側が同じものを追加します;右結合は右側のすべてを表示し、左側と右側が同じものを表示します。

  私たちの要件は、注文を通じてユーザーに関連させることです。ordersテーブルには外キー(userId)があります。userIdを通じて関連テーブルuserテーブルのデータをクエリする際には、userIdはuserテーブルの主キーです。この時点では、1つのuser情報しか取得できませんが、このレコードは主クエリ結果に影響を与えません。したがって、私たちは内結合クエリを選択します。この時点で、私たちのSQLクエリは以下のようになります:

 select * from orders, user where orders.user_id = user.id

    クエリが完了すると、以下のような結果が得られます:

    ここで問題が発生しました。私たちは、この時点で2つのIDが出现し、これによりデータがオブジェクトにエンキャップされる際に問題が発生するようになりました。また、User_idカラムは私たちのユーザIDデータと重複しています。私たちはSQLを改造する必要があります。どう改造するのでしょうか?

    私たちのメインテーブルデータはすべてのデータをクエリする必要がありますが、ユーザーテーブルはusername、sex、adressの3つの情報だけが必要です(ここでは仮定していますので、必要な情報が何か気にする必要はありません)。したがって、私たちは手動でSQLクエリのフィールドを指定する必要があります:    

SELECT 
 orders.*,
 USER.username,
 USER.sex,
 USER.address 
FROM
 orders,
 USER 
WHERE orders.user_id = user.id

    これらはSQLリンクツールでクエリを行う場合ですが、必要なデータベースが表示できるようになると、SQL文が確定します。この時点で次のステップに進みます:

   pojoの作成

    mybatisフレームワークを使用して、検索した結果を対応するオブジェクトにデータをエンブレムする必要があります。問題は、この検索したデータを誰が受け取るかです。上記のSQLクエリの結果をpojoにマッピングする場合、pojoにはすべての検索列名を含む必要があります。しかし、元のOrdersクラスやUserクラスではすべてのフィールドをマッピングすることができません。この場合、簡単な解決策があります:返されるフィールドに基づいて特別なクラスを作成し、このクラスが返される結果セットを受け取るようにします。

    この場合、新しいpojoにはすべてのフィールドを書かなくても大丈夫です。新しいpojoは結果セットの検索フィールドが多いクラスを継承し、他の必要なデータをこのサブクラスに書くだけで十分です。

    pojoの作成が完了したら、規格に従ってマッピングファイルを作成し、対応するインターフェースのメソッドを記述する必要があります:

    mapper.xml

    mapper.javaのインターフェース:

 ResultMap

    SQL文では、resultTypeとresuleMapの実現方法が同じですので、ここでは飛ばします。

  resultMapを使用するマッピングの考え方

    pojoを使用する場合、データをpojoのオブジェクト属性にエンブレムすることができます。この属性はシンプルなデータ型または別のpojoであれば何でもかまいません。この場合、以下のようにすることができます:

    resultMapを使用してクエリ結果の注文情報をOrdersオブジェクトにマッピングし、ordersクラスにUser属性を追加し、関連クエリから得られたユーザー情報をordersオブジェクトのuser属性にマッピングします。

    Ordersクラスにuser属性を追加

  mapper.xml

    resultMapの方法を使って結果セットをマッピングする際には、2つの操作を行う必要があります。1つはresultMapの定義で、検索された結果セットの各列に対応するオブジェクトの属性を設定します。これは少し面倒ですが難しくありません。もう1つはstatementの定義です。

   resultMap

    resultMap实现的基本思路我们刚才已经说了。而且也在orders的pojo类中增加了相应的属性了。接下啦,就是写一个resultMap,将整个查询的结果映射到Orders中在这里面,首先是order订单的映射。就是直接用id 和result标签将两者相互对应即可。然后就是,关联的用户信息的映射,这时候需要用到一个association的标签,将在orders类中的user字段与User类进行映射,然后在其内部还是用id和result标签,将查询的数据和User的属性相映射。

    具体代码如下:   

<!-- 订单查询关联用户的resultMap
 将整个查询的结果映射到cn.mybatis.po.Orders中
  -->
 <resultMap type="cn.mybatis.po.Orders" id="OrdersUserResultMap">
  <!-- 配置映射的订单信息 -->
  <!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
   column:订单信息的唯 一标识 列
   property:订单信息的唯 一标识 列所映射到Orders中哪个属性
   -->
  <id column="id" property="id"/>
  <result column="user_id" property="userId"/>
  <result column="number" property="number"/>
  <result column="createtime" property="createtime"/>
  <result column="note" property=note/>
  <!-- 配置映射的关联的用户信息 -->
  <!-- association:用于映射关联查询单个对象的信息
  property:要将关联查询的用户信息映射到Orders中哪个属性
   -->
  <association property="user" javaType="cn.mybatis.po.User">
   <!-- id:关联查询用户的唯 一标识
   column:指定唯 一标识用户信息的列
   javaType:映射到user的哪个属性
    -->
   <id column="user_id" property="id"/>
   <result column="username" property="username"}/>
   <result column="sex" property="sex"/>
   <result column="address" property="address"/>
  </association>
 </resultMap>

   statement

    statementは比較的シンプルで、結果セットのマッピング方法をresultMapに変更し、返却タイプを先ほど作成したresultMapに設定します。

  mapper.java    

 両者の違い

    一对一検索の実現方法について説明した後、それぞれの違いや長所・短所について分析します。

    まず、pojoに対して修正が必要です。一つはpojoクラスを追加し、もう一つはpojoのフィールドを修正します。個人的には、デザインパターンの開放/閉鎖原則に基づいて、resultTypeはresultMapより良いと思います。

    次に、シンプルさの面では、resultTypeを使用する方が簡単です。この点で、resultTypeもresultMapより良いです。

    ただし、resultMapは遅延ロードを実現できますが、resultTypeは遅延ロードを実現できません。この点で、resultTypeはresultMapより劣ります。

    したがって、特定の検索結果の要件がない場合は、resultTypeを使用することをお勧めします。

以上は、編集者が皆さんに紹介したmybatisの一对一検索機能です。皆さんに役立つことを願っています。何か疑問があれば、コメントを残してください。編集者は迅速に回答します。このサイトへのサポートに感謝しています!

声明:この記事の内容はインターネットから取得され、著作権者に帰属します。インターネットユーザーが自発的に貢献し、アップロードしたものであり、このウェブサイトは所有権を持ちません。また、人工的な編集は行われていません。著作権侵害が疑われる内容がある場合は、メールで notice#w までご連絡ください。3codebox.com(メール送信時は、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認がとれると、このサイトは即座に侵害疑いのコンテンツを削除します。)

おすすめ