mybatis::SQL执行流和动态代理


sql执行流

image.png

mapper 动态代理

image.png

简单摘要一下mybatis,mapper接口到方法执行的代理实现

  • 模拟几个注解 Insert Update Select
package test.myproxy.mockframework;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Insert {
    public abstract String[] value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Select {
    public abstract String[] value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Update {
    public abstract String[] value();
}
  • 动态代理
  • 1.MapperProxy
public class MapperProxy implements InvocationHandler {

    private String method;
    private Class target;
    private String methodType;
    private String sql;

    public static <T> T newMapperProxy(Class<T> mapperInterface) {
        ClassLoader classLoader = mapperInterface.getClassLoader();
        Class[] interfaces = new Class[]{mapperInterface};
        MapperProxy proxy = new MapperProxy();

        return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy);
    }

    private String judgeMethodType(Method method) {
        String[] value = method.getAnnotation(Insert.class).value();

        if(method.isAnnotationPresent(Insert.class))
        {
            sql = value[0];
            return methodType="insert";
        }else if(method.isAnnotationPresent(Update.class))
        {
            sql = value[0];
            return methodType="update";
        }else if(method.isAnnotationPresent(Select.class))
        {
            sql = value[0];
            return methodType="select";
        }

        return null;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] objects) throws Throwable {
        System.out.println(" =====被代理了====此处可以做些aop类的事情=====");

        judgeMethodType(method);
        if(null==methodType)
        {
            System.out.println("unknow method  drop this process");
            return null;
        }
        MapperMethod mapperMethod = new MapperMethod(sql);
        mapperMethod.execute(methodType);

        System.out.println(" =====代理执行结束=====");
        return null;
    }
}
  • 2.MapperMethod
public class MapperMethod {
    private String sql;

    public MapperMethod() {
    }

    public MapperMethod(String sql) {
        this.sql = sql;
    }

    /**
     * @param methodType
     * @return
     */
    public Object execute(String methodType) {

        if (null != sql) {
            System.out.println("SQL:::" + sql);
        }

        if ("insert".equals(methodType)) {
            System.out.println("insert  获取sql和参数,合成sql 交给下游executor执行");
        } else if ("update".equals(methodType)) {
            System.out.println("update  获取sql和参数,合成sql 交给下游executor执行");
        } else if ("delete".equals(methodType)) {
            System.out.println("delete 获取sql和参数,合成sql 交给下游executor执行");
        } else {
            System.out.println("unkonw method type");
        }
        return null;
    }
}
  • 3.SqlSession
public class SqlSession {
    public <T> T getMapper(Class<T> clz){
        return MapperProxy.newMapperProxy(clz);
    }
}
  • 4.mapper
public interface BlogMapper {

    void delete();

    @Insert("insert into mytable")
    void insert();

    void update();

}
  • 5.Test
public class MyTestCase {

    @Test
    public void myTest() {
        SqlSession sqlSession = new SqlSession();
        BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
        blogMapper.insert();
    }
}
  • 6.输出
=====被代理了====此处可以做些aop类的事情=====
SQL:::insert into mytable
insert  获取sql和参数,合成sql 交给下游executor执行
 =====代理执行结束=====

上述代码纯属摘要模拟,不考虑鲁棒、安全和优雅

小结

  • 看码过程中,mybatis作者更加喜欢构造函数构建对象,和spring的setter注入主张各有千秋
  • 标准的动态代理,通过封装方法,使用更简单
    代码中还是有很多宝贝的,慢慢系统性的挖掘一下 😃
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值