解決する複数の方法 selectOne() によって 1 つの結果 (または null) が返されることが予期されましたが、見つかりました: x エラー

1. エラーを再現します


今日、テスト女性は、テスト環境のバックグラウンド管理システムのホームページでエラーが報告されたと言い、次の写真を送ってきました。

ここに画像の説明を挿入

テスト環境のデータベースは変更できないため、テスト環境のデータベースはバックアップしてローカルにコピーすることしかできません。

次の図に示すように、バックアップ上にマウスを置き、右クリックして「バックアップの復元」を選択し、「開始」をクリックします。

ここに画像の説明を挿入

[注意事項] バックアップを復元すると、現在のデータベース内の既存のデータが置き換えられるため、慎重に行う必要があります。

次の図に示すように、ローカルにバックアップした後、ローカルを使用してKnife4j問題のあるインターフェイスをテストします。

ここに画像の説明を挿入

案の定、例外が発生しました org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2

2. 分析エラー


次の図に示すように、これChatGPTを使用して質問に戻ることができます。

ここに画像の説明を挿入

しかし、ChatGP私の質問に答えることはできません。この例外を自分で分析することしかできません。

私たちはExpected one result (or null) to be returned by selectOne(), but found: 2この文を分析して中国語に翻訳することに重点を置いています。希望返回1个结果(或者null),但返回了2个结果。

2 つの結果が返されるのはなぜですか? 分析を続けます。

selectOne()次のコードに示すように、メソッドが呼び出される場所を見つけます。

......
 // 获取企业用户 id
Wrapper<EnterpriseUser> queryWrapper =new LambdaQueryWrapper<EnterpriseUser>()
   .eq(EnterpriseUser::getUserId, tokenProperties.getUserId());

EnterpriseUser enterpriseUser = enterpriseUserService.selectOne(queryWrapper);
......

同時に、コードに示すように、mybatis出力されたステートメントを見つけます。SQL

SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2165c177] was not registered for synchronization because synchronization is not active
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@6c5e6da] will not be managed by Spring

==>  Preparing: select * from enterprise_user_role r where r.enterprise_user_id = ? and r.role_id in(select id from role where deleted = 0)
==> Parameters: 1(Long)
<==    Columns: id, enterprise_user_id, role_id, create_time, update_time, deleted
<==        Row: 37, 1, 4, 2023-01-03 16:26:29, 2023-01-03 16:26:28, 0
<==        Row: 94, 1, 17, 2023-03-02 10:00:39, 2023-03-02 10:00:37, 0
<==      Total: 2

上記のSQLステートメントから判断すると、データの一部が返されるのは事実です2

ただしselectOne()、このメソッドはデータの一部しか返せないため、現在はデータの一部を1返すため、上記のエラーが報告されます。2

同時に、クエリ条件に従って複数のデータがクエリされた場合、getOne()メソッドは上記のエラーも報告します。

したがって、selectOne()orgetOne()メソッドを使用して複数のデータをクエリすることはできません。

3. 問題を解決する


プロダクトマネージャーとコミュニケーションをとり、プロダクトマネージャーから提示された企画書の中から最新のデータを選択します。

最新のデータを選択するには、次の 2 つの方法を使用します。

  1. list()次のコードに示すように、メソッドをselectOne()メソッドに置き換えます。
......
 // 获取企业用户 id
Wrapper<EnterpriseUser> queryWrapper = new LambdaQueryWrapper<EnterpriseUser>()
     .eq(EnterpriseUser::getUserId, tokenProperties.getUserId())
     .orderByDesc(EnterpriseUser::getCreateTime);

 EnterpriseUser enterpriseUser = null;
 List<EnterpriseUser> enterpriseUsers = enterpriseUserService.list(queryWrapper);
 if (!enterpriseUsers.isEmpty()) {
    
    
   enterpriseUser = enterpriseUsers.get(0);
 }
......
  1. selectOne()次のコードに示すように、メソッドの代わりにメソッドを書き換えます。
  • EnterpriseUserMapperクラスの新しいselectOneByLimitメソッド
/**
 * 通过用户查询企业用户
 *
 * @author super先生
 * @datetime 2023/3/2:13:34
 * @param userId 用户id
 * @return 返回企业用户信息
 */
@Select(
    "SELECT "
        + " *  "
        + "FROM "
        + " enterprise_user_role r  "
        + "WHERE "
        + " r.enterprise_user_id = #{userId}  "
        + " AND r.role_id IN ( SELECT id FROM role WHERE deleted = 0 ) "
        + "ORDER BY create_time DESC "
        + "LIMIT 1")
EnterpriseUser selectOneByLimit(@Param("userId") Long userId);
  • EnterpriseUserServiceクラスselectOneByLimitの新しいメソッド
/**
 * 通过用户查询企业用户
 *
 * @author super先生
 * @datetime 2023/3/2:13:38
 * @param userId 用户id
 * @return 返回企业用户信息
 */
public EnterpriseUser selectOneByLimit(Long userId) {
    
    
  return enterpriseUserMapper.selectOneByLimit(userId);
}
  • その他のサービスクラス呼び出しEnterpriseUserService#selectOneByLimitメソッド
......
EnterpriseUser enterpriseUser = enterpriseUserService.selectOneByLimit(tokenProperties.getUserId());
......

4. 記事の備考


上記のエラー メッセージが報告されます: Expected one result (or null) to be returned by selectOne(), but found: 2

通常、データの一部をクエリする必要があるため、selectOne()orgetOne()メソッドを使用します。ただし、クエリ条件に従って、複数のデータがクエリされます。

変更方法は、プロダクトマネージャーを自分で選択できます。プロダクトマネージャーのニーズに応じて、最適なソリューションを決定します。

私の解決策で問題を解決できない場合は、コメント欄にメッセージを残していただければ、みんなで一緒に進歩していきます。

おすすめ

転載: blog.csdn.net/lvoelife/article/details/129299453