第一节中,分析了Mybatis的ORM框架的初始化,这篇来分析SQL执行过程中,对象->SQL是如何转换的

  其中包含两种映射思想

  ①DAO接口->Mapper实例

  ②执行DAO的方法时,参数->SQL的转换

  • DAO接口如何转变成具体可执行SQL的Mapper

   我们在使用mybatis的时候,Mapper会设置命名空间。

<mapper namespace="org.mybatis.example.mapper.MybatistestMapper">

 Java对象的DAO接口声明如下:

 package org.mybatis.example.mapper;

 import java.util.List;
import org.mybatis.example.model.Mybatistest; public interface MybatistestMapper {

  从包结构以及命名分析,Dao接口与Mapper有关系(XML 以及Mapper对象)

  在不使用Spring的时候,mybatis通过sqlSession.getMapper(MybatistestMapper.class) 来获得DAO-Mapper代理代理类。

  查看SqlSession的默认实现类DefaultSqlSession.getMapper(),通过configuration得到Mapper

  @Override
public <T> T getMapper(Class<T> type) {
return configuration.<T>getMapper(type, this);
}

  查看Configuration.getMapper

  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}

  继续查看mapperRegistry.getMapper。可以得到以下信息

  ①创建Mapper的工厂被缓存在knownMappers

   如果工厂不存在,则报错。查看代码,工厂是在XMLMapperBuilder解析Mapper时候添加进去的。

   根据Mapper.xml中的namespace,缓存Factory。有个好处。对获取的DaoMapper需要在配置文件中配置过。限定了使用范围。也避免后期执行时候出错。

   代码可自行查找源码

  ②当缓存中不存在时,则创建动态代理MapperProxyFactory.newInstance

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

mapperProxyFactory.newInstance

  @SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
} public T newInstance(SqlSession sqlSession) {
  //代理类中实际执行操作的代码
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}

  通过以上步骤,我们找到了Dao接口的实现(Mapper 实例接口)

  • 当调用一个DAO接口中的方法时,如何找到SQL以及转化为SQL的?.

  通过上面的代码,可以得知实际执行SQL的是mapperProxy 代理类

  看下mapperProxy 的invoke方法

  @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
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);
}
final MapperMethod mapperMethod = cachedMapperMethod(method);   //通过MapperMethod执行
return mapperMethod.execute(sqlSession, args);
}

查看MapperMethod的execute方法

public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
switch (command.getType()) {
case INSERT: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.insert(command.getName(), param));
break;
}
case UPDATE: {
Object param = method.convertArgsToSqlCommandParam(args);
     //实际找到SqlSession的update方法。command.getName()是Mapper的Id
result = rowCountResult(sqlSession.update(command.getName(), param));
break;
}

  到此为止,我们只是找到了要执行的SQL。由SqlSession来执行。

  

  

  

     

mybatis关于ORM的使用以及设计(二)[DaoInterface 转换 Mapper代理对象]的更多相关文章

  1. springboot集成下,mybatis的mapper代理对象究竟是如何生成的

    前言 开心一刻 中韩两学生辩论. 中:端午节是属于谁的? 韩:韩国人! 中:汉字是谁发明的? 韩:韩国人! 中:中医是属于谁的? 韩:韩国人! 中:那中国人到底发明过什么? 韩:韩国人! 前情回顾 M ...

  2. Mybatis源码解析 - mapper代理对象的生成,你有想过吗

    前言 开心一刻 本人幼教老师,冬天戴帽子进教室,被小朋友看到,这时候,有个小家伙对我说:老师你的帽子太丑,赶紧摘了吧.我逗他:那你好好学习,以后给老师买个漂亮的?这孩子想都没想立刻回答:等我赚钱了,带 ...

  3. mybatis关于ORM的使用以及设计(三)[参数对象转换为SQL语言]

    上节分析了Mapper对象的创建. 在ORM的定义中可以理解为Object->SQLMapper抽象层(这一层并不负责具体的SQL执行.这一层可以理解为SQL代理层) 本节分析以下内容: ①Sq ...

  4. mybatis关于ORM的使用以及设计(一)[ORM的初始化]

    ORM WIKI中的解释.画重点 Object-relational mapping (ORM, O/RM, and O/R mapping tool) in computer science is ...

  5. mybatis入门基础(二)----原始dao的开发和mapper代理开发

    承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...

  6. Mybatis学习总结(二)——Mapper代理开发

    一.概要 1.原始DAO开发中存在的问题:(1)DAO实现方法体中存在很多过程性代码.(2)调用SqlSession的方法(select/insert/update)需要指定Statement的id, ...

  7. Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6869133.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)——My ...

  8. Spring + Mybatis - 原始dao开发整合 与 Mapper代理整合

    Spring + Mybatis - 原始dao开发整合 与 Mapper代理整合 标签: mybatisSpringbeanApplicationContextMapper 2015-12-31 1 ...

  9. 【mybatis深度历险系列】深入浅出mybatis中原始dao的开发和mapper代理开发

    使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.mybatis在进行dao开发的时候,涉及到三姐妹,分别是SqlSessionFactoryBuilder ...

随机推荐

  1. WEB学习笔记3-开发环境和工具

    WEB前端集成开发环境:Aptana Studio和WebStormWEB前端代码调试:IE浏览器自带的IE Dev Toolbar,Chrome浏览器自带的Developer Tools,Firef ...

  2. 在虚拟机上利用宿主机共享目录编译linux程序

    #前提条件: 宿主机:windows7 虚拟机:REDHAT 开发环境 qt4.7.4 +vs2010 . 代码在windows7 上编译成功 ,运行正常 在linux下编译需要的第三方库已经编译成功 ...

  3. Linux报错之ping: www.baidu.com: Name or service not known

    Linux报错之ping: www.baidu.com: Name or service not known 出现这个以后,首先去ping下主机Ip,发现能ping通,但是出现另一个问题Destina ...

  4. Javascript仿贪吃蛇出现Bug的反思

    bug现象:    图一

  5. Windows Essentials Movie Maker 安装失败报错 ——问题解决

    Windows Essentials Movie Maker 安装失败报错: (软件包名: wlsetup-all.exe) 查到官方论坛给出了一些回复: https://social.technet ...

  6. 软件测试2019:第四次作业—— 性能测试(含JMeter实验)

    题目:性能测试练习 一.回答下述问题: 性能测试有几种类型,它们之间什么关系? 性能测试根据不同测试目的可以分为以下类: (1)性能验证测试 (2)性能基准测试 (3)性能规划测试 (4)容量测试 渗 ...

  7. 查看win10系统产品密钥

    查看win10系统产品密钥 1.win+R 输入Regedit运行注册表 2.找到(在HKEY_LOCAL_MACHINE–>SOFTWARE–>Microsoft–>Windows ...

  8. js数组遍历方法总结

    数组遍历方法 1.for循环 使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显. 1 2 3 for(j = 0,len=arr.length; j < le ...

  9. Spring mvc后台重定向页面,实际前端不跳转

    1.ajax不支持重定向 ajax是不支持重定向的,因为ajax本身就是局部刷新,不重新加载页面的. 2.若后台出现需要重定向页面,可以设置唯一错误码 前端ajax公共调用后,凡是遇到这一类错误码,则 ...

  10. 【学习】C++多态机制

    多态:静态(早绑定) 在编译阶段和链接就能确定功能调用的函数.     动态(晚绑定) 在程序运行时根据需要的功能确定调用的函数. 实现晚绑定就要定义虚函数,使用虚函数则会用到基类指针. 继承基类虚成 ...