MyBatis主键生成器Jdbc3KeyGenerator(二)
上一篇博客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(二)的更多相关文章
- MyBatis主键生成器SelectKeyGenerator(三)
前面两篇博客我们介绍了MyBatis主键生成器KeyGenerator(一)和MyBatis主键生成器Jdbc3KeyGenerator(二),接下来我们介绍SelectKeyGenerator, 如 ...
- MyBatis主键生成器KeyGenerator(一)
Mybatis提供了主键生成器接口KeyGenerator,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能 . 由于 ...
- 轻量级封装DbUtils&Mybatis之四MyBatis主键
MyBatis主键 不支持对象列表存储时对自增id字段的赋值(至少包括3.2.6和3.3.0版本),如果id不是采用底层DB自增主键赋值,不必考虑此问题 温馨提示:分布式DB环境下,DB主键一般会采用 ...
- 主键生成器效率提升方案|基于雪花算法和Redis控制进程隔离
背景 主键生成效率用数据库自增效率也是比较高的,为什么要用主键生成器呢?是因为需要insert主表和明细表时,明细表有个字段是主表的主键作为关联.所以就需要先生成主键填好主表明细表的信息后再一次过在一 ...
- Hibernate各种主键生成器策略与配置详解(转载)
http://www.cnblogs.com/kakafra/archive/2012/09/16/2687569.html 1.assigned 主键由外部程序负责生成,在 save() 之前必须指 ...
- Hibernate主键生成器
主键生成器负责生成数据表记录的主键:increment:为long,short或者int类型主键生成唯一标识.只有在没有其他进程往同一张表中插入数据时才能使用.在集群下不能使用! identity:在 ...
- MyBatis主键返回
在使用MyBatis做持久层时,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能. 比如在表的关联关系中,将数据插入主 ...
- mybatis 主键UUID生成策略
<insert id="insert" parameterType="com.lsfwpt.lawmis.po.SysUser"> <sele ...
- Hibernate中的主键生成器generator
本文讲述Hibernate的generator属性的意义.Generator属性有7种class,本文简略描述了这7种class的意义和用法. [xhtml] view plaincopy <c ...
随机推荐
- Linux下打包tar.gz
将heben-addressbookinit打包成heben-addressbookinit.tar.gz格式 方式1:czvf heben-addressbookinit.tar.gz heben- ...
- 在vue生命周期中及时销毁全局作用的代码
一.纯客户端中 对于全局的代码,比如定时器等,在 beforeDestroy或 destroyed 生命周期时将其销毁.如果在跳转路由时候,组件销毁了,全局的定时器却没有销毁,这会使得页面产生卡顿. ...
- python读取文本文件数据
本文要点刚要: (一)读文本文件格式的数据函数:read_csv,read_table 1.读不同分隔符的文本文件,用参数sep 2.读无字段名(表头)的文本文件 ,用参数names 3.为文本文件制 ...
- redis的基本数据类型
一:redis是一个开源的,使用C语言编写,支持网络,可基于内存亦可持久化的日志型,key-value方式存储的nosql数据库.作为缓存服务器,速度效率都很快,和memcache相似 redis支持 ...
- 自定义Java注解的方式与应用
注解的作用 Annotation(注解)是JDK 5.0引入的特性,它的基本作用就是修饰编程元素. 注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记.编译器.开发工具或其他程序可以用反射 ...
- Angularjs + Bootstrap 制作的一个TODO List
看了一个关于Angularjs的视频,视频内容讲解的是如何制作一款TODO list形式的SPA(Simple Page Application,单页面应用).为了增强理解,下面写了一篇文章,用以复习 ...
- EBS多组织结构
1. 业务组: 它代表组织结构的最高层次, 它分离了人力资源的信息. 例如, 当你查询人员时, 它会列出所有分配给相应业务组的成员, 而你自己所属于的组织只不过是业务组的一份子. 这样说可能造成一种误 ...
- FFmpeg源代码简单分析:avformat_write_header()
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- 14 Fragment 注意点
API 过时问题 API 23过时 public void onAttach(Activity activity)替换为public void onAttach(Context context) 注意 ...
- 4.1、Android Stuido配置你的Build Variant
每个版本的build variant代表了你可以构建的每一个版本.虽然你未直接配置build variants,你可以通过配置build type和product flavor. 比如,一个demo的 ...