Mybatis的Mapper接口方法无法重载


前言

博主最近在基于 [smpe](www.baidu.com) 开源框架去写一个项目,但是因为数据库的表需要修改,一些mapper的sql也需要做修改。为了保证原有项目的可运行,就直接在mapper.class下进行了重载,但是结果却不对。

一、情景再现

提示:为了详细说明,本篇博客就快速创建简单的mapper和数据库表进行演示。

1. sql

DROP TABLE IF EXISTS `role`;
CREATE TABLE `role`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO `role` VALUES (1, '测试角色1');
INSERT INTO `role` VALUES (2, '角色2');
INSERT INTO `role` VALUES (3, '青山');

2. Mapper

public interface RoleMapper extends BaseMapper<Role> {

    @Select("SELECT r.* FROM role r where r.id = #{id} and r.name = #{name}")
    public List<Role> getRole(Long id, String name);

    @Select("SELECT r.* FROM role r where r.id = #{id}")
    public List<Role> getRole(Long id);
}

3. 测试类

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MapperTest {

    @Autowired
    private RoleMapper roleMapper;

    @Test
    public void TestMapper() {
        List<Role> list= roleMapper.getRole(3l);
        List<Role> list2 = roleMapper.getRole(3l, "青山");
        System.out.println(list);
        System.out.println(list2);
    }

}

4.结果

在这里插入图片描述
从结果上看我们发现,只有传入两个参数的方法才是执行成功的。

二、问题分析

1.通过查看执行sql

  • 单个参数的sql执行情况
    在这里插入图片描述
  • 多参数的sql执行情况
    在这里插入图片描述
    从结果上看,虽然mapper接口确实对sql进行重载,编译也顺利通过,但是最终执行的还是Mapper中第一个被写入的方法。之后经过将mapper的两个方法顺序调换,都是调用的单参数sql的方法

2. 查看源码

在通过debug断点执行的时候,在MapperMethod类中发现了executeForMany方法(这个方法是mapper代理查询集合的最终执行目标),
executeForMany代码如下(示例):

 private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
        List<E> result;
        Object param = method.convertArgsToSqlCommandParam(args);
        if (method.hasRowBounds()) {
            RowBounds rowBounds = method.extractRowBounds(args);
            result = sqlSession.selectList(command.getName(), param, rowBounds);
        } else {
        	// 重点行 command ,command.getName()的值为全称方法名:com.mapper.RolerMapper.getRole,不包含参数列表
            result = sqlSession.selectList(command.getName(), param);
        }
        if (!method.getReturnType().isAssignableFrom(result.getClass())) {
            if (method.getReturnType().isArray()) {
                return convertToArray(result);
            } else {
                return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
            }
        }
        return result;
    }

在这里插入图片描述
结果从mapper的代理对象选择sql的方式就可以看出来,mapper在执行接口方法的时候是不管重载方法的参数列表以及返回列表,因此对于mybatis来说也就不存在重载了。


总结

  1. Mybatis不支持方法重载,但是java本身是一定支持重载的。
  2. Mybatis获取执行方法是同一个key从内存在获取的,key的结构为包名.方法名,不包括方法参数列表方法返回值
  3. Mybatis的这种方式应该和mapper的扫描和生成mapper代理的方式有关,需要研究
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值