Mybatis源码分析之存储过程调用

时间:2022-09-02 16:49:53

这一篇博客我们学习一下Mybatis调用存储过程的使用和运行流程。首先我们先创建一个简单的存储过程

DELIMITER $
CREATE PROCEDURE mybatis.ges_user_count(IN age INT, OUT user_count INT)
BEGIN
SELECT COUNT(*) FROM users WHERE users.age=age INTO user_count;
END
$

这个存储过程的含义其实比较简单的,就是输入age,然后执行select count(*) from users where users.age = age into user_count;获得年龄等于age的人数赋值给user_count,还是比较简单的。

接下来是存储过程的调用,执行如下命令就可以完成存储过程的调用。

Mybatis源码分析之存储过程调用

接下来我们看看利用Mybatis是如何调用存储过程的。

userMapper.xml添加存储过程调用配置:

<select id="count" statementType="CALLABLE" parameterMap="getUserCountMap">
      CALL mybatis.ges_user_count(?,?)
</select>

Main函数:

public class Learn1Main {

	public static void main(String [] args){

		//mybatis的配置文件
	    String resource = "learn/mybatis-config.xml";
	    //使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)
	    InputStream is = Learn1Main.class.getClassLoader().getResourceAsStream(resource);
	    //构建sqlSession的工厂
	    SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
	    SqlSession session = sessionFactory.openSession();
	    Map<String, Integer> parameterMap = new HashMap<String, Integer>();
	    parameterMap.put("age", 12);
	    parameterMap.put("user_count", -1);
	    session.selectOne("com.tianjunwei.learn.learn1.entity.User.count", parameterMap);
	    Integer result = parameterMap.get("user_count");
	    System.out.println(result);

	}
}

运行结果:

Mybatis源码分析之存储过程调用

其最终的执行过程在DefaultResultSetHandler中,调用普通的sql和存储过程之间还是有所区别的,Sql语句的执行是使用CallableStatement。

Mybatis源码之Statement处理器CallableStatementHandler(六)

  //
  // HANDLE OUTPUT PARAMETER
  //
  //调用存储过程返回结果,将结果值放在参数中
  @Override
  public void handleOutputParameters(CallableStatement cs) throws SQLException {
    final Object parameterObject = parameterHandler.getParameterObject();
    final MetaObject metaParam = configuration.newMetaObject(parameterObject);
    final List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
	//循环处理每个参数
    for (int i = 0; i < parameterMappings.size(); i++) {
      final ParameterMapping parameterMapping = parameterMappings.get(i);
	  //判断参数的模式
      if (parameterMapping.getMode() == ParameterMode.OUT || parameterMapping.getMode() == ParameterMode.INOUT) {
        if (ResultSet.class.equals(parameterMapping.getJavaType())) {
          handleRefCursorOutputParameter((ResultSet) cs.getObject(i + 1), parameterMapping, metaParam);
        } else {
          final TypeHandler<?> typeHandler = parameterMapping.getTypeHandler();
          metaParam.setValue(parameterMapping.getProperty(), typeHandler.getResult(cs, i + 1));
        }
      }
    }
  }

  private void handleRefCursorOutputParameter(ResultSet rs, ParameterMapping parameterMapping, MetaObject metaParam) throws SQLException {
    try {
      final String resultMapId = parameterMapping.getResultMapId();
      final ResultMap resultMap = configuration.getResultMap(resultMapId);
      final DefaultResultHandler resultHandler = new DefaultResultHandler(objectFactory);
      final ResultSetWrapper rsw = new ResultSetWrapper(rs, configuration);
      handleRowValues(rsw, resultMap, resultHandler, new RowBounds(), null);
      metaParam.setValue(parameterMapping.getProperty(), resultHandler.getResultList());
    } finally {
      // issue #228 (close resultsets)
      closeResultSet(rs);
    }
  }

Mybatis源码分析之存储过程调用的更多相关文章

  1. mybatis源码分析(方法调用过程)

    十一月月底,宿舍楼失火啦,搞得20多天没有网,目测直到放假也不会来了... 正题 嗯~,其实阅读源码不是为了应付面试,更重要的让你知道,大师是怎样去写代码的,同样是用Java,为啥Clinton Be ...

  2. MyBatis源码分析-MyBatis初始化流程

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...

  3. MyBatis源码分析-SQL语句执行的完整流程

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...

  4. MyBatis 源码分析 - 缓存原理

    1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...

  5. Mybatis源码分析

    MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...

  6. 精尽MyBatis源码分析 - MyBatis 的 SQL 执行过程(一)之 Executor

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  7. 精尽MyBatis源码分析 - SQL执行过程(二)之 StatementHandler

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  8. 精尽MyBatis源码分析 - SQL执行过程(三)之 ResultSetHandler

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  9. 精尽 MyBatis 源码分析 - SqlSession 会话与 SQL 执行入口

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

随机推荐

  1. Js扩展方法ReplaceAll

    String.prototype.replaceAll = function (reallyDo, replaceWith, ignoreCase) { if (!RegExp.prototype.i ...

  2. JS常见排序算法

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. 什么是Zookeeper,Zookeeper的作用是什么,在Hadoop及hbase中具体作用是什么

    什么是Zookeeper,Zookeeper的作用是什么,它与NameNode及HMaster如何协作?在没有接触Zookeeper的同学,或许会有这些疑问.这里给大家总结一下. 一.什么是Zooke ...

  4. Windows 中默认安装的&period;Net 版本

    Windows contains a version of .NET by default. Here's a listing of them. XP .NET v1.0 -- Service pac ...

  5. SQL Server 视图

    视图实际上就是一个存储查询,重点是是可以混合和匹配来自基本表(或者其他视图)的数据,从而创建在很多方面像另一个基表那样起作用的对象.可以创建一个简单的查询,仅仅从一个表中选择几列,而忽略其他列:或者也 ...

  6. ThinkPHP5&period;0版本和ThinkPHP3&period;2版本的区别

    5.0版本和之前版本的差异较大,本篇对熟悉3.2版本的用户给出了一些5.0的主要区别. URL和路由 5.0的URL访问不再支持普通URL模式,路由也不支持正则路由定义,而是全部改为规则路由配合变量规 ...

  7. Android ROM包定制(解包,增删模块,打包)

    1. 解包 假设有一个名为update.zip的ROM包,我们要在Ubuntu下对它进行定制.首先把system.transfer.list和system.new.dat.br(有些旧版的系统的镜像可 ...

  8. php 从2维数组组合为四维数组分析&lpar;项目中前台侧边栏导航三级分类显示&rpar;

    foreach函数(循环函数)内嵌套循环函数时,当内层完全循环完后,才会向上一级循环 数组要注意问题 array_merge----合并一个或多个数组 将一个或多个数组的单元合并起来,一个数组中的值附 ...

  9. 预备作业3:Linux安装及命令入门

    linux系统的安装 1.虚拟机: 首先是VirtualBox5.2.7的安装,这个按照老师给的基于VirtualBox安装Ubuntu图文教程一步步来很快就能安好,也没有遇到无法选择64-bit的问 ...

  10. pl&sol;sql 如何将Excel文件数据导入oracle的数据表?

    1.准备导入数据的excel文件 注意:excel列名和数据表列名必须相同,excel文件sheet2和sheet3可以删除 1)excel文件格式 2)数据表格式 2.打开pl/sql ,找到工具- ...