mybatis中mapper引用另外一个mapper的resultMap或select

本文介绍了在Mybatis中遇到的一个问题:如何在UserMapper.xml中引用UserDetailMapper.xml的resultMap。通过分析错误提示,发现由于namespace不同导致引用失败。解决方案是使用完整的namespace路径来引用resultMap,或者直接使用select标签引用其他mapper的查询方法。作者通过实践总结了解决此类问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

先来看一下两个mapper:

UserMapper.xml——主要完成对用户表(user)的表操作

<mapper namespace=”com.A.xsstuser.impl.dao.UserDao”>
<resultMap id=”BaseResultMap” type=”com.kainaodong.xsstuser.impl.model.User”>
<id column=”user_id” jdbcType=”INTEGER” property=”userId” />
<result column=”nickname” jdbcType=”VARCHAR” property=”nickname” />
<result column=”school_id” jdbcType=”INTEGER” property=”schoolId” />
<result column=”password” jdbcType=”VARCHAR” property=”password” />
……
</resultMap>
……
</mapper>

 UserDetailMapper.xml——主要完成对用户详情表(UserDetail)的表操作

<mapper namespace=”com.A.xsstuser.impl.dao.UserDetailDao”>
<resultMap id=”UserDetailMap” type=”com.kainaodong.xsstuser.impl.model.UserDetail” >
<id column=”user_id” property=”userId” jdbcType=”INTEGER” />
<result column=”realname” property=”realname” jdbcType=”VARCHAR” />
<result column=”gender” property=”gender” jdbcType=”TINYINT” />
<result column=”birthday” property=”birthday” jdbcType=”DATE” />
……
</resultMap>
<sql id=”UserDetail_Base_Column_List” >
user_id, realname, gender, birthday
</sql>
<select id=”selectUserDetailById” resultMap=”UserDetailMap” parameterType=”java.lang.Integer” >
select
<include refid=”UserDetail_Base_Column_List” />
from user_detail
where user_id = #{userId,jdbcType=INTEGER}
</select>
</mapper>

现在有一个需求是需要将User表和UserDetail进行关联查询。我的设计是将这个操作放在UserMapper.xml里面。复杂的关联查询在网上都有很多说明了,这里就不复述了。

既然UserDetailMapper.xml中已经有了映射UserDetail表的列,因此按照编程习惯,肯定要复用一下的,所以根据网上的资料,一开始我在UserMapper.xml里面添加了如下resultMap:

<resultMap id=”UserJoinUserDetail” type=”User”>
<id column=”user_id” jdbcType=”INTEGER” property=”userId” />
<result column=”nickname” jdbcType=”VARCHAR” property=”nickname” />
<result column=”school_id” jdbcType=”INTEGER” property=”schoolId” />
<result column=”password” jdbcType=”VARCHAR” property=”password” />
……
<!– 关联userdetail表 –>
<association property=”userDetail” column=”user_detail” resultMap=”UserDetailMap” />
</resultMap>

保存,然后测试,嗯~妥妥的报错了。看了一下提示,大概就是UserDetailMap不存在的意思。那就奇怪了,明明在UserDetailMapper.xml中定义了的,为什么呢?然后就查看两个mapper,看到<mapper namespace ……>,难道由于namespace不同原因,所以果断将UserDetailMapper.xml的namespace换成和UserMapper的相同的。再测试,这次成功了,真的是namespace的原因。

那这样说,是不是应该同一个模块的mapper的namespace都设成一样呢?我测试了一下,如果改成其他名称如:User,启动的时候会报错(由于mapper是用mybatis的相关功能自动生成的,所以当时只引入了xml,而没将mapper 接口类引入,不然改了UserDetailMapper的namespace时,应该启动就报错)。原因是这个namespace有一个意义是指定相关POJO接口的路径,详情可查看以下链接。

Mybatis的namespace问题说明

那该怎么办,上网找,好像都没有很明确关于如何引用其他mapper文件中的resultMap的文章。那只能再回去看错误日志:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:

Error querying database. Cause: java.lang.IllegalArgumentException: Result Maps collection does not contain value for com.A.kainaodong.xsstuser.impl.dao.UserDao.UserDetailMap

The error may exist in com/A/xsstuser/impl/dao/UserMapper.xml

细心看,其实可以发现,错误中com.A.kainaodong.xsstuser.impl.dao.UserDao.UserDetailMap的UserDetailMap前面还有一串东西,刚好也就是UserMapper的namespace,在UserMapper下当然是找不到UserDetailMap的了,那如果在UserDetailMap前加上UserDetailMapper的namespace的话可能可以,即:

<association property=”userDetail” column=”user_detail” resultMap=”com.A.xsstuser.impl.dao.UserDetailDao.UserDetailMap” />

然后保存,测试,通过。确实可以这样写。

如果不引用resultmap的话,可以应用其他文件的select,如下

<association property=”userDetail” column=”user_id” select=”com.kainaodong.xsstuser.impl.dao.UserDetailDao.selectUserDetailById” /> // 当然也要加上namespace咯。

出现这种问题,也可能由于我对mybatis的运行机制还不太了解。所以写一下这篇文章,整理一下思路。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值