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接口声明如下:

1 package org.mybatis.example.mapper;
2
3 import java.util.List;
4 import org.mybatis.example.model.Mybatistest;
5
6 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来执行。

  

  

  

     

原文地址:https://www.cnblogs.com/marioS/p/10300413.html

时间: 2024-08-02 22:29:03

mybatis关于ORM的使用以及设计(二)[DaoInterface 转换 Mapper代理对象]的相关文章

mybatis关于ORM的使用以及设计(一)[ORM的初始化]

ORM WIKI中的解释.画重点 Object-relational mapping (ORM, O/RM, and O/R mapping tool) in computer science is a programming technique for converting data between incompatible type systems using object-oriented programming languages. This creates, in effect, a

Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发(转发同上)

前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)--MyBatis的基础知识.MybatisFirst中存在大量重复的代码.这次简化下代码: 原地址:http://www.cnblogs.com/shanheyongmu/p/7121016.html 使用MyBatis开发Dao,通常有两种方法,即原始Dao开发方法和Mapper接口开发方法. 1.SqlSession使用范围 1.1 SqlsessionFactoryBuilder 通过SqlSessionFac

Mybatis中Mapper代理形式开发与spring整合

1.导入jar包 2.分包 cogfig:存放配置文件 mapper:存放映射与接口 pojo:存放实体类 test:测试代码 3.编写配置文件 SqlMapConfig.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybat

【MyBatis学习04】mapper代理方法开发dao

上一篇博文总结了mybatis使用 原始dao的方法存在的一些弊端,我们肯定不会去用它,那么mybatis中该如何开发dao呢?如题所述,这篇博文主要来总结一下使用mapper代理的方法来开发dao的步骤. 使用mapper代理的方法来开发dao时,程序员只需要干两件事即可: 需要编写mapper.xml映射文件 需要编写mapper接口(相当于dao接口) 从做的工作来看,使用mybatis中使用mapper代理来开发dao会很方便,完全不需要我们去写具体的实现类,只需要写出接口即可,但是接口

Mybatis 和Spring整合之mapper代理开发

F:\1ziliao\mybatis\代码 1.1 SqlMapConfig.xml <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <conf

Mybatis获取代理对象

mybatis-config.xml里标签可以放置多个environment,这里可以切换test和develop数据源 databaseIdProvider提供多种数据库,在xml映射文件里选择databaseId即可使用对应的数据库 Oracle的自增是使用Sequence实现的,若要获取插入数据的主键,在xml映射里写上selectKey标签,select seq.nextval from dual; 哪些地方不能使用占位符?比如分表时表名,orderby,desc @Mapkey("id

[simple-orm-mybaits]基于Mybatis的ORM封装介绍

目录 前言 ORM框架现状 Mybatis优缺点 simple-orm-mybatis设计思路介绍 simple-orm-mybatis使用说明 simple-orm-mybatis实际使用 推荐最佳实践 更多说明 simple-orm-mybatis在github开源,直接跳转查看,欢迎大家fork和star.有什么建议也可以提出,我会尽快修复或实现. 前言 最早接触Java的web开发框架就是SSH,其中的H就是Hibernate.Hibernate作为最出名的Java的ORM框架,现在的版

ORM表之间高级设计

ORM表之间高级设计 一.表的继承 # db_test1 # 一.基表 # Model类的内部配置Meta类要设置abstract=True, # 这样的Model类就是用来作为基表 # 多表:Book,Publish,Author,AuthorDetail class BaseModel(models.Model): # 实现表公共字段的继承 create_data = models.DateTimeField(auto_now_add=True) is_delete = models.Boo

justinmind夜话:数据母板系列视频教程之原型设计二十一条军规

案例描述:使用数据母板实现原型设计二十一条军规 知识点: 数据母板 效果图: 本站在线效果预览:(原型文件) 原型下载地址:数据母板原型设计二十一条军规 .vp  数据母板原型设计二十一条军规.html 在线视频: 实现步骤: