`
king_tt
  • 浏览: 2233051 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

}


分享到:
评论

相关推荐

    Spring整合Mybatis与SpringBoot整合Mybatis原理分析

    **Spring整合Mybatis原理分析** 在Java Web开发中,Spring框架以其强大的依赖注入和面向切面编程能力,成为了事实上的核心框架。Mybatis则是一个轻量级的持久层框架,它简化了数据库操作,提供了直观的SQL映射。将...

    深入浅出MyBatis技术原理与实战

    《深入浅出MyBatis技术原理与实战》这本书旨在为Java开发者提供MyBatis框架的全面理解...通过学习,你不仅可以掌握MyBatis的基本用法,还能提升对数据库操作和Java编程的理解,为你的软件开发生涯增添一份强大的工具。

    深入理解mybatis原理

    为了适应面向接口编程的趋势,MyBatis提供了第二种交互方式,即使用Mapper接口。在MyBatis配置文件中,每一个节点对应一个Mapper接口,这个接口声明的方法名称和参数类型与配置文件中|update|delete|insert&gt;节点项相...

    深入浅出MyBatis技术原理与实战(高清带书签)

    《深入浅出MyBatis技术原理与实战》是一本针对Java开发者深度解析MyBatis框架的专业书籍。MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射,旨在简化Java开发中的数据库操作。这本书通过理论...

    mybatis源码分析

    MyBatis是一个流行的Java持久层框架,它简化了数据库操作,通过XML或注解的方式将SQL与Java代码绑定,提供了一种动态SQL的解决方案。在深入理解MyBatis的源码之前,我们需要先了解其核心概念和功能。 1. SQL映射...

    mybatis笔记一对应代码

    【标题】"mybatis笔记一对应代码"涵盖了MyBatis框架的基础使用和核心概念,这是一份关于如何在实际开发中应用MyBatis的详细笔记。MyBatis是一款优秀的持久层框架,它允许开发者将SQL语句直接写在XML配置文件或者注解...

    MyBatis 中文帮助文档以及MyBatis包

    阅读《MyBatis 3 User Guide Simplified Chinese.pdf》和《MyBatis3用户指南中文版.pdf》这两份文档,开发者可以深入理解MyBatis的工作原理,掌握其配置、使用和优化技巧,从而在项目开发中得心应手地运用这一强大的...

    mybatis-3.2.2-src.rar 源码

    通过深入研究Mybatis 3.2.2的源码,开发者可以了解到其内部的工作原理,提升自己的编程技能,也能更好地理解和解决在实际开发中遇到的问题。源码阅读可以让你看到Mybatis是如何优雅地处理ORM,如何实现SQL的动态生成...

    mybatis-3.5.9 源码(mybatis-3-mybatis-3.5.9.tar.gz)

    源码分析这部分,可以理解到 MyBatis 如何利用 Java 的反射和动态代理技术来实现这一特性。 4. **Executor**:执行器是 MyBatis 的心脏,它负责执行 SQL 语句。Executor 分为 SimpleExecutor、ReuseExecutor 和 ...

    mybatis项目练习及流程文档

    MyBatis是一个优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC...实践中,尝试创建一个简单的CRUD操作,理解每个步骤的作用,这将有助于你更好地理解MyBatis的工作原理。

    mybatis-3.4.1源码

    通过研究其源码,开发者可以深入理解MyBatis的工作原理,提高编程技能,并优化自己的应用。 在MyBatis 3.4.1源码中,我们可以关注以下几个核心知识点: 1. **SqlSessionFactoryBuilder**: 这是创建...

    mybatis-3-mybatis-3.4.1源码

    通过对MyBatis源码的阅读和分析,开发者能够深入理解数据库操作的底层细节,提高编程效率,同时也能更好地应对性能优化、异常处理和扩展需求。对于任何想成为优秀Java开发者的程序员来说,研究MyBatis源码都是一个...

    mybatis架包与源码

    "源码"部分则是MyBatis的Java源代码,深入研究源码可以帮助我们了解MyBatis的工作原理,如: 1. **SqlSession的实现**:查看SqlSession是如何管理数据库连接和事务的。 2. **Executor的实现**:分析不同类型的...

    mybatis项目

    本项目结合MySQL数据库,将提供一个完整的实践环境,帮助学习者从实际操作中理解MyBatis的工作原理和用法。通过这个项目,你可以深入学习如何在Java应用中集成MyBatis,实现数据持久化的高效处理。

    mybatis-3.2.8 java api

    MyBatis Generator是一个代码生成工具,能够自动生成Java模型类、Mapper接口和XML映射文件,基于数据库表结构。这极大地提高了开发效率。 **9. 源码分析** `mybatis-3.2.8-sources.jar`文件包含MyBatis框架的源代码...

    mybatis3.4.1jar包和源码

    通过分析源码,你可以深入理解MyBatis的工作原理,例如如何解析XML配置文件,如何执行SQL,以及如何处理结果集。此外,对于自定义拦截器、动态SQL等功能的实现,源码也会提供宝贵的参考。 总之,MyBatis 3.4.1的jar...

    spring+mybatis开发实战

    5. **Mybatis的缓存机制**:分析Mybatis的一级和二级缓存,以及如何自定义缓存策略。 6. **Mybatis与Spring的整合**:展示如何在Spring中配置Mybatis,实现DataSource、SqlSessionFactoryBean等的集成。 此外,书中...

    mybatis-3.4.4

    而源代码压缩包则提供了MyBatis框架的所有源码,这对于学习和理解MyBatis的工作原理、进行自定义扩展或者排查问题非常有帮助。 MyBatis的主要特点包括: 1. **动态SQL**:MyBatis允许在映射文件中编写动态SQL,...

    逆向工程mybatis-generator-1.3.2

    MyBatis Generator(MBG)是一个强大的工具,能够自动生成MyBatis接口和映射器XML文件,以及Java实体类,从而减轻开发人员的手动编码工作。 MyBatis Generator的核心功能是通过解析数据库表结构,自动生成与之对应...

    第一个mybatis.zip

    - MyBatis的缓存机制:MyBatis提供了本地缓存和二级缓存,理解它们的工作原理并能灵活运用。 - MyBatis与Spring的整合:学习如何在Spring框架中集成MyBatis,实现依赖注入,简化配置。 - MyBatis的扩展:如自定义...

Global site tag (gtag.js) - Google Analytics