Mybatis接口编程原理分析(一)
Mybatis接口编程示例
(1)首先定义接口编程需要的接口及其方法
public interface IUserMapper { public User getById(int id);//接口方法,不需要实现 }
(2)创建mybatis的mapper文件,其中namespace的值为接口的完整类名
<mapper namespace="com.tianjunwei.learn.learn2.IUserMapper">//接口完整类名 <select id="getById" parameterType="int" resultType="com.tianjunwei.learn.learn1.entity.User"> select * from users where id=#{id} </select> </mapper>
(3)创建接口调用操作
public class Learn2Main { public static void main(String [] args){ String resource = "learn/mybatis-config.xml"; InputStream is = Learn1Main.class.getClassLoader().getResourceAsStream(resource); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is); SqlSession session = sessionFactory.openSession(); IUserMapper userMapper = session.getMapper(IUserMapper.class);//获取接口,已经是代理接口 userMapper.getById(1); RowBounds rowBounds = new RowBounds(2, 4);//接口分页编程 System.out.println(userMapper.page(rowBounds).size()); } }
Mybatis接口编程相关的类主要有MapperProxyFactory、MapperProxy、MapperMethod和MapperRegister四个类:
MapperProxyFactory:通过类名我们可以猜到这是一个MapperProxy的工厂类,用于创建MapperProxy的,通过函数newInstance(SqlSession sqlSession)来创建MapperProxy的代理类。
源码如下:
//这个类赋值创建具体mapper接口代理对象的工厂 public class MapperProxyFactory<T> { //具体Mapper接口的class对象 private final Class<T> mapperInterface; //该接口下面的缓存,key是方法对象,value是对接口中方法对象的封装 private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>(); public MapperProxyFactory(Class<T> mapperInterface) { this.mapperInterface = mapperInterface; } public Class<T> getMapperInterface() { return mapperInterface; } public Map<Method, MapperMethod> getMethodCache() { return methodCache; } @SuppressWarnings("unchecked") protected T newInstance(MapperProxy<T> mapperProxy) { //创建一个代理类并返回 return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy); } public T newInstance(SqlSession sqlSession) { //在这里创建MapperProxy对象,这个类实现了JDK的动态代理接口 InvocationHandler final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache); //调用上面的方法,返回一个接口的代理类 return newInstance(mapperProxy); } }
MapperProxy:通过类名可以猜到这个类为一个代理类,它实现了JDK动态代理接口InvocationHandler,通过查看源码发现它又不像一个真正的代理类,它一般不会真正执行被代理类的函数方法,只是在执行被代理类函数方法时来执行MapperMethod类的execute方法,具体逻辑详看invoke函数
源码如下:
//实现了JDK动态代理的接口,InvocationHandler //在invoke方法中实现了代理方法调用的细节 public class MapperProxy<T> implements InvocationHandler, Serializable { private static final long serialVersionUID = -6424540398559729838L; //sqlSession private final SqlSession sqlSession; //接口的类型对象 private final Class<T> mapperInterface; //接口中方法的缓存,由MapperProxyFactory传递过来 private final Map<Method, MapperMethod> methodCache; //构造函数 public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) { this.sqlSession = sqlSession; this.mapperInterface = mapperInterface; this.methodCache = methodCache; } //接口代理对象所有的方法调用都会调用该方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //判断是不是基础方法比如toString、hashCode等,这些方法直接调用不需要处理 if (Object.class.equals(method.getDeclaringClass())) { try { return method.invoke(this, args); } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } } //进行缓存 final MapperMethod mapperMethod = cachedMapperMethod(method); //调用mapperMethod.execute 核心的地方就在这个方法里,这个方法对才是真正对SqlSession进行的包装调用 return mapperMethod.execute(sqlSession, args); } //缓存处理 private MapperMethod cachedMapperMethod(Method method) { MapperMethod mapperMethod = methodCache.get(method); if (mapperMethod == null) { mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()); methodCache.put(method, mapperMethod); } return mapperMethod; } }
Mybatis接口编程原理分析(一)的更多相关文章
- Mybatis接口编程原理分析(三)
前面两篇博客Mybatis接口编程原理分析(一)和Mybatis接口编程原理分析(二)我们介绍了MapperProxyFactory.MapperProxy和MapperMethod的操作及源码分析, ...
- Mybatis接口编程原理分析(二)
在上一篇博客中 Mybatis接口编程原理分析(一)中我们介绍了MapperProxyFactory和MapperProxy,接下来我们要介绍的是MapperMethod MapperMethod:它 ...
- MyBatis整合Spring原理分析
目录 MyBatis整合Spring原理分析 MapperScan的秘密 简单总结 假如不结合Spring框架,我们使用MyBatis时的一个典型使用方式如下: public class UserDa ...
- MyBatis的深入原理分析之1-架构设计以及实例分析
MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构设计思路,并且讨论MyBatis的几个核心部件,然后结合一个select查询实例, ...
- MyBatis框架及原理分析
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 MyBatis的主要设计目的就 ...
- Linux下Golang Socket编程原理分析与代码实现
在POSIX标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带Runtime的跨平台编程语言,Go中提供给开发者的Socket API是建立在操作系统原生Socket ...
- Mybatis插件原理分析(三)分页插件
在Mybatis中插件最经常使用的是作为分页插件,接下来我们通过实现Interceptor来完成一个分页插件. 虽然Mybatis也提供了分页操作,通过在sqlSession的接口函数中设置RowBo ...
- mybatis(一、原理,一对多,多对一查询)
MyBatis框架及原理分析 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 ...
- Spark原理分析目录
1 Spark原理分析 -- RDD的Partitioner原理分析 2 Spark原理分析 -- RDD的shuffle简介 3 Spark原理分析 -- RDD的shuffle框架的实现概要分析 ...
随机推荐
- 原生js实现preAll和nextAll方法
一直以来都在好奇,jquery的prevAll和nextAll方法都是咋实现的,那么厉害,而且还那么方便.不得不说,jquery真的帮我们省去了开发中手写大量js代码带来的开发进度问题,而且很好的解决 ...
- VMware在宿主上没有VMnet0、VMnet8,解决方法
一开始,坐着上机实验,一直搞不通为什么虚拟机上的客户机可以ping通自己的ip也可以ping通自己本身的ip,但是主机ping不通虚拟机的客户机,也ping不通虚拟机的网关. 尝试了各种问题,也追出了 ...
- java连接sqlserver2008
java连接sqlserver2008时应有sqljdbc4.jar驱动包.连接的示例代码如下: import java.sql.*; public class ConnectSQL { public ...
- Bootstrap3 代码-变量
通过 <var> 标签标记变量. y = mx + b <var>y</var> = <var>m</var><var>x< ...
- Android仅2步实现 滚粗 汉堡导航栏效果~ 全新底部导航交互(滑动隐藏)
本文同步自wing的地方酒馆 布吉岛大家有木有看这一篇文章,再见,汉堡菜单,我们有了新的 Android 交互设计方案 本库下载地址:https://github.com/githubwing/Bye ...
- Bootstrap3 排版-对齐
通过文本对齐类,可以简单方便的将文字重新对齐. Left aligned text. Center aligned text. Right aligned text. Justified text. ...
- Bootstrap3 栅格系统-列偏移
使用 .col-md-offset-* 类可以将列向右侧偏移.这些类实际是通过使用 * 选择器为当前元素增加了左侧的边距(margin).例如,.col-md-offset-4 类将 .col-md- ...
- Apache Curator入门实战
Apache Curator入门实战 Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeep ...
- springMVC源码分析--ControllerBeanNameHandlerMapping(八)
在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...
- Python 文本转语音
文本转语音,一般会用在无障碍开发.下面介绍如何使用Python实现将文本文件转换成语音输出. 准备 使用Speech API 原理 示例代码 小总结 pyttsx方式 原理 示例代码 小总结 pytt ...