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 ...
随机推荐
- 使用Python画一个带坐标轴的圆
Download Microsoft Visual Studio Microsoft Visual Studio enables you develop your python Application ...
- ps 处理gif
ps打开gif后,做了修改(去掉了背景色),但之后发现本来是动图的gif不动了. 解决该问题需要注意两点: 一:保存时,要选择保存为web格式 二:在ps中打开时间轴,在时间轴中选中某一帧时,只能有多 ...
- SQL函数语句
MyBatis实现模糊查询 1.${-}代替#{-} 2.把'%#{name}%'改为"%"#{name}"%" 3.使用sql中的字符串拼接函数 4.使用标签 ...
- QT | 一些学习心得
1. 如何使控件随着窗口大小变化而自动填充? 选中控件中最外层的那个控件,如centralWidget(不要去选中内部的小控件,这样能够保证内部的相对位置) 然后对centralWidget选择布局方 ...
- 本地新建git仓库后与远端仓库关联
背景说明:如果你想把自己的一个项目开源到,需要新建一个本地代码仓库,然后与远端代码库建立关.不想使用git clone 命令去克隆远端新建代码仓库,然后再将我们写好的代码copy到克隆下来的文件夹里, ...
- easyui获取正在编辑行的代码
easyui获取正在编辑行的代码……没这个真不知道怎么搞0.0可能这问题还要弄半天……卧槽 ...等于是笔记下来 : var ed = $("dg").datagrid('get ...
- SQL SEVER 时间格式转换
常用:时分秒(HH:mm:ss):Select CONVERT(varchar(100), GETDATE(), 8) : 10:57:46年月日 (yyyyMMdd):Select CONVERT( ...
- 653. Two Sum IV - Input is a BST-easy
我不懂有没有收藏之类的功能,收藏别人的解法. tql,不懂为什么直接比较set里的值,不是两个数sum么 有一些答案都用到了iterator迭代器 http://www.cplusplus.com/r ...
- 中间件和Django缓存
中间件定义: 中间件是一个.一个的管道,如果相对任何所有的通过Django的请求进行管理都需要自定义中间件 中间件可以对进来的请求和出去的请求进行控制 中间件是一类. 看下面的代码在settings里 ...
- Python基础:八、python基本数据类型
一.什么是数据类型? 我们人类可以很容易的分清数字与字符的区别,但是计算机并不能,计算机虽然很强大,但从某种角度上来看又很傻,除非你明确告诉它,"1"是数字,"壹&quo ...