MyBatis主键生成器SelectKeyGenerator(三)
前面两篇博客我们介绍了MyBatis主键生成器KeyGenerator(一)和MyBatis主键生成器Jdbc3KeyGenerator(二),接下来我们介绍SelectKeyGenerator,
如在Oraclee中并不提供自增组件,提供了Sequence主键,我们就需要执行它的Sequence主键,如在mysql中如下配置:
<insert id="save"> <selectKey resultType="int" keyProperty="id" order="BEFORE"> SELECT LAST_INSERT_ID() AS id </selectKey> insert into tbl_log (log_type,log_info) values (#{logType},#{logInfo}) </insert>
其实现原理就是执行selectKey中的sql语句来获得结果,在SelectKeyGenerator的源码实现中就是执行 select last_insert_id() as id这条sql语句,获得结果,并赋值给id,源码实现如下:
/** * @author Clinton Begin * @author Jeff Butler */ public class SelectKeyGenerator implements KeyGenerator { public static final String SELECT_KEY_SUFFIX = "!selectKey"; private boolean executeBefore; private MappedStatement keyStatement; public SelectKeyGenerator(MappedStatement keyStatement, boolean executeBefore) { this.executeBefore = executeBefore; this.keyStatement = keyStatement; } @Override public void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter) { if (executeBefore) { processGeneratedKeys(executor, ms, parameter); } } @Override public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) { if (!executeBefore) { processGeneratedKeys(executor, ms, parameter); } } //执行来获得结果值 private void processGeneratedKeys(Executor executor, MappedStatement ms, Object parameter) { try { if (parameter != null && keyStatement != null && keyStatement.getKeyProperties() != null) { String[] keyProperties = keyStatement.getKeyProperties(); final Configuration configuration = ms.getConfiguration(); final MetaObject metaParam = configuration.newMetaObject(parameter); if (keyProperties != null) { // Do not close keyExecutor. // The transaction will be closed by parent executor. Executor keyExecutor = configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE); //执行获得主键的sql语句 List<Object> values = keyExecutor.query(keyStatement, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER); if (values.size() == 0) { throw new ExecutorException("SelectKey returned no data."); } else if (values.size() > 1) { throw new ExecutorException("SelectKey returned more than one value."); } else { //执行结果 MetaObject metaResult = configuration.newMetaObject(values.get(0)); //返回参数如果是一个 if (keyProperties.length == 1) { //判断返回参数使用有get方法 if (metaResult.hasGetter(keyProperties[0])) { setValue(metaParam, keyProperties[0], metaResult.getValue(keyProperties[0])); } else { // no getter for the property - maybe just a single value object // so try that setValue(metaParam, keyProperties[0], values.get(0)); } } else { //如果有多个返回参数则需要循环赋值 handleMultipleProperties(keyProperties, metaParam, metaResult); } } } } } catch (ExecutorException e) { throw e; } catch (Exception e) { throw new ExecutorException("Error selecting key or setting result to parameter object. Cause: " + e, e); } } //如果有多个返回参数则需要循环赋值 private void handleMultipleProperties(String[] keyProperties, MetaObject metaParam, MetaObject metaResult) { String[] keyColumns = keyStatement.getKeyColumns(); //如果没设置返回参数的值,则使用结果属性的值 if (keyColumns == null || keyColumns.length == 0) { // no key columns specified, just use the property names for (int i = 0; i < keyProperties.length; i++) { setValue(metaParam, keyProperties[i], metaResult.getValue(keyProperties[i])); } } else { if (keyColumns.length != keyProperties.length) { throw new ExecutorException("If SelectKey has key columns, the number must match the number of key properties."); } for (int i = 0; i < keyProperties.length; i++) { setValue(metaParam, keyProperties[i], metaResult.getValue(keyColumns[i])); } } } //设置返回参数对应的值 private void setValue(MetaObject metaParam, String property, Object value) { if (metaParam.hasSetter(property)) { metaParam.setValue(property, value); } else { throw new ExecutorException("No setter found for the keyProperty '" + property + "' in " + metaParam.getOriginalObject().getClass().getName() + "."); } } }
MyBatis主键生成器SelectKeyGenerator(三)的更多相关文章
- MyBatis主键生成器Jdbc3KeyGenerator(二)
上一篇博客MyBatis主键生成器KeyGenerator(一)中我们大体介绍了主键生成器的接口及配置等,接下来我们介绍一下KeyGenerator的实现类Jdbc3KeyGenerator Jdbc ...
- 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 ...
随机推荐
- Spring中整合Cage,实现验证码功能
1.pom.xml中添加Cage依赖. <dependency> <groupId>com.github.cage</groupId> <artifactId ...
- ajax中基本参数应用
$(function () { $("#verificationCodeBtn").click(function () { $("#verificationCodeIma ...
- 关于一些基础的Java问题的解答(六)
26. ThreadPool用法与优势 ThreadPool即线程池,它是JDK1.5引入的Concurrent包中用于处理并发编程的工具.使用线程池有如下好处: 降低资源消耗:通过重复利用已创建的线 ...
- android基础-界面开发注意事项
做安卓开发时一定要注意,主线程不能更改UI界面,如果出现程序运行时崩溃的情况,如果没有明显的语法错误,请检查自己的进程是否出现冲突,崩溃.如果有与后台的连接,即请求向服务器发送请求的时尤其需要注意,或 ...
- Emacs Python 自动补全--Elpy
安装方法: 首先,安装一些依赖包: # Either of these pip install rope pip install jedi # flake8 用来检查语法错误 pip install ...
- JavaScript while 循环
JavaScript while 循环的目的是为了反复执行语句或代码块. 只要指定条件为 true,循环就可以一直执行代码块. while 循环 while 循环会在指定条件为真时循环执行代码块. 语 ...
- 学习笔记:Zookeeper 应用案例(上下线动态感知)
1.Zookeeper 应用案例(上下线动态感知) 8.1 案例1--服务器上下线动态感知 8.1.1 需求描述 某分布式系统中,主节点可以有多台,可以动态上下线 任意一台客户端都能实时感知到主节点服 ...
- SpringBatch的核心组件JobLauncher和JobRepository
Spring Batch的框架包括启动批处理作业的组件和存储Job执行产生的元数据.因此只需掌握配置这个基础框架在批处理应用程序中即启动Jobs并存储Job元数据. 组件:Job Launcher和J ...
- 异步请求引发的Chrome死锁
浏览器支持的并发异步请求数目是有限的,当需要的资源过多时候(远远大于并发数目),就需要自己管理XHR请求. 在实现自己的XHR的Manger时候,当请求数目达到2000多的时候,经常会遇到chrome ...
- python将nan, inf转为特定的数字
最近,处理两个矩阵的点除,得到结果后,再作其他的计算,发现有些内置的函数不work:查看得到的数据,发现有很多nan和inf,导致python的基本函数运行不了,这是因为在除的过程中分母出现0的缘故. ...