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

      

  • 相关阅读:
    【题解】Luogu p2016 战略游戏 (最小点覆盖)
    【模板】Linux下输出文件的对比
    【题解】Luogu P3052 【USACO12】摩天大楼里的奶牛Cows in a Skyscraper
    【题解】滑雪 luogu1434 记忆化搜索
    【题解】Luogu P3110 [USACO14DEC]驮运Piggy Back
    【题解】Luogu P3123 [USACO15OPEN]贝茜说哞Bessie Goes Moo
    【题解】Luogu P2214 [USACO14MAR]哞哞哞Mooo Moo
    【题解】Luogu P2327 [SCOI2005]扫雷
    【题解】Luogu P1011 车站
    【题解】Luogu P2889 [USACO07NOV]挤奶的时间Milking Time
  • 原文地址:https://www.cnblogs.com/gnwzj/p/10706874.html
Copyright © 2020-2023  润新知