mybatis#mapper原理

mapper是比较神奇的东西,通过一个接口,不写实现类,就可以完成sql语句的执行。

通过对jdk的动态代理进行学习,开始明白了其中的原理。

一个demo:

文件1:Subject.java 对应的就是XxMapper.java

public interface Subject {
    void hello(String name);
}
View Code

文件2:SubjectProxy.java 对应的就是 MapperProxy.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class SubjectProxy implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("hello world " + args[0]);
        // System.out.println(method.getDeclaringClass().getName()+"."+method.getName());
        return null;
    }
}
View Code

文件3:Client.java 对应的就是 平时使用XxMapper接口的地方

import java.lang.reflect.Proxy;

public class Client {
    public static void main(String[] args) {
        SubjectProxy proxy = new SubjectProxy();
        Subject sub = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(), new Class[]{Subject.class}, proxy);
        sub.hello("kitty");
    }
}
View Code

执行结果:


---------------------------------------------------------------------
再SpringBoot中,Spring框架会自动生成Mapper的代理,是MapperProxy<T>的实例,
其中的invoke方法会拦截,对mapper.方法的调用。
然后会执行关键代码:
MapperMethod mapperMethod = this.cachedMapperMethod(method);
return mapperMethod.execute(this.sqlSession, args);


因为Mapper接口的包名,和XxMapper.xml的命名空间一致,
Mapper接口中的方法名称又和,XxMapper.xml中的sql的id一致,
在MapperProxy中,又会把调用mapper接口的参数也拿到;
于是在MapperMethod实例中,其实就是通过sqlSession对,数据库进行操作了。用到的是命令模式。

---------------------------------------------------------------------

大概也就是这个样子了,原来最终Mapper接口都没有实例。对动态代理也有一点点失望,失望来自于误解,
还以为会自动,的生成Mapper的实现,谁知只是张冠李戴。

猜你喜欢

转载自www.cnblogs.com/luohaonan/p/11671126.html