MyBatis源码解析之Mapper方法调用过程

本文深入解析了MyBatis中Mapper方法的调用过程,从SqlSession的getMapper()开始,通过MapperProxy的动态代理执行MapperMethod的invoke()方法。MapperMethod封装了Mapper接口方法信息,并利用SqlCommand解析SQL语句类型和Mapper ID,同时MethodSignature处理方法签名,包括参数名和注解。整个流程展示了MyBatis如何通过动态代理将Mapper方法映射到SqlSession的操作上,实现数据库交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MyBatis源码解析之Mapper方法调用过程

在此声明,此文章是对江荣波老师的《MyBatis3源码深度解析》的总结,尊重原作者。

分析过程

这里我们介绍Mapper方法的执行过程以及Mapper接口与Mapper SQL配置是如何关联的。

  1. 首先我们需要调用SqlSession对象的getMapper()获取一个动态代理对象MapperProxy,然后通过代理对象调用方法即可。

     // MapperRegistry类,根据Mapper接口Class对象获取Mapper动态代理对象
      @SuppressWarnings("unchecked")
      public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
         
        final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
        if (mapperProxyFactory == null) {
         
          throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
        }
        try {
         
          return mapperProxyFactory.newInstance(sqlSession);
        } catch (Exception e) {
         
          throw new BindingException("Error getting mapper instance. Cause: " + e, e);
        }
      }
      //测试类
      @Test
      public  void testMybatis () throws IOException {
         
         // 获取配置文件输入流
         InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
         // 通过SqlSessionFactoryBuilder的build()方法创建SqlSessionFactory实例
         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
         // 调用openSession()方法创建SqlSession实例
         SqlSession sqlSession = sqlSessionFactory.openSession();
         // 获取UserMapper代理对象
         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
         // 执行Mapper方法,获取执行结果
         List<UserEntity> userList = userMapper.listAllUser();
         /*
         // 兼容Ibatis,通过Mapper Id执行SQL操作
         List<UserEntity> userList = sqlSession.selectList(
                 "com.blog4java.mybatis.com.blog4java.mybatis.example.mapper.UserMapper.listAllUser");
         */
         System.out.println(JSON.toJSONString(userList));
     }  
    
  2. MapperProxy是一个动态代理对象,实现了InvocationHandler接口,用于实现动态代理相关逻辑。当我们调用动态代理对象的方法时,会执行MapperProxy的invoke()方法。

      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         
        try {
         
          // 从Object类继承的方法不做处理
          if (Object.class.equals(method.getDeclaringClass())) {
         
            return method.invoke(this, args);
          } else if (isDefaultMethod(method)) {
         
            return invokeDefaultMethod(proxy, method, args);
          }
        } catch (Throwable t) {
         
          throw ExceptionUtil.unwrapThrowable(t);
        }
        // 对Mapper接口中定义的方法进行封装,生成MapperMethod对象
        final MapperMethod mapperMethod = cachedMapperMethod(method);
        return mapperMethod.execute(sqlSession, args);
      }
    
    
  3. 在invoke()方法中,对Mapper接口定义的方法,调用cachedMapperMethod()方法获取一个MapperMethod对象,这里用到了设计模式的享元模式思想,首先从缓存中获取一个需要的对象,没有的话就创建一个,然后加入到缓存中。

      private Mappe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值