上一篇博客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);
      }
    }
  }

}

MyBatis主键生成器Jdbc3KeyGenerator(二)的更多相关文章

  1. MyBatis主键生成器SelectKeyGenerator(三)

    前面两篇博客我们介绍了MyBatis主键生成器KeyGenerator(一)和MyBatis主键生成器Jdbc3KeyGenerator(二),接下来我们介绍SelectKeyGenerator, 如 ...

  2. MyBatis主键生成器KeyGenerator(一)

    Mybatis提供了主键生成器接口KeyGenerator,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能 . 由于 ...

  3. 轻量级封装DbUtils&Mybatis之四MyBatis主键

    MyBatis主键 不支持对象列表存储时对自增id字段的赋值(至少包括3.2.6和3.3.0版本),如果id不是采用底层DB自增主键赋值,不必考虑此问题 温馨提示:分布式DB环境下,DB主键一般会采用 ...

  4. 主键生成器效率提升方案|基于雪花算法和Redis控制进程隔离

    背景 主键生成效率用数据库自增效率也是比较高的,为什么要用主键生成器呢?是因为需要insert主表和明细表时,明细表有个字段是主表的主键作为关联.所以就需要先生成主键填好主表明细表的信息后再一次过在一 ...

  5. Hibernate各种主键生成器策略与配置详解(转载)

    http://www.cnblogs.com/kakafra/archive/2012/09/16/2687569.html 1.assigned 主键由外部程序负责生成,在 save() 之前必须指 ...

  6. Hibernate主键生成器

    主键生成器负责生成数据表记录的主键:increment:为long,short或者int类型主键生成唯一标识.只有在没有其他进程往同一张表中插入数据时才能使用.在集群下不能使用! identity:在 ...

  7. MyBatis主键返回

    在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能. 比如在表的关联关系中,将数据插入主 ...

  8. mybatis 主键UUID生成策略

    <insert id="insert" parameterType="com.lsfwpt.lawmis.po.SysUser"> <sele ...

  9. Hibernate中的主键生成器generator

    本文讲述Hibernate的generator属性的意义.Generator属性有7种class,本文简略描述了这7种class的意义和用法. [xhtml] view plaincopy <c ...

随机推荐

  1. 如何用Netty实现一个轻量级的HTTP代理服务器

    为什么会想通过Netty构建一个HTTP代理服务器?这也是笔者发表这篇文章的目的所在. 其主要还是源于解决在日常开发测试过程中,一直困扰测试同学很久的一个问题,现在我就来具体阐述一下这个问题. 在日常 ...

  2. 如何在 vmware esxi 中开放 VNC功能及端口实现远程管理 完整篇

    VMWare esxi中开放 VNC功能及端口实现远程管理 完整篇 在多个论坛上看了相关文章,总的写得不完整.现将各方资源整编写完整版.详文如下! (图片来自51CTO) 步骤1. 修改ESXi主机的 ...

  3. Weekly Contest 75题解

    Q1. Rotate String(796) We are given two strings, A and B. A shift on A consists of taking string A a ...

  4. 判断是否是IE;自定义onkeyup事件

    <script> /*onkeyup和onchange事件在IE下冲突,在此做区分*/ if (!!window.ActiveXObject || "ActiveXObject& ...

  5. Java类加载器的工作原理

    Java类加载器的作用就是在运行时加载类.Java类加载器基于三个机制:委托.可见性和单一性.委托机制是指将加载一个类的请求交给父类加载 器,如果这个父类加载器不能够找到或者加载这个类,那么再加载它. ...

  6. webpack require.ensure 按需加载

    使用 vue-cli构建的项目,在 默认情况下 ,会将所有的js代码打包为一个整体比如index.js.当使用存在多个路由代码的时候,index.js可能会超大,影响加载速度. 这个每个路由页面除了i ...

  7. 微信内置浏览器 如何小窗不全屏播放视频?也可以尝试canvas.

    设置属性: <video height="100%" width="100%" autoplay="autoplay" control ...

  8. 用JavaScript按一定格式解析出URL 串中所有的参数

    1.先看看location对象 2.其中的search属性就获取当前URL的查询部分(问号?之后的部分) 3.改造location.search 比如当前URL为:https://www.hao123 ...

  9. SpringBoot+Mybatis+ Druid+PageHelper 实现多数据源并分页

    前言 本篇文章主要讲述的是SpringBoot整合Mybatis.Druid和PageHelper 并实现多数据源和分页.其中SpringBoot整合Mybatis这块,在之前的的一篇文章中已经讲述了 ...

  10. PHP 5 常量

    PHP 5 常量 常量值被定义后,在脚本的其他任何地方都不能被改变. PHP 常量 常量是一个简单值的标识符.该值在脚本中不能改变. 一个常量由英文字母.下划线.和数字组成,但数字不能作为首字母出现. ...