在mybatis里面经常遇到生成主键的问题,使用自增或者序列,保存对象后对象里面有主键值,来看看是怎么处理的:
1、在BaseStatementHandler里面有生成generateKeys,主要是执行:
protected void generateKeys(Object parameter) {
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
ErrorContext.instance().store();
keyGenerator.processBefore(executor, mappedStatement, null, parameter);
ErrorContext.instance().recall();
}
processBefore,
表示执行前处理,对应mapper里面的selectKey中的order="BEFORE"属性,先执行查询key,并设置到参数对象中。
2、在各个声明处理器中,update有代码:
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
processAfter,
表示执行后处理,
对应mapper里面的selectKey中的order="AFTER"属性,表示执行后,再查一遍key,设置到参数对象中
3、KeyGenerator分Jdbc3KeyGenerator和SelectKeyGenerator
mappedStatement.keyGenerator = configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType) ? new Jdbc3KeyGenerator() : new NoKeyGenerator();
if (configuration.hasKeyGenerator(keyStatementId)) {
keyGenerator = configuration.getKeyGenerator(keyStatementId);
} else {
keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))
? new Jdbc3KeyGenerator() : new NoKeyGenerator();
}
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver);