-
Notifications
You must be signed in to change notification settings - Fork 45.8k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
更正:Dao 接口里的方法可以重载,但是Mybatis的XML里面的ID不允许重复! #1122
Comments
👍LGTM! |
答案讲了一半,还需要考虑 default method 的情况,下面分情况讨论。 Java 语法层面 JDK Proxy 是支持方法重载的,所以在 情况 1:在 MapperInterface 中的普通 interface method 这种情况下,不同的重载方法由于 从源码角度解读 // file => /org/apache/ibatis/binding/MapperProxy.java:92
private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
// ......
else {
return new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
}
// ......
}
// file => /org/apache/ibatis/binding/MapperMethod.java:224
public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {
// ......
MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass,
configuration);
// ......
}
// file => /org/apache/ibatis/binding/MapperMethod.java:254
private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName, Class<?> declaringClass, Configuration configuration) {
// 实际调试过程显示
// "cn.plusman.mybatis.mapper.BlogMapper" + "." + "selectBlog"
String statementId = mapperInterface.getName() + "." + methodName;
// 注意 statementId 里面是不带方法的参数类型的,所以到 MappedStatement 这里是不存在 Java 语法定义上的重载的。
} 情况 2:在 MapperInterface 中的 default mehtod public interface BlogMapper {
/**
* 根据 id 获取博客内容
* @param id
* @return
*/
Blog selectBlog(
int id
);
/**
* default method
* @return
*/
default Blog selectBlog() {
// 可以自定义一些业务逻辑逻辑,也可以理解成 mybatis 的一个拓展点
// some code
// 可以通过调用内部其他方法,返回真实数据
return this.selectBlog(12);
// 单元测试的时候,也可以返回 fake 数据
// return new Blog()
// .setBlogId(12)
// .setContent("hello world");
}
} 源码实现相对简单,跟踪如下 // file => /org/apache/ibatis/binding/MapperProxy.java:92
private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
// ......
// 判断是否是 default method
if (m.isDefault()) {
try {
if (privateLookupInMethod == null) {
return new DefaultMethodInvoker(getMethodHandleJava8(method));
} else {
return new DefaultMethodInvoker(getMethodHandleJava9(method));
}
} catch (IllegalAccessException | InstantiationException | InvocationTargetException
| NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
// ......
}
// file => /org/apache/ibatis/binding/MapperProxy.java:156
private static class DefaultMethodInvoker implements MapperMethodInvoker {
// 直接触发代理执行,无 MapStatement 绑定逻辑
@Override
public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
return methodHandle.bindTo(proxy).invokeWithArguments(args);
}
} |
本人也是测试过后,发现几个问题,这里其实并不是真正意义上的重载,楼主亲测的可行的重载方法,存在一个很大的问题,就是定义多个有参方法的时候,比如:
结论是:dao中的接口不可可以重载的。用注解的方式就会报Mapped Statements collection already contains value *** |
欢迎提交PR👍 |
说的对,其实这种用法是投机取巧,或者说钻了源码BUG的空子,生产这么用就是挖坑.... |
LGTM |
更正:Dao 接口里的方法可以重载,但是Mybatis的XML里面的ID不允许重复!
此处错误更正:
Dao 接口里的方法可以重载,但是Mybatis的XML里面的ID不允许重复。
Mybatis版本3.3.0,亲测如下:
然后在StuMapper.xml中利用Mybatis的动态sql就可以实现。
能正常运行,并能得到相应的结果,这样就实现了在Dao接口中写重载方法。
总结:
The text was updated successfully, but these errors were encountered: