作为一款优秀的ORM框架,mybatis主要完成的工作可以归纳为一下几点:
1 抽象方法和数据操作节点的映射,在调用抽象方法时执行数据操作节点操作完成SQL的执行
2 抽象方法上的参数和SQL语句里面参数的映射
3 SQL返回结果和抽象方法返回对象的映射
Java是不能使用接口或者抽象类创建实例对象的,那么当我们调用接口中的方法时,实际上是由谁来执行这个方法的呢 ?
其实,mybatis使用的JDK的动态代理实现的,最终执行接口中的抽象方法的是由mybatis创建的代理对象来执行的。
今天我在这里简单的分析一下
在执行 sqlSession.getMapper(DevQuestionDao.class) 这句时,mybatis做的工作。
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
// 这里完成了mybatis所有的配置文件的解析工作 如:数据库的链接 对象关系映射等工作
SqlSessionFactory factory = factoryBuilder.build(reader);
今天简单的分析一下 下面这句代码的流程
DevQuestionDao questionDao = sqlSession.getMapper(DevQuestionDao.class);
DefaultSqlSqlsession 这个对象中会存放整个xml文件解析的对象 Configuration
DefaultSqlSqlsession.getMapper(Class<T> type); 这个方法中会执行
Configuration.getMapper()方法 如下所示:
public <T> T getMapper(Class<T> type, SqlSession sqlSession) { return this.mapperRegistry.getMapper(type, sqlSession); } MapperRegistry 中 public <T> T getMapper(Class<T> type, SqlSession sqlSession) { MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type); if (mapperProxyFactory == null) { throw new BindingException("Type " + type + " is not known to the MapperRegistry."); } else { try { // 这里就创建了代理对象 return mapperProxyFactory.newInstance(sqlSession); } catch (Exception var5) { throw new BindingException("Error getting mapper instance. Cause: " + var5, var5); } } }
所以从上面的代码可以看出 最终代理类 是执行的 MapperProxy 类的 invoke 方法 ,来完成数据库的操作