mybatis-5 手寫代理

 

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

  

public interface UserDao {

    @Select("select * from t_user where tid = #{i}")
    public List<Map> query(int i);
}

  

public class UserDaoInvocationHandle implements InvocationHandler {

    public SqlSession sqlSession;

    public UserDaoInvocationHandle(SqlSession sqlSession){
        this.sqlSession = sqlSession;

    }
    //使用管理者返回方法返回返回值
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(args);
    }
}

  

public class Test {

    public static void main(String args[]){

        //模擬
        try {
            init();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //創建sqlSession
        SqlSession sqlSession = GetSqlSession.getSqlSession();

        //創建Handle
        UserDaoInvocationHandle h = new UserDaoInvocationHandle(sqlSession);

        //使用jdk代理 1ClassLoader 2Class[] 3Handle
        UserDao ud =(UserDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(),new Class[]{UserDao.class},h);

        //此時的ud就是由JDK代理得到的代理class
        System.out.println(mapperStatement);
        //當使用ud.query()方法的時候,就是將ud的class路徑+名字+方法的名字當做參數去mapperStatement裏面獲取到sql
        //再由Executor去執行sql語句並返回結果,其中mybatis還有緩存機制,會將sql語句當做緩存的id保存結果。
    }

    public static Map<String,String> mapperStatement = new HashMap<String, String>();
    /**
     * 模擬初始化將Mapper.xml中命名空間和方法名字當作kay,sql語句當作value保存到MapperStatement中(請回顧mybatis-4中總結的初始化)
     * 初始化信息(數據庫連接信息,掃描mapper包中的class用於創建bean對象,spring中的類applicationFactory用於創建變對象、mapper中的xml的id與sql放到MapperStatement對象中)
     *       其中對於掃描mapper包中的class路徑+參數basePackages轉成文件夾,然後循環找到所有的類名,使用.......(請看MapperScannerRegistrar引出的doScan方法)
     * */
    public static void init() throws ClassNotFoundException {
       Class clazz =  Class.forName("com.dao.UserDao");
       Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            //判斷UserDao中是否存在Select類的註解
            if(method.isAnnotationPresent(Select.class)){
                //將獲取這個註解類
                Select select = method.getAnnotation(Select.class);
                //這裏獲取的是java.dao.UserDao.query
                String key = method.getDeclaringClass().getName()+"."+method.getName();
                //這裏最終實現的就是啓動的時候將命名空間和方法名當作key使用,SQL語句當作Value
                mapperStatement.put(key,select.value());
            }
        }
    }
}

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章