mybatis::SQL執(zhí)行流和動態(tài)代理

sql執(zhí)行流

image.png

mapper 動態(tài)代理

image.png

簡單摘要一下mybatis,mapper接口到方法執(zhí)行的代理實現(xiàn)

  • 模擬幾個注解 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();
}
  • 動態(tài)代理
  • 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(" =====代理執(zhí)行結束=====");
        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和參數(shù),合成sql 交給下游executor執(zhí)行");
        } else if ("update".equals(methodType)) {
            System.out.println("update  獲取sql和參數(shù),合成sql 交給下游executor執(zhí)行");
        } else if ("delete".equals(methodType)) {
            System.out.println("delete 獲取sql和參數(shù),合成sql 交給下游executor執(zhí)行");
        } 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和參數(shù),合成sql 交給下游executor執(zhí)行
 =====代理執(zhí)行結束=====

上述代碼純屬摘要模擬,不考慮魯棒、安全和優(yōu)雅

小結

  • 看碼過程中,mybatis作者更加喜歡構造函數(shù)構建對象,和spring的setter注入主張各有千秋
  • 標準的動態(tài)代理,通過封裝方法,使用更簡單
    代碼中還是有很多寶貝的,慢慢系統(tǒng)性的挖掘一下 :)
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容