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接口编程原理分析(一)的更多相关文章

  1. Mybatis接口编程原理分析(三)

    前面两篇博客Mybatis接口编程原理分析(一)和Mybatis接口编程原理分析(二)我们介绍了MapperProxyFactory.MapperProxy和MapperMethod的操作及源码分析, ...

  2. Mybatis接口编程原理分析(二)

    在上一篇博客中 Mybatis接口编程原理分析(一)中我们介绍了MapperProxyFactory和MapperProxy,接下来我们要介绍的是MapperMethod MapperMethod:它 ...

  3. MyBatis整合Spring原理分析

    目录 MyBatis整合Spring原理分析 MapperScan的秘密 简单总结 假如不结合Spring框架,我们使用MyBatis时的一个典型使用方式如下: public class UserDa ...

  4. MyBatis的深入原理分析之1-架构设计以及实例分析

    MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构设计思路,并且讨论MyBatis的几个核心部件,然后结合一个select查询实例, ...

  5. MyBatis框架及原理分析

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 MyBatis的主要设计目的就 ...

  6. Linux下Golang Socket编程原理分析与代码实现

    在POSIX标准推出后,socket在各大主流OS平台上都得到了很好的支持.而Golang是自带Runtime的跨平台编程语言,Go中提供给开发者的Socket API是建立在操作系统原生Socket ...

  7. Mybatis插件原理分析(三)分页插件

    在Mybatis中插件最经常使用的是作为分页插件,接下来我们通过实现Interceptor来完成一个分页插件. 虽然Mybatis也提供了分页操作,通过在sqlSession的接口函数中设置RowBo ...

  8. mybatis(一、原理,一对多,多对一查询)

    MyBatis框架及原理分析 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 ...

  9. Spark原理分析目录

    1 Spark原理分析 -- RDD的Partitioner原理分析 2 Spark原理分析 -- RDD的shuffle简介 3 Spark原理分析 -- RDD的shuffle框架的实现概要分析 ...

随机推荐

  1. day06_JDBC学习笔记

    ============================================================ 一.JDBC概述 为什么要使用JDBC? JDBC:Java DataBase ...

  2. 更快实现Android多级树形选择列表

    快速实现Android多级树形列表,这个库是在鸿洋多级树形列表demo中修改而来. 解决的问题: 1. 支持ID为int类型和String类型. 2. 支持多级复选框选中,使用只需一行代码. 3. 支 ...

  3. ThreadLocal(线程绑定)

    为保证在DAO层里的操作都在同一事务里,我们曾使用以参数的形式将Connection向下传递的方式,而ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection ...

  4. Scala:函数式编程之下划线underscore

    http://blog.csdn.net/pipisorry/article/details/52913548 python参考[python函数式编程:apply, map, lambda和偏函数] ...

  5. ELK搭建

    ELK安装 elasticsearch安装 * 下载elasticsearch-5.0.0.tar.gz,并解压. 通过elasticsearch.yml可设置host和port. vim confi ...

  6. [Pelican]Pelican入门(一)

    听说这个静态博客很好用,最近又在协助"蟒周刊"翻译,于是先学习下基本的用法 office site You can startup for here. 安装环境 我的os是win7 ...

  7. java.util.Arrays类详解(源码总结)

    概述 Arrays类位于java.util包下,是一个对数组操作的工具类.今天详细的看了看Arrays类的4千多行源码,现将Arrays类中的方法做一个总结(JDK版本:1.6.0_34).Array ...

  8. Swift基础语法(常量变量、数据类型、元组、可选、断言)

    本文来自Swift中文开发组,感谢翻译者的分享. 本文将分几部分对Swift对ios的语法做讲解.本文为第一节,主要讲解基础语法. 常量和变量 常量和变量把一个名字(比如maximumNumberOf ...

  9. JQuery其他常用函数

    isArray(obj)                      检测obj否为一个数组对象 isFunction(obj)                 检测obj否为一个函数 isEmptyO ...

  10. Cocos2D在Xcode7和iOS 9.2上IMP调用出错

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 原来的代码一直在Xcode6.4上和iOS 8.4上运行,没有 ...