TakeshiUeta
@TakeshiUeta

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Spring-bootのMyBatisで期待通りの結果にならない

MyBatisで記述したクエリでList型の戻り値が返って来ないので困っています

いつもお世話になっております。
Spring-bootのMyBatisで期待通りの戻り値が返ってこないので困っています。
分かる方がいらっしゃたらお答え頂けると幸いです。

発生している問題・エラー

以下の記述をした時にresultUIdAllをコントローラでサービスとして使用したときに戻り値として帰ってきたUserクラスのresultListに何も格納されていません。
色々試してみましたが結局分からず・・・。
冗長で見辛いかと思いますが下記にソースコードを記述します。

問題の画像

デバッグしてresultUIdAllを使用した時の画像です。

スクリーンショット 2023-09-24 182739.png
赤枠のところのResultListのElementDataが空です・・・。
(サービスとして実装しているのでメソッド名が違いますがresultUIdAllを
ただ使用して戻り値をreturnしているだけのものです。)

Mapper.XML

~省略~
<mapper namespace="com.example.Mapper.UserMapper">
	<resultMap type="com.example.form.User" id="user">
		<id column="user_id" property="userId" />
		<result column="password" property="password" />
		<result column="user_name" property="name" />
		<collection property="resultList" resultMap="result"
			columnPrefix="result_" />
	</resultMap>

	<resultMap type="com.example.form.Result" id="result">
		<id column="result_id" property="resultId" />
		<result column="go_time" property="goTime" />
		<result column="out_time" property="outTime" />
		<result column="user_id" property="userId" />
	</resultMap>
~省略~
	<!--ユーザーIDと紐付いた結果をすべて取得 -->
	<select id="resultUIdAll" resultMap="user">
		select
			 t_user.user_id
			,t_user.user_name
			,t_result.result_id as t_result_result_id
			,t_result.go_time as t_result_go_time
			,t_result.out_time as t_result_out_time
			,t_result.user_id as t_result_user_id
		from
			t_user
		left join
			t_result
		on
			t_user.user_id = t_result.user_id
		where
			t_user.user_id = #{userId}
	</select>
</mapper>

Mapper.java

@Mapper
public interface UserMapper {
~省略~
	/*ユーザーIDと紐付いた結果を全て取得*/
	public User resultUIdAll(String userId);
}

エンティティ

User.java

package com.example.form;

import java.util.List;

import lombok.Data;

@Data
public class User {
	/* ユーザーID */
	private String userId;
	/* パスワード */
	private String password;
	/* 名前 */
	private String name;
	/* 結果リスト */
	private List<Result> resultList;

	/**
	 * コンストラクタ
	 */
	User() {
	}

	/**
	 * コンストラクタ
	 * @param userId   ユーザーID
	 * @param password パスワード
	 * @param name     名前
	 */
	User(String userId, String password, String name) {
		this.userId = userId;
		this.password = password;
		this.name = name;
	}

	/**
	 * コンストラクタ
	 * @param userId     ユーザーID
	 * @param password   パスワード
	 * @param name       名前
	 * @param resultList 結果リスト
	 */
	User(String userId, String password, String name, List<Result> resultList) {
		this.userId = userId;
		this.password = password;
		this.name = name;
		this.resultList = resultList;
	}

}

Result.java

package com.example.form;

import lombok.Data;

@Data
public class Result {
	/* 結果ID */
	private String resultId;
	/* 出勤時間 */
	private String goTime;
	/* 退勤時間 */
	private String outTime;
	/* ユーザーID */
	private String userId;

	/**
	 * コンストラクタ
	 */
	Result() {
	}

	/**
	 * コンストラクタ
	 * 
	 * @param resultId 結果ID
	 * @param goTime   出勤時間
	 * @param outTime  退勤時間
	 */
	Result(String resultId, String goTime, String outTime, String userId) {
		this.resultId = resultId;
		this.goTime = goTime;
		this.outTime = outTime;
		this.userId = userId;
	}
}

schema.sql,Data.sql

schema.sql

/*ユーザーマスタ*/
CREATE TABLE IF NOT EXISTS t_user(
	 user_id VARCHAR(50) PRIMARY KEY
	,password VARCHAR(100)
	,user_name VARCHAR(50)
);
/*結果テーブル*/
CREATE TABLE IF NOT EXISTS t_result(
	 result_id VARCHAR(50) PRIMARY KEY
	,go_time timestamp
	,out_time timestamp
	,user_id VARCHAR(50)
);

data.sql

/**
*データ挿入
*/

/*ユーザーマスタ*/
INSERT INTO t_user(
	user_id,
	password,
	user_Name
)VALUES
	('****','***','タイム太郎'),
	('****','***','タイム二郎')
;
/*結果テーブル*/
INSERT INTO t_result(
	result_id,
	go_time,
	out_time,
	user_id
)VALUES
	('*****','2023-01-05 9:45:30','2023-01-05 19:00:30','*****'),
	('*****','2023-01-06 9:50:30','2023-01-06 19:10:30','*****'),
	('*****','2023-01-07 9:40:30','2023-01-07 19:05:30','*****')
;
※ID,passwordはプライバシー保護のため隠します。

自分で試したこと

xmlの記述が悪いのかと思いresultMapperタグやcollectionタグを確認しましたが、特に問題はないように思えます。
クエリが悪いのかなとも思いターミナルでテストも行いましたが問題なく出力されました。
他にもサイトなどで調べたりしましたが分からず・・・。

八方塞がりなのでよろしければ助けて頂けると幸いです。何卒宜しくお願い致します。

0

2Answer

SQLを見ると、t_resultテーブルの結果には、t_result_というprefixを付与しています。一方、Mapper XMLでは以下のように記載されており、整合性が取れていないようにみえます。

<collection property="resultList" resultMap="result"
			columnPrefix="result_" />
0Like

Comments

  1. @TakeshiUeta

    Questioner

    ご返信頂きありがとうございます!
    うわぁ・・・こんな初歩的なミスを。お恥ずかしい・・・。
    ホントに申し訳ありません。
    ご指摘いただきありがとうございました。
    以上でクローズとさせて頂きます。

MyBatisを最後に触ってから少し時間が経ってまして、違っていましたら、すみません。

<collection property="resultList" resultMap="result"
			columnPrefix="result_" />

columnPrefix="result_"というルールを設定されていますね。

SQLのエイリアスの部分について、
as result_XXXといった形で、result_を先頭にもってこないと、データが取得できなかったと思います。
以下のようにSQLを書き換えます。

	<select id="resultUIdAll" resultMap="user">
		select
			 t_user.user_id
			,t_user.user_name
			,t_result.result_id as result_t_result_result_id
			,t_result.go_time as result_t_result_go_time
			,t_result.out_time as result_t_result_out_time
			,t_result.user_id as result_t_result_user_id
		from
			t_user
		left join
			t_result
		on
			t_user.user_id = t_result.user_id
		where
			t_user.user_id = #{userId}
	</select>

試してみてください!

(以下あたりを眺めてました。)
https://mybatis.org/mybatis-3/ja/sqlmap-xml.html#%E3%83%8D%E3%82%B9%E3%83%88%E3%81%95%E3%82%8C%E3%81%9F%E7%B5%90%E6%9E%9C%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6-collection-%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80

0Like

Comments

  1. @TakeshiUeta

    Questioner

    ご丁寧な対応ありがとうございます!

    columnPrefix="t_result_"
    

    とすることで対応いたしました。
    お騒がせして申し訳ありませんでした。

Your answer might help someone💌