聊聊Mybatis的BaseStatementHandler的三个子类

Posted 周杰伦本人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊Mybatis的BaseStatementHandler的三个子类相关的知识,希望对你有一定的参考价值。

@[TOC]

聊聊Mybatis的BaseStatementHandler的三个子类

今天我们继续聊StatementHandler的实现类

PreparedStatementHandler

PreparedStatementHandler处理的是包含?占位符的sql语句,所以它需要进行参数绑定:

@Override
  public void parameterize(Statement statement) throws SQLException 
    parameterHandler.setParameters((PreparedStatement) statement);
  

我们通过parameterize()方法的实现就能看出,这个方法是设置参数的,而其他的方法和和StatementHandler整体差不多

SimpleStatementHandler

SimpleStatementHandler对没有占位符的sql语句的StatementHandler类,看一下它的update()方法的实现:

对于insert update delete语句都会执行这个方法

public int update(Statement statement) throws SQLException 
    String sql = boundSql.getSql();
    Object parameterObject = boundSql.getParameterObject();
    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
    int rows;
    if (keyGenerator instanceof Jdbc3KeyGenerator) 
      statement.execute(sql, Statement.RETURN_GENERATED_KEYS);
      rows = statement.getUpdateCount();
      keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
     else if (keyGenerator instanceof SelectKeyGenerator) 
      statement.execute(sql);
      rows = statement.getUpdateCount();
      keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
     else 
      statement.execute(sql);
      rows = statement.getUpdateCount();
    
    return rows;
  
  1. 获取到sql
  2. 获取KeyGenerator实例,如果是Jdbc3KeyGenerator实例,调用execute(sql, Statement.RETURN_GENERATED_KEYS)方法执行sql,如果是SelectKeyGenerator,调用execute(sql)执行sql,然后执行keyGenerator.processAfter()方法将主键存入MappedStatement对象中
  3. 通过getUpdateCount()方法获取影响行数并返回

有的同学会产生疑问,为什么没有调用keyGenerator.processBefore()方法呢?其实在BaseStatementHandler的构造方法中就产生调用了

对于查询方法就更简单了,获取sql调用statement.execute(sql)进行执行,然后resultSetHandler.handleResultSets(statement)进行结果处理,返回list集合

CallableStatementHandler

而CallableStatementHandler也是继承BaseStatementHandler,实现抽象方法instantiateStatement(),实现方法中返回CallableStatement对象,而他的其他查询更新等方法都调用了resultSetHandler.handleOutputParameters(cs)进行参数的输出

@Override
public int update(Statement statement) throws SQLException 
  CallableStatement cs = (CallableStatement) statement;
  cs.execute();
  int rows = cs.getUpdateCount();
  Object parameterObject = boundSql.getParameterObject();
  KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
  keyGenerator.processAfter(executor, mappedStatement, cs, parameterObject);
  resultSetHandler.handleOutputParameters(cs);
  return rows;

从代码中我们和SimpleStatementHandler的update代码对比,除了Statement不同,整体一样,多了个步骤就是对参数的输出:resultSetHandler.handleOutputParameters(cs);

总结

这篇文章我们讲了继承BaseStatementHandler抽象类的三个类,PreparedStatementHandler处理的是带有问号占位符的sql语句,它需要做参数处理,而SimpleStatementHandler处理没有占位符的sql语句,所以不需要进行参数的处理,CallableStatementHandler和PreparedStatementHandler差不多,也需要做参数的设置,除此之外,它还需要处理的就是进行代码参数的输出

以上是关于聊聊Mybatis的BaseStatementHandler的三个子类的主要内容,如果未能解决你的问题,请参考以下文章

聊聊Mybatis的总体流程

聊聊Mybatis的事务模块

聊聊 MyBatis 缓存

聊聊Mybatis与Spring的整合

Java框架!聊聊MyBatis的历史

聊聊MyBatis缓存机制