mybatis关于ORM的使用以及设计(二)[DaoInterface 转换 Mapper代理对象]
第一节中,分析了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代理对象]的更多相关文章
- springboot集成下,mybatis的mapper代理对象究竟是如何生成的
前言 开心一刻 中韩两学生辩论. 中:端午节是属于谁的? 韩:韩国人! 中:汉字是谁发明的? 韩:韩国人! 中:中医是属于谁的? 韩:韩国人! 中:那中国人到底发明过什么? 韩:韩国人! 前情回顾 M ...
- Mybatis源码解析 - mapper代理对象的生成,你有想过吗
前言 开心一刻 本人幼教老师,冬天戴帽子进教室,被小朋友看到,这时候,有个小家伙对我说:老师你的帽子太丑,赶紧摘了吧.我逗他:那你好好学习,以后给老师买个漂亮的?这孩子想都没想立刻回答:等我赚钱了,带 ...
- mybatis关于ORM的使用以及设计(三)[参数对象转换为SQL语言]
上节分析了Mapper对象的创建. 在ORM的定义中可以理解为Object->SQLMapper抽象层(这一层并不负责具体的SQL执行.这一层可以理解为SQL代理层) 本节分析以下内容: ①Sq ...
- mybatis关于ORM的使用以及设计(一)[ORM的初始化]
ORM WIKI中的解释.画重点 Object-relational mapping (ORM, O/RM, and O/R mapping tool) in computer science is ...
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...
- Mybatis学习总结(二)——Mapper代理开发
一.概要 1.原始DAO开发中存在的问题:(1)DAO实现方法体中存在很多过程性代码.(2)调用SqlSession的方法(select/insert/update)需要指定Statement的id, ...
- Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6869133.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)——My ...
- Spring + Mybatis - 原始dao开发整合 与 Mapper代理整合
Spring + Mybatis - 原始dao开发整合 与 Mapper代理整合 标签: mybatisSpringbeanApplicationContextMapper 2015-12-31 1 ...
- 【mybatis深度历险系列】深入浅出mybatis中原始dao的开发和mapper代理开发
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.mybatis在进行dao开发的时候,涉及到三姐妹,分别是SqlSessionFactoryBuilder ...
随机推荐
- zuul源码(2)
路由 路由是网关的核心功能,既然在spring的框架下,那就要按Spring的规矩来. 路由规则类:org.springframework.cloud.netflix.zuul.filters.Rou ...
- 并发编程心得--synchronized
根据业务需求解决并完善并发问题-- IWMS仓库系统不考虑并发那么大的情况下,我想到的有2种并发解决方案. 1.在同时请求时,给需要操作的保存接口添加synchronized 同步方式,同步保存方法, ...
- Maven&&Philosophy~
What is Maven? At first glance Maven can appear to be many things, but in a nutshell Maven is an att ...
- flask 图文混排的简单操作
1.引入js 包<script type="text/javascript" src="../../static/news/js/jquery-1.12.4.min ...
- 图解HTTP阅读笔记(1)-网络基础TCP/IP
1.TCP/IP协议族 TCP/IP这个概念对大家来说很熟悉,之前我的了解它只是一个协议.今天阅读才知道TCP/IP实际上是一个协议族,其中HTTP协议属于该协议族的一个子集.图1是TCP/IP协议族 ...
- js立即执行函数用法
js立即执行函数可以让你的函数在创建后立即执行,js立即执行函数模式是一种语法,可以让你的函数在定义后立即被执行,这种模式本质上就是函数表达式(命名的或者匿名的),在创建后立即执行. 一.JS立即执行 ...
- Restful levels&HATEOAS详解
RESTful: Rest是一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等 ...
- 2017 cinemachine
只有2017以上才可以使用~ 导入Asset store中的cinemachine,会在上方显示cinemachine.每创建一个虚拟摄像机,就会在主摄像机下创建组件 cinemachine Bra ...
- 防F12扒代码:按下F12关闭当前页面
只要按下那神秘的审查元素.按下那神秘的F12键,奇迹出现了!网站变成了空白页,可谓杀防君子放火必备佳品!一段JavaScript代码即可实现上述功能,插入到 footer.php 的 </bod ...
- redis key命令
key命令主要用于管理redis中的key del key //删除key, 不存在的key会忽略 dump key //序列化key,不存在的key返回nil exists key //判断key是 ...