開発効率を向上させるために必要なスキル: Mybatis リレーションシップ マッピングの深い理解

目次

導入

1. リレーショナルマッピングの概要

2. resultType と resultMap の違い

3 つの 1 対 1 の関係クエリ

3.1. ネストされた結果セットの書き込み

3.2. ケーステスト

4. 1 対多の関係クエリ

4.1. ネストされた結果セットの書き込み

4.2. ケーステスト

5. 多対多の関係クエリ

5.1. ネストされた結果セットの書き込み

5.1. ケーステスト

6. まとめ


導入

実際の開発では、データベースの操作には複数のテーブルが関与することが多いですが、MyBatis では複数のテーブル間の操作に対して、テーブルとオブジェクト、オブジェクトとオブジェクトの関連付けをうまく扱える関連付けマッピングを提供しています。リレーショナル データベースには、テーブル間の関連付けマッピング関係として、1 対 1 関係、1 対多関係、および多対多関係の 3 種類があります。

1. リレーショナルマッピングの概要

MyBatis では、オブジェクト間の関連付け関係は、データ テーブル間の関係を維持するための一連の属性を提供する association 要素を通じて処理されます。association 要素は resultMap 要素のサブ要素であり、ネストされたクエリモードとネストされた結果セット モードという 2 つの構成モードがあります。

属性 説明する
カラム エンティティ クラスの属性名に対応するデータベースの列名を表します。
財産 データベースの列名に対応する、エンティティ クラスの属性名を示します。
コレクション エンティティクラスのListやSetなどのコレクション型に対応するコレクション型を表します。
タイプの コレクション内の要素のタイプを示します。コレクション内の要素のタイプを指定するために使用されます。
協会 エンティティ クラスの属性とデータベース テーブルの列に対応する 1 対 1 の関係を表します。
javaタイプ Java のデータ型を表します。コレクション内の要素の型を指定するために使用されます。

2. resultType と resultMap の違い

ここでは、プロジェクト開発時にネストされた結果セットの形でコードを記述するシナリオを想定しており、resultType(resultType="com.csdn.xw.model.Book")を使用します。本の名前と本の価格を調べます。要求を書いた後、顧客は再度要求を変更します。便宜上、resultType="java.util.Map" と書きます。このとき、顧客がいつ要求したかは関係ありません。それが必要な場合、コードの文字列は変更されません。時代は変わり、あなたは元の会社を辞め、後から来た開発者は、あなたが書いたコード、あなたが受け取ったフィールドは何か、それが本の名前なのか、本のタイトルなのか、そしてその価格なのかを知りません。本など。これが欠点です。

上記の話を要約しましょう。

resultType を使用して、クエリ結果のタイプ (ここでは「com.csdn.xw.model.Book」) を直接指定します。これは通常、単純なクエリ ステートメントに使用され、複雑なマッピング関係は必要ありません。利点はシンプルで直感的であることですが、欠点は複雑なマッピング操作を実行できないことです (エンティティ クラスにはこの属性がありません)。

また、resultMap を使用すると、クエリ結果をあらゆるタイプの Java オブジェクトにより柔軟にマッピングできます。resultMap を定義することで、各クエリ結果列と Java オブジェクト プロパティ間のマッピング関係を指定できます。利点は、強力でさまざまな複雑なマッピング操作を実行できることですが、欠点は、より多くの XML 構成コードを記述する必要があることです。

以下は、テーブル間に 3 つの関連付けマッピング関係があることを示す、ネストされた結果セットです。

3 つの 1 対 1 の関係クエリ

ここで VO クラスを構築する必要があります VO は Value Object の略で、ビュー層とビジネスロジック層の間でデータを転送するために使用される軽量のデータ構造です。VO は通常、ビジネス ロジック層またはデータ アクセス層から取得されるビュー層で必要なデータを表すために使用されます。VO の主な目的は、ビジネス ロジック層のデータ構造をビュー層で使用できるデータ構造に変換することです。簡単に言えば、リレーショナル マッピングの結果受信に使用されます。

以下では、注文項目と注文を使用して 1 対 1 の関係を記述するため、OrderitemVo を作成します。

public class OrderitemVo extends Orderitem {
    private Order order;

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }

3.1. ネストされた結果セットの書き込み

<resultMap id="OrderitemvoMap" type="com.csdn.xw.vo.OrderitemVo">
    <result column="order_item_id" property="orderItemId"></result>
    <result column="product_id" property="productId"></result>
    <result column="quantity" property="quantity"></result>
    <result column="oid" property="oid"></result>
    <association property="order" javaType="com.csdn.xw.model.Order">
      <result column="order_id" property="orderId"></result>
      <result column="order_no" property="orderNo"></result>
    </association>
  </resultMap>

  <select id="selectByOiid" resultMap="OrderitemvoMap" parameterType="java.lang.Integer">
    select * from t_hibernate_order o,t_hibernate_order_item oi where o.order_id=oi.oid and oi.order_item_id=#{oiid}
  </select>

3.2. ケーステスト

ビズが書いた

public interface OrderitemBiz {
    OrderitemVo selectByOiid(Integer oiid);
}

書かれた命令

@Service
public class OrderitemImpl implements OrderitemBiz {
    @Autowired
    private OrderitemMapper OrderitemMapper;

    @Override
    public OrderitemVo selectByOiid(Integer oiid) {
        return OrderitemMapper.selectByOiid(oiid);
    }
}

