上一篇博客MyBatis主键生成器KeyGenerator(一)中我们大体介绍了主键生成器的接口及配置等,接下来我们介绍一下KeyGenerator的实现类Jdbc3KeyGenerator

Jdbc3KeyGenerator实际上实现了processAfter方法,其使用方法如下配置,目的是将主键作为返回值返回,这种用法只能是在有自增主键的数据库中使用:

<insert id="save" useGeneratedKeys="true" keyColumn="i_id" keyProperty="id">
<span style="white-space:pre">	</span>insert into tbl_log (log_type,log_info) values (#{logType},#{logInfo})
</insert>

其实现原理就是获得数据库的记录条数,然后加1,作为返回参数的值返回,源码实现如下:

/**
 * @author Clinton Begin
 */
public class Jdbc3KeyGenerator implements KeyGenerator {

  //jdbc模式只能是执行之后返回主键id
  @Override
  public void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
    // do nothing
  }

  @Override
  public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
    List<Object> parameters = new ArrayList<Object>();
    parameters.add(parameter);
    processBatch(ms, stmt, parameters);
  }
  //
  public void processBatch(MappedStatement ms, Statement stmt, List<Object> parameters) {
    ResultSet rs = null;
    try {
      rs = stmt.getGeneratedKeys();
      final Configuration configuration = ms.getConfiguration();
      final TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
	  //获得返回值的参数名
      final String[] keyProperties = ms.getKeyProperties();
      final ResultSetMetaData rsmd = rs.getMetaData();
      TypeHandler<?>[] typeHandlers = null;
      if (keyProperties != null && rsmd.getColumnCount() >= keyProperties.length) {
        for (Object parameter : parameters) {
          // there should be one row for each statement (also one for each parameter)
          if (!rs.next()) {
            break;
          }
          final MetaObject metaParam = configuration.newMetaObject(parameter);
		  //获得执行之后返回值的类型
          if (typeHandlers == null) {
            typeHandlers = getTypeHandlers(typeHandlerRegistry, metaParam, keyProperties);
          }
          populateKeys(rs, metaParam, keyProperties, typeHandlers);
        }
      }
    } catch (Exception e) {
      throw new ExecutorException("Error getting generated key or setting result to parameter object. Cause: " + e, e);
    } finally {
      if (rs != null) {
        try {
          rs.close();
        } catch (Exception e) {
          // ignore
        }
      }
    }
  }
  //设置执行sql之后返回参数对应的值
  private TypeHandler<?>[] getTypeHandlers(TypeHandlerRegistry typeHandlerRegistry, MetaObject metaParam, String[] keyProperties) {
    TypeHandler<?>[] typeHandlers = new TypeHandler<?>[keyProperties.length];
    for (int i = 0; i < keyProperties.length; i++) {
      if (metaParam.hasSetter(keyProperties[i])) {
        Class<?> keyPropertyType = metaParam.getSetterType(keyProperties[i]);
        TypeHandler<?> th = typeHandlerRegistry.getTypeHandler(keyPropertyType);
        typeHandlers[i] = th;
      }
    }
    return typeHandlers;
  }

  private void populateKeys(ResultSet rs, MetaObject metaParam, String[] keyProperties, TypeHandler<?>[] typeHandlers) throws SQLException {
    for (int i = 0; i < keyProperties.length; i++) {
      TypeHandler<?> th = typeHandlers[i];
      if (th != null) {
		 //获得执行后对应参数的值
        Object value = th.getResult(rs, i + 1);
		//设置返回参数的值
        metaParam.setValue(keyProperties[i], value);
      }
    }
  }

}

最新文章

  1. Python成长笔记 - 基础篇 (六)python模块
  2. yourphp问题中心
  3. 【转】七年IT经验的七个总结
  4. yii2权限控制rbac之rule详细讲解(转)
  5. Lua程序设计入门
  6. VueJs2.0建议学习路线
  7. Oracle表空间管理
  8. sqlserver根据id集合,批量插入。(巧用sqlserver内置函数)
  9. oAuth 认证
  10. Java 本地开发环境搭建(框架采用 Spring+Spring MVC+Hibernate+Jsp+Gradle+tomcat+mysql5.6)
  11. spring boot 给返回值加状态 BaseData
  12. Fiddler抓包6-get请求(url详解)
  13. BZOJ.5339.[TJOI2018]教科书般的亵渎(拉格朗日插值) &amp; 拉格朗日插值学习笔记
  14. Linux Tomcat8 启动堆内存溢出
  15. ansible role 理解
  16. Spring-MVC配置Gson做为Message Converter解析Json
  17. ubuntu svn二进制文件
  18. [LeetCode&amp;Python] Problem 868. Binary Gap
  19. html的loadrunner脚本
  20. PAT甲级1034. Head of a Gang

热门文章

  1. TensorFlow 中文资源全集,官方网站,安装教程,入门教程,实战项目,学习路径。
  2. mysql insert插入时实现如果数据表中主键重复则更新,没有重复则插入的四种方法
  3. SQL Server 2016 非域Aways On环境搭建
  4. Spring消息之AMQP.
  5. PHP While 循环
  6. Docker容器时间与宿主机时间不一致
  7. cassandra 3.x官方文档(2)---架构解析
  8. VMware中的桥接模式、NAT(网络地址转换模式)、Host-only(主机模式):转自:http://blog.chinaunix.net/uid-11798538-id-3061551.html
  9. nginx平台初识(二) 浏览器 HTTP 协议缓存机制详解
  10. Leetcode解题-链表(2.2.1)AddTwoNumbers