spring data jpa dao層接口返回元素爲null的list

項目使用Spring Data JPA作爲數據層的框架,用來操作數據庫。
其支持使用 @Query 註解來自定義查詢語句,正是此功能,遇到了一個問題,返回的結果集包含了null的元素

項目中有 用戶表、角色表、用戶關聯角色表,想要實現通過角色ID查詢所有相關聯用戶信息。
代碼如下,大家可以先思考下異同:

public interface UserToRoleDao extends JpaRepositoryImplementation<UserToRolePO, String> {

	@Query("select u from UserToRolePO utr left join UserPO u on utr.userId = u.id and utr.roleId = ?1")
	List<UserPO> findUsersByRoleId(String roleId);

	@Query("select u from UserToRolePO utr left join UserPO u on utr.userId = u.id where utr.roleId = ?1")
	List<UserPO> findUsersByRoleId2(String roleId);

}

有區別嗎?
是的,sql的左後一段,判斷roleId用了不同的方式。
findUsersByRoleId 方法使用了 and,findUsersByRoleId2方法使用了 where。

最終的結果就是,當查詢的角色並沒有關聯任何一個用戶時,findUsersByRoleId 返回了擁有1個元素的list,但是這一個元素是null;findUsersByRoleId2 返回了一個空的list。

探究下所以然,開啓了jpa的show_sql = true。當執行查詢時打印日誌。在控制檯看到兩個查詢對應的sql語句。

@Query("select u from UserToRolePO utr left join UserPO u on utr.userId = u.id and utr.roleId = ?1")
List<UserPO> findUsersByRoleId(String roleId);
對應的sql,記爲sql1:
SELECT
	userpo1_.id AS id1_13_,
	userpo1_.name AS name10_13_,
	userpo1_.nickname AS nicknam11_13_,
	userpo1_.password AS passwor12_13_
FROM
	role_to_user roletou0_
LEFT OUTER JOIN sys_user userpo1_ ON (
	roletou0_.user_id = userpo1_.id
	AND roletou0_.role_id = '?'
)
///////////////////////////////////////
///////////////////////////////////////
@Query("select u from UserToRolePO utr left join UserPO u on utr.userId = u.id where utr.roleId = ?1")
List<UserPO> findUsersByRoleId2(String roleId);
對應的sql是,記爲sql2:
SELECT
	userpo1_.id AS id1_13_,
	userpo1_.name AS name10_13_,
	userpo1_.nickname AS nicknam11_13_,
	userpo1_.password AS passwor12_13_
FROM
	role_to_user roletou0_
LEFT OUTER JOIN sys_user userpo1_ ON (
	roletou0_.user_id = userpo1_.id
)
WHERE
	roletou0_.role_id = '?'
}

隨便填個role_id,拿這兩條sql語句分別在數據庫中執行,果然,返回結果是不一樣的。(如果是在圖形化工具上執行sql,可能看到結果是一樣的。爲了避免圖形化工具瞎摻和的情況,博主特意在shell窗口執行sql。)
開啓shell終端,執行 mysql -uroot -proot 登錄mysql,執行 use test_db; 切換到指定數據庫。
分別執行上述sql語句,可以看到,
sql1 返回了一行全是null值的記錄。
在這裏插入圖片描述
sql2返回了 “Empty set”
在這裏插入圖片描述

這就可以初略解釋爲什麼兩種寫法在程序中的結果不一致。至於msyql是如何解析執行sql的,等有時間再研究吧。


end

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章