テストテスト

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class OrderitemImplTest {
    @Autowired
    private OrderitemBiz OrderitemBiz;

    @Test
    public void selectByOiid() {
        OrderitemVo orderitemVo = OrderitemBiz.selectByOiid(27);
        System.out.println(orderitemVo);
        System.out.println(orderitemVo.getOrder());
    }
}

試験結果:

4. 1 対多の関係クエリ

以下では、注文と注文項目を使用して 1 対多の関係を記述するため、OrderVo を作成します。

public class OrderVo extends Order {
    private List<Orderitem> orderitems=new ArrayList<>();

    public List<Orderitem> getOrderitems() {
        return orderitems;
    }

    public void setOrderitems(List<Orderitem> orderitems) {
        this.orderitems = orderitems;
    }

    @Override
    public String toString() {
        return "OrderVo{" +
                "orderitems=" + orderitems +
                '}';
    }
}

4.1. ネストされた結果セットの書き込み

 <resultMap id="OrderMap" type="com.csdn.xw.vo.OrderVo" >
    <result column="order_id" property="orderId"></result>
    <result column="order_no" property="orderNo"></result>
    <collection property="orderitems" ofType="com.csdn.xw.model.Orderitem">
      <result column="order_item_id" property="orderItemId"></result>
      <result column="product_id" property="productId"></result>
      <result column="quantity" property="quantity"></result>
      <result column="oid" property="oid"></result>
    </collection>
  </resultMap>


  <select id="byOid" resultMap="OrderMap" parameterType="java.lang.Integer" >
    select * from t_hibernate_order o,t_hibernate_order_item oi where o.order_id=oi.oid
     and o.order_id=#{oid}
  </select>

4.2. ケーステスト

ビズが書いた

public interface OrderBiz {
    OrderVo byOid(Integer id);
}

書かれた命令

@Service
public class OrderBizImpl implements OrderBiz {
    @Autowired
    private OrderMapper orderMapper;
    @Override
    public OrderVo byOid(Integer id) {
        return orderMapper.byOid(id);
    }
}

テストライティング

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class OrderBizImplTest {
@Autowired
private OrderBiz orderBiz;
    @Test
    public void byOid() {
        OrderVo orderVo = orderBiz.byOid(7);
        System.out.println(orderVo);
        orderVo.getOrderitems().forEach(System.out::println);
    }
}

試験結果:

5. 多対多の関係クエリ

書籍と複数のカテゴリの関係、および各カテゴリと複数の書籍の関係を使用して、多対多の関係をクエリします。

Hブックヴォ

public class HbookVo  extends HBook {
    private List<HCategory> hcategory;

    public List<HCategory> getHcategory() {
        return hcategory;
    }

    public void setHcategory(List<HCategory> hcategory) {
        this.hcategory = hcategory;
    }
}

5.1. ネストされた結果セットの書き込み

<resultMap id="HbookVo" type="com.csdn.xw.vo.HbookVo" >
    <result column="book_id" property="bookId"></result>
    <result column="book_name" property="bookName"></result>
    <result column="price" property="price"></result>
    <collection property="hcategory" ofType="com.csdn.xw.model.HCategory">
      <result column="category_id" property="categoryId"></result>
      <result column="category_name" property="categoryName"></result>
    </collection>
  </resultMap>

  <select id="selectByBid" resultMap="HbookVo" parameterType="java.lang.Integer">
    SELECT
	*
FROM
	t_hibernate_book b,
	t_hibernate_book_category bc,
	t_hibernate_category c
WHERE
	b.book_id = bc.bid
	AND bc.cid = c.category_id
	AND b.book_id =#{bid}
  </select>

5.1. ケーステスト

ビズが書いた

public interface HBookBiz {
    HbookVo selectByBid(Integer bid);
}

書かれた命令

@Service
public class HBookBizImpl implements HBookBiz {
    @Autowired
    private HBookMapper hbookMapper;

    @Override
    public HbookVo selectByBid(Integer bid) {
        return hbookMapper.selectByBid(bid);
    }
}

テストライティング

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring-context.xml"})
public class HBookBizImplTest {
    @Autowired
    private HBookBiz hbookBiz;



    @Test
    public void selectByBid() {
        HbookVo hbookVo = hbookBiz.selectByBid(8);
        System.out.println(hbookVo);
        hbookVo.getHcategory().forEach(System.out::println);
    }
}

試験結果:

6. まとめ

resultMap と resultType の違いは、resultType が戻り値の型 (基本型、パッケージ化型) を直接表すのに対し、resultMap は外部 ResultMap への参照であることです。 

Vo と Dto は 2 つの異なるデータ転送オブジェクトです。Vo は主にディスプレイ層とビジネス層の間のデータ転送に使用され、Dto は主にリモート通話時の異なる層間のデータ転送に使用されます。 

ofType と javaType は両方とも、Java 型と JDBC 型の間で変換するための MyBatis の型プロセッサです。このうち、ofType はコレクション型を扱うために使用され、javaType は基本データ型と JDBC 型を扱うために使用されます。

使用シナリオ: クエリ結果がコレクション型の場合は ofType を使用でき、クエリ結果が基本データ型または JDBC 型の場合は javaType を使用できます。

私の共有はここで終わりです。議論やコミュニケーションのためにコメントエリアへようこそ!

役に立ったと思ったら、高評価をお願いします♥♥

おすすめ

転載: blog.csdn.net/weixin_74318097/article/details/132509509