在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);
所以如果想用插入後有主鍵值,需要配置useGeneratedKeys爲true。使用Jdbc3KeyGenerator生成器,或者使用SelectKey