これはmybatisシリーズの9番目の記事です。前の提案を読む前に、[Java Tsukuba Fox]パブリックアカウントにアクセスして前の記事を表示すると、理解と把握に便利です。前回の記事では、MyBatisの自動マッピングを開いて使用する方法を紹介しましたが、誰もがこの知識を理解していると思います。
今日お届けしたいのは、主にMyBatisの遅延読み込みとディスクリミネーターに関連する側面の知識と内容です。
遅延読み込み
遅延読み込みの概要
いわゆる遅延読み込みは、データの読み込みのタイミングを延期することであり、一般的なアプリケーションは、ネストされたクエリの実行のタイミングを延期することです。
mybatisでは関連クエリがよく使用されますが、関連クエリの結果をすぐに返す必要は必ずしもありません。たとえば、注文情報をクエリする場合、注文に対応するユーザー情報や注文の詳細を時間内に返す必要がないため、このような状況が発生した場合はメカニズムが必要です。関連データを表示する必要がある場合は、対応するクエリを実行すると、目的の結果が返されます。
この種の要求は、遅延読み込みメカニズムを使用してmybatisに実装できます。
遅延ロードの2つの設定方法
MyBatisには、遅延読み込み用の2つの設定方法があります。
- グローバル構成
- sqlmapで構成する方法
これら2つのメソッドの名前から判断すると、これら2種類の遅延読み込みの違いがわかります。最初のメソッドは関連するすべてのクエリに有効ですが、2番目のメソッドは関連する設定にのみ有効です。
遅延読み込みを使用する2つの方法を見てみましょう。
グローバル構成の遅延読み込み
グローバル設定遅延読み込みを実現するには、mybatisの設定ファイルを渡す必要があります。
mybatis構成ファイルは、次の2つの属性を使用して、読み込みの遅延を制御します。
<settings>
<!--打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当为true的时候,调用任意延迟属性,会去加载所有延迟属性,如果为false,则调用某个属性的时候,只会加载指定的属性 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
- lazyLoadingEnabled:このプロパティは理解しやすく、遅延読み込みを有効にするかどうか、デフォルトはfalseです。遅延読み込みを有効にする必要がある場合は、trueに設定してください。
- アグレッシブLazyLoading:trueの場合、任意の遅延プロパティを呼び出すと、すべての遅延プロパティがロードされます。falseの場合、特定のプロパティが呼び出されたときに、指定されたプロパティのみがロードされます。
これは、グローバル構成の遅延読み込みの説明です。特定の例を使用して、グローバル構成の遅延読み込みがどのように使用されるかを説明しましょう。
要求する
今回は、MyBatisを使用して需要を達成するために、注文ユーザー情報、注文詳細リストなど、注文IDを介して注文のさまざまな情報をクエリします。その中で、注文ユーザー情報と注文詳細情報は遅延読み込みによって取得されます。
mybatisの構成
前の紹介によると、最初のステップはmybatisの設定ファイルを介して設定することです。次のように:
<settings>
<!--打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当为true的时候,调用任意延迟属性,会去加载所有延迟属性,如果为false,则调用某个属性的时候,只会加载指定的属性 -->
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
OrderMapper.xml
グローバル構成をセットアップした後、通常の開発アプローチに進みます。1つ目は、xmlファイルを記述し、xmlファイルにsqlステートメントを書き込むことです。
<resultMap id="orderModelMap1" type="com.zhonghu.chat09.demo5.model.OrderModel">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="create_time" property="createTime"/>
<result column="up_time" property="upTime"/>
<!-- 通过订单中user_id作为条件,查询下单人信息 -->
<association property="userModel" select="com.zhonghu.chat09.demo5.mapper.UserMapper.getById1" column="user_Id"/>
<!-- 通过订单id作为条件,查询详情列表 -->
<collection property="orderDetailModelList" select="com.zhonghu.chat09.demo5.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>
<select id="getById1" resultMap="orderModelMap1">
<![CDATA[
SELECT
a.id ,
a.user_id,
a.create_time,
a.up_time
FROM
orders a
WHERE
a.id = #{value}
]]>
</select>
上記のorderModelMap1要素の下に2つの関連するクエリがありますが、それらについても記述しましょう。
UserMapper.xml
<!-- 根据用户id查询用户信息 -->
<select id="getById1" resultType="com.zhonghu.chat09.demo5.model.UserModel">
<![CDATA[
SELECT id,name FROM user where id = #{user_id}
]]>
</select>
OrderDetailMapper.xml
<!-- 根据订单di查询订单明细列表 -->
<select id="getListByOrderId1" resultType="com.zhonghu.chat09.demo5.model.OrderDetailModel">
<![CDATA[
SELECT
a.id,
a.order_id AS orderId,
a.goods_id AS goodsId,
a.num,
a.total_price AS totalPrice
FROM
order_detail a
WHERE
a.order_id = #{order_id}
]]>
</select>
対応する3モデル
上記の3つのxmlを記述し、次にxmlに対応するモデルを記述します。
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderModel {
private Integer id;
private Integer userId;
private Long createTime;
private Long upTime;
private UserModel userModel;
//订单详情列表
private List<OrderDetailModel> orderDetailModelList;
}
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserModel {
private Integer id;
private String name;
}
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderDetailModel {
private Integer id;
private Integer orderId;
private Integer goodsId;
private Integer num;
private Double totalPrice;
}
テストケース
モデルを記述したら、基本的にコードが完成します。次に、遅延読み込みの効果を見てみましょう。
com.zhonghu.chat09.demo5.Demo5Test#getById1
@Test
public void getById1() throws IOException {
//指定mybatis全局配置文件
mybatisConfig = "demo5/mybatis-config.xml";
this.before();
OrderModel orderModel = null;
try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
orderModel = mapper.getById1(1);
}
log.info("-------分割线--------");
log.info("{}", orderModel.getUserModel());
}
出力を実行
01:55.343 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ?
01:55.372 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 1(Integer)
01:55.431 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <== Total: 1
01:55.431 [main] INFO c.j.chat05.demo5.Demo5Test - -------分割线--------
01:55.432 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ==> Preparing: SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM order_detail a WHERE a.order_id = ?
01:55.432 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ==> Parameters: 1(Integer)
01:55.435 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <== Total: 2
01:55.439 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ==> Preparing: SELECT id,name FROM user where id = ?
01:55.439 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ==> Parameters: 2(Integer)
01:55.441 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <== Total: 1
01:55.441 [main] INFO c.j.chat05.demo5.Demo5Test - UserModel(id=2, name=Java冢狐)
ログから、合計3つのクエリがあり、次の2つのクエリが分割線の後に表示され、orderModel.getUserModel()が呼び出されて次の2つのクエリアクションがトリガーされることがわかります。
コードで呼び出すのはユーザー情報を取得することであり、注文リスト情報も読み込まれます。これは主に、aggressiveLazyLoadingがtrueに設定されているためです。遅延読み込み属性が使用されると、他の遅延読み込み属性も一緒に使用されます。 、したがって、2つの関連するクエリがトリガーされました。
アグレッシブLazyLoadingをfalseに設定した場合の効果を見てみましょう
<settings>
<!--打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当为true的时候,调用任意延迟属性,会去加载所有延迟属性,如果为false,则调用某个属性的时候,只会加载指定的属性 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
テストケース出力を再度実行します
12:19.236 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ?
12:19.268 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 1(Integer)
12:19.336 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <== Total: 1
12:19.337 [main] INFO c.j.chat05.demo5.Demo5Test - -------分割线--------
12:19.338 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ==> Preparing: SELECT id,name FROM user where id = ?
12:19.338 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ==> Parameters: 2(Integer)
12:19.340 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <== Total: 1
12:19.341 [main] INFO c.j.chat05.demo5.Demo5Test - UserModel(id=2, name=Java冢狐)
これら2つの比較を通じて、遅延読み込みが有効になっているかどうかの効果の違いを簡単に確認できます。
sqlmapでの遅延読み込み
上記のスペースでは、グローバル遅延読み込みの仕組みと使用方法を紹介しました。グローバルアプローチはすべての関連クエリに有効であり、影響の範囲は比較的大きいです。Mybatisは、現在設定されている関連クエリにのみ有効になる関連クエリを設定する方法も提供します。
関連付けられたクエリ。通常は関連付けとコレクションを使用します。これら2つの要素にはfetchType属性があり、この属性を介して関連付けられたクエリの読み込み方法を指定できます。
fetchTypeには2つの値があります
- 熱心:すぐにロード
- レイジー:レイジーローディング
要件を実装しましょう。引き続き注文IDを使用して注文情報をクエリし、関連するユーザー情報と注文詳細リストを取得します。ユーザー情報はすぐに読み込む必要があり、注文詳細は後で読み込む必要があります。
mapperxmlは次のとおりです
<resultMap id="orderModelMap2" type="com.zhonghu.chat09.demo5.model.OrderModel">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="create_time" property="createTime"/>
<result column="up_time" property="upTime"/>
<!-- 通过订单中user_id作为条件,查询下单人信息 -->
<association property="userModel" fetchType="eager" select="com.zhonghu.chat09.demo5.mapper.UserMapper.getById1" column="user_Id"/>
<!-- 通过订单id作为条件,查询详情列表 -->
<collection property="orderDetailModelList" fetchType="lazy" select="com.zhonghu.chat09.demo5.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>
<select id="getById2" resultMap="orderModelMap2">
<![CDATA[
SELECT
a.id ,
a.user_id,
a.create_time,
a.up_time
FROM
orders a
WHERE
a.id = #{value}
]]>
</select>
上記の構成の関連付けと収集の2つの要素のfetchType属性に注意してください。eagerは即時ロードを意味し、lazyは遅延ロードを意味します。
テストケース
com.zhonghu.chat09.demo5.Demo5Test#getById2
@Test
public void getById2() throws IOException {
//指定mybatis全局配置文件
mybatisConfig = "demo5/mybatis-config2.xml";
this.before();
OrderModel orderModel = null;
try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
orderModel = mapper.getById2(1);
}
log.info("-------分割线--------");
log.info("{}", orderModel.getOrderDetailModelList());
}
出力を実行
36:54.284 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ?
36:54.321 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Parameters: 1(Integer)
36:54.385 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Preparing: SELECT id,name FROM user where id = ?
36:54.385 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 2(Integer)
36:54.387 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <==== Total: 1
36:54.389 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - <== Total: 1
36:54.390 [main] INFO c.j.chat05.demo5.Demo5Test - -------分割线--------
36:54.392 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ==> Preparing: SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM order_detail a WHERE a.order_id = ?
36:54.392 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ==> Parameters: 1(Integer)
36:54.397 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <== Total: 2
36:54.398 [main] INFO c.j.chat05.demo5.Demo5Test - [OrderDetailModel(id=1, orderId=1, goodsId=1, num=2, totalPrice=16.00), OrderDetailModel(id=2, orderId=1, goodsId=1, num=1, totalPrice=16.00)]
出力の分割線に注意してください。ユーザー情報は注文情報と一緒にすぐに見つかり、orderModel.getOrderDetailModelList()を呼び出して注文リストを取得すると、注文の詳細が遅延して読み込まれることが分析できます。
弁別器
データベースクエリが複数の異なる結果セットを返す場合があります(ただし、一般的には特定の接続があります)。discriminator要素はこの状況に対処するように設計されており、discriminatorの概念はよく理解されています-スイッチと非常によく似ています。 Java言語のステートメント。
識別子タグの2つの一般的に使用される属性は次のとおりです。
- column:この属性は、値が比較される列を設定するために使用されます。
- javaType:この属性は、列のタイプを指定して、同じjavaタイプが値の比較に使用されるようにするために使用されます。
Discriminatorタグには、1つ以上のcaseタグを含めることができます。caseタグには、より重要な属性があります。
- value:この値は、ディスクリミネーターが照合に使用する列を指定する値です。一致すると、結果はこのケースに関連付けられたマッピングに従います。
ディスクリミネーターを使用して関数を実装します。注文IDを介して注文情報をクエリし、受信注文IDが1の場合、注文情報と注文者の情報を取得します。受信注文IDが2の場合、取得します。注文情報、注文情報、注文詳細情報。その他の場合、デフォルトでは注文情報のみが照会されます。
OrderMapper.xml
<resultMap id="orderModelMap1" type="com.zhonghu.chat09.demo6.model.OrderModel">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="create_time" property="createTime"/>
<result column="up_time" property="upTime"/>
<!-- 鉴别器 -->
<discriminator javaType="int" column="id">
<case value="1">
<!--通过用户id查询用户信息-->
<association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
</case>
<case value="2">
<!--通过用户id查询用户信息-->
<association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
<!--通过订单id查询订单列表-->
<collection property="orderDetailModelList" select="com.zhonghu.chat09.demo6.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</case>
</discriminator>
</resultMap>
<select id="getById1" resultMap="orderModelMap1">
<![CDATA[
SELECT
a.id ,
a.user_id,
a.create_time,
a.up_time
FROM
orders a
WHERE
a.id = #{value}
]]>
</select>
上記のディスクリミネーターに注意してください。この部分が重要です。ディスクリミネーター内のケースは、クエリ結果の各行のidフィールドと照合されます。照合が成功すると、ケース内の関連するクエリが実行されます。一致せず、ディスクリミネーターのみがデフォルトになります。構成されたマッピングルール。
UserMapper.xml
<!-- 通过用户id查询用户信息 -->
<select id="getById1" resultType="com.zhonghu.chat09.demo6.model.UserModel">
<![CDATA[
SELECT id,name FROM user where id = #{user_id}
]]>
</select>
OrderDetailMapper.xml
<!-- 通过订单id查询订单明细列表 -->
<select id="getListByOrderId1" resultType="com.zhonghu.chat09.demo6.model.OrderDetailModel">
<![CDATA[
SELECT
a.id,
a.order_id AS orderId,
a.goods_id AS goodsId,
a.num,
a.total_price AS totalPrice
FROM
order_detail a
WHERE
a.order_id = #{order_id}
]]>
</select>
対応する3つのモデルクラス
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderModel {
private Integer id;
private Integer userId;
private Long createTime;
private Long upTime;
//用户信息
private UserModel userModel;
//订单详情列表
private List<OrderDetailModel> orderDetailModelList;
}
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserModel {
private Integer id;
private String name;
}
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderDetailModel {
private Integer id;
private Integer orderId;
private Integer goodsId;
private Integer num;
private Double totalPrice;
}
テストケース
com.zhonghu.chat09.demo6.Demo6Test#getById1
@Test
public void getById1() throws IOException {
try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
//查询订单为1的
OrderModel orderModel = mapper.getById1(1);
log.info("{}", orderModel);
log.info("------------------------------------------------------------");
//查询订单为2的
orderModel = mapper.getById1(2);
log.info("{}", orderModel);
log.info("------------------------------------------------------------");
//查询订单为3的
orderModel = mapper.getById1(3);
log.info("{}", orderModel);
}
}
出力を実行
58:16.413 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ?
58:16.457 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 1(Integer)
58:16.481 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Preparing: SELECT id,name FROM user where id = ?
58:16.481 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 2(Integer)
58:16.488 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <==== Total: 1
58:16.489 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <== Total: 1
58:16.489 [main] INFO c.j.chat05.demo6.Demo6Test - OrderModel(id=1, userId=2, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=2, name=Java冢狐), orderDetailModelList=null)
58:16.491 [main] INFO c.j.chat05.demo6.Demo6Test - ------------------------------------------------------------
58:16.491 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ?
58:16.492 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 2(Integer)
58:16.493 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Preparing: SELECT id,name FROM user where id = ?
58:16.493 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 1(Integer)
58:16.494 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <==== Total: 1
58:16.495 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====> Preparing: SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM order_detail a WHERE a.order_id = ?
58:16.495 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====> Parameters: 2(Integer)
58:16.505 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <==== Total: 1
58:16.505 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <== Total: 1
58:16.506 [main] INFO c.j.chat05.demo6.Demo6Test - OrderModel(id=2, userId=1, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=1, name=冢狐), orderDetailModelList=[OrderDetailModel(id=3, orderId=2, goodsId=1, num=1, totalPrice=8.00)])
58:16.506 [main] INFO c.j.chat05.demo6.Demo6Test - ------------------------------------------------------------
58:16.506 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ?
58:16.506 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - ==> Parameters: 3(Integer)
58:16.508 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById1 - <== Total: 1
58:16.509 [main] INFO c.j.chat05.demo6.Demo6Test - OrderModel(id=3, userId=1, createTime=1610803573, upTime=1610803573, userModel=null, orderDetailModelList=null)
出力から、オーダー1が2回照会され、オーダー2が3回照会され、オーダー3が1回照会されたことがわかります。これは、ディスクリミネーターが優れた機能であると見なされます。
継承(拡張)
Javaでの継承は、コードを再利用する役割を果たすことができる3つの主要な機能の1つであり、mybatisには、Javaでの継承の役割と同様の継承の機能もあります。これは、主にresultMapで使用され、他のresultMapで構成されたマッピング関係。
使用法
<resultMap extends="被继承的resultMap的id"></resultMap>
ケーススタディ
継承を使用して、上記の識別子のケースを変換し、コードを最適化しましょう
OrderMapper.xml
<resultMap id="orderModelMap2" type="com.zhonghu.chat09.demo6.model.OrderModel">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="create_time" property="createTime"/>
<result column="up_time" property="upTime"/>
<!-- 鉴别器 -->
<discriminator javaType="int" column="id">
<case value="1" resultMap="orderModelMap3" />
<case value="2" resultMap="orderModelMap4" />
</discriminator>
</resultMap>
<resultMap id="orderModelMap3" type="com.zhonghu.chat09.demo6.model.OrderModel" extends="orderModelMap2">
<!--通过用户id查询用户信息-->
<association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
</resultMap>
<resultMap id="orderModelMap4" type="com.zhonghu.chat09.demo6.model.OrderModel" extends="orderModelMap3">
<!--通过订单id查询订单列表-->
<collection property="orderDetailModelList" select="com.zhonghu.chat09.demo6.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>
<select id="getById2" resultMap="orderModelMap2">
<![CDATA[
SELECT
a.id ,
a.user_id,
a.create_time,
a.up_time
FROM
orders a
WHERE
a.id = #{value}
]]>
</select>
上記の2つのextendsプロパティに焦点が当てられています。上記のorderModelMap3は、orderModelMap2で構成されたマッピング関係(ディスクリミネーターを除く)を継承し、クエリユーザー情報への関連付けを追加します。orderModelMap4はorderModelMap3を継承し、クエリ注文リストを追加します。コレクション要素。上記の使用法は、コードの再利用を実現するために拡張されています。これは、実際には次のコードと同じです。
<resultMap id="orderModelMap2" type="com.zhonghu.chat09.demo6.model.OrderModel">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="create_time" property="createTime"/>
<result column="up_time" property="upTime"/>
<!-- 鉴别器 -->
<discriminator javaType="int" column="id">
<case value="1" resultMap="orderModelMap3" />
<case value="2" resultMap="orderModelMap4" />
</discriminator>
</resultMap>
<resultMap id="orderModelMap3" type="com.zhonghu.chat09.demo6.model.OrderModel">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="create_time" property="createTime"/>
<result column="up_time" property="upTime"/>
<!--通过用户id查询用户信息-->
<association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
</resultMap>
<resultMap id="orderModelMap4" type="com.zhonghu.chat09.demo6.model.OrderModel">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="create_time" property="createTime"/>
<result column="up_time" property="upTime"/>
<!--通过用户id查询用户信息-->
<association property="userModel" select="com.zhonghu.chat09.demo6.mapper.UserMapper.getById1" column="user_Id"/>
<!--通过订单id查询订单列表-->
<collection property="orderDetailModelList" select="com.zhonghu.chat09.demo6.mapper.OrderDetailMapper.getListByOrderId1" column="id"/>
</resultMap>
<select id="getById2" resultMap="orderModelMap2">
<![CDATA[
SELECT
a.id ,
a.user_id,
a.create_time,
a.up_time
FROM
orders a
WHERE
a.id = #{value}
]]>
</select>
テストケース
com.zhonghu.chat09.demo6.Demo6Test#getById2
@Test
public void getById2() throws IOException {
try (SqlSession sqlSession = this.sqlSessionFactory.openSession(true);) {
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
//查询订单为1的
OrderModel orderModel = mapper.getById2(1);
log.info("{}", orderModel);
log.info("------------------------------------------------------------");
//查询订单为2的
orderModel = mapper.getById2(2);
log.info("{}", orderModel);
log.info("------------------------------------------------------------");
//查询订单为3的
orderModel = mapper.getById2(3);
log.info("{}", orderModel);
}
}
出力を実行
39:55.936 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ?
39:55.969 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Parameters: 1(Integer)
39:55.986 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Preparing: SELECT id,name FROM user where id = ?
39:55.987 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 2(Integer)
39:55.992 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <==== Total: 1
39:55.993 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - <== Total: 1
39:55.993 [main] INFO c.j.chat05.demo6.Demo6Test - OrderModel(id=1, userId=2, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=2, name=Java冢狐), orderDetailModelList=null)
39:55.994 [main] INFO c.j.chat05.demo6.Demo6Test - ------------------------------------------------------------
39:55.994 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ?
39:55.995 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Parameters: 2(Integer)
39:55.995 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====> Preparing: SELECT a.id, a.order_id AS orderId, a.goods_id AS goodsId, a.num, a.total_price AS totalPrice FROM order_detail a WHERE a.order_id = ?
39:55.996 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - ====> Parameters: 2(Integer)
39:56.000 [main] DEBUG c.j.c.d.m.O.getListByOrderId1 - <==== Total: 1
39:56.001 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Preparing: SELECT id,name FROM user where id = ?
39:56.004 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - ====> Parameters: 1(Integer)
39:56.005 [main] DEBUG c.j.c.d.mapper.UserMapper.getById1 - <==== Total: 1
39:56.005 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - <== Total: 1
39:56.005 [main] INFO c.j.chat05.demo6.Demo6Test - OrderModel(id=2, userId=1, createTime=1610803573, upTime=1610803573, userModel=UserModel(id=1, name=冢狐), orderDetailModelList=[OrderDetailModel(id=3, orderId=2, goodsId=1, num=1, totalPrice=8.00)])
39:56.005 [main] INFO c.j.chat05.demo6.Demo6Test - ------------------------------------------------------------
39:56.005 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Preparing: SELECT a.id , a.user_id, a.create_time, a.up_time FROM orders a WHERE a.id = ?
39:56.006 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - ==> Parameters: 3(Integer)
39:56.007 [main] DEBUG c.j.c.d.mapper.OrderMapper.getById2 - <== Total: 1
39:56.007 [main] INFO c.j.chat05.demo6.Demo6Test - OrderModel(id=3, userId=1, createTime=1610803573, upTime=1610803573, userModel=null, orderDetailModelList=null)
総括する
この記事の冒頭では、MyBatisの遅延読み込みの関連コンテンツに焦点を当て、グローバル遅延読み込みと部分遅延読み込みに焦点を当てています。遅延読み込みが導入された後、いくつかの関連する識別子と継承が紹介されます。関連コンテンツ。
やっと
- 読んでやりがいを感じたら、気をつけたいと思います。ちなみに、いいねを言ってください。これが私のアップデートの最大のモチベーションになります。ご支援ありがとうございます。
- Javaとコンピュータの基本的な知識に焦点を当てた私の公開アカウント[JavaFox]に注目してください。私を信じていない場合は、私を叩いてください。
- ワンクリックのトリプル接続を探します:いいね、転送、視聴。
- 読んだ後に異なる意見や提案がある場合は、コメントして私たちと共有してください。皆様のご支援、ご愛顧を賜りますようお願い申し上げます。
-私は竹湖です。あなたと同じくらいプログラミングが大好きです。
最新ニュースについては、パブリックアカウント「JavaFox」をフォローすることを歓迎します