标签:and ++ 解析 ora 填充 turn tco type 配置
本文,我们来分享 SQL 执行的第三部分,keygen
包。整体类图如下:
org.apache.ibatis.executor.keygen.KeyGenerator
,主键生成器接口。代码如下:
// KeyGenerator.java
|
parameter
参数,指的是什么呢?以下面的方法为示例:
|
country
方法参数,就是一个 parameter
参数。parameter
参数的对应属性。KeyGenerator 有三个子类,如下图所示:
org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator
,实现 KeyGenerator 接口,基于 Statement#getGeneratedKeys()
方法的 KeyGenerator 实现类,适用于 MySQL、H2 主键生成。
// Jdbc3KeyGenerator.java
|
|
// Jdbc3KeyGenerator.java
|
#processBatch(Executor executor, MappedStatement ms, Statement stmt, Object parameter)
方法,处理返回的自增主键。单个 parameter
参数,可以认为是批量的一个特例。
// Jdbc3KeyGenerator.java
|
<1>
处,获得主键属性的配置。如果为空,则直接返回,说明不需要主键。<2>
处,调用 Statement#getGeneratedKeys()
方法,获得返回的自增主键。<3>
处,调用 #getSoleParameter(Object parameter)
方法,获得唯一的参数对象。详细解析,先跳到 「3.4.1 getSoleParameter」 。
<3.1>
处,调用 #assignKeysToParam(...)
方法,设置主键们,到参数 soleParam
中。详细解析,见 「3.4.2 assignKeysToParam」 。<3.2>
处,调用 #assignKeysToOneOfParams(...)
方法,设置主键们,到参数 parameter
中。详细解析,见 「3.4.3 assignKeysToOneOfParams」 。<4>
处,关闭 ResultSet 对象。
// Jdbc3KeyGenerator.java
|
<1>
处,如下可以符合这个条件。代码如下:
|
<2>
处,如下可以符合这个条件。代码如下:
|
country
和 someId
参数,但是最终会被封装成一个 parameter
参数,类型为 ParamMap 类型。为什么呢?答案在 ParamNameResolver#getNamedParams(Object[] args)
方法中。country
的 id
属性,因为注解上的 keyProperty = "country.id"
配置。<3>
处,如下可以符合这个条件。代码如下:
|
<2>
的示例,主要是 keyProperty = "id"
的修改,和去掉了 @Param("someId") Integer someId
参数。<1>
是类似的。<2>
和 <3>
有点复杂,胖友实际上,理解 <1>
即可。
// Jdbc3KeyGenerator.java
|
<1>
处,包装成 Collection 对象。通过这样的方式,使单个 param
参数的情况下,可以统一。<2>
处,遍历 paramAsCollection
数组:
<2.1>
处, 顺序遍历 rs
,相当于把当前的 ResultSet 对象的主键们,赋值给 obj
对象的对应属性。<2.2>
处,创建 MetaObject 对象,实现对 obj
对象的属性访问。<2.3>
处,调用 #getTypeHandlers(...)
方法,获得 TypeHandler 数组。代码如下:
// Jdbc3KeyGenerator.java
|
<2.4>
处,调用 #populateKeys(...)
方法,填充主键们。详细解析,见 「3.5 populateKeys」 。
// Jdbc3KeyGenerator.java
|
<1>
处,需要有 .
。例如:@Options(useGeneratedKeys = true, keyProperty = "country.id")
。<2>
处,获得真正的参数值。<3>
处,获得主键的属性的配置。<4>
处,调用 #assignKeysToParam(...)
方法,设置主键们,到参数 param
中。所以,后续流程,又回到了 「3.4.2」 咧。
// Jdbc3KeyGenerator.java
|
org.apache.ibatis.executor.keygen.SelectKeyGenerator
,实现 KeyGenerator 接口,基于从数据库查询主键的 KeyGenerator 实现类,适用于 Oracle、PostgreSQL 。
// SelectKeyGenerator.java
|
// SelectKeyGenerator.java
|
#processGeneratedKeys(...)
方法。
// SelectKeyGenerator.java
|
#processGeneratedKeys(...)
方法。
// SelectKeyGenerator.java
|
<1>
处,有查询主键的 SQL 语句,即 keyStatement
对象非空。<2>
处,创建执行器,类型为 SimpleExecutor 。<3>
处,调用 Executor#query(...)
方法,执行查询主键的操作。?? 简单脑暴下,按照 SelectKeyGenerator 的思路,岂不是可以可以接入 SnowFlake 算法,从而实现分布式主键。<4.1>
处,查不到结果,抛出 ExecutorException 异常。<4.2>
处,查询的结果过多,抛出 ExecutorException 异常。<4.3>
处,创建 MetaObject 对象,访问查询主键的结果。
<4.3.1>
处,单个主键,调用 #setValue(MetaObject metaParam, String property, Object value)
方法,设置属性到 metaParam
中,相当于设置到 parameter
中。代码如下:
// SelectKeyGenerator.java
|
<4.3.2>
处,多个主键,调用 #handleMultipleProperties(String[] keyProperties, MetaObject metaParam, MetaObject metaResult)
方法,遍历,进行赋值。代码如下:
// SelectKeyGenerator.java
|
#setValue(...)
方法,进行赋值。org.apache.ibatis.executor.keygen.NoKeyGenerator
,实现 KeyGenerator 接口,空的 KeyGenerator 实现类,即无需主键生成。代码如下:
// NoKeyGenerator.java
|
标签:and ++ 解析 ora 填充 turn tco type 配置
原文地址:https://www.cnblogs.com/siye1989/p/11624144.html