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

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