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());
            }
        }
    }
}

  

 

posted @ 2019-04-14 20:38  为了WZJ  阅读(170)  评论(0编辑  收藏  举报