ibatis中selectKey的用法与源码
最近用到插入oracle数据库时,主键id是sequnce自动生成,具体写法如下
对于oracle:
<insertid="insertUser"parameterclass="ibatis.User">
<selectKeyresultclass="long"keyProperty="id">
selectSEQ_USER_ID.nextvalasidfromdual
</selectKey>
insertintouser
(id,name,password)
values
(#id#,#name#,#password#)
</insert>
对于mysql:
<insertid="insertUser"parameterclass="ibatis.User">
insertintouser
(name,password)
values
(#name#,#password#)
<selectKeyresultclass="long"keyProperty="id">
SELECTLAST_INSERT_ID()ASID
</selectKey>
</insert>
上面是两种数据库的实现。
下面我们看看源码是如何做的
//--BasicMethods
/**
*CallaninsertstatementbyID
*
*@paramsessionScope-thesession
*@paramid-thestatementID
*@paramparam-theparameterobject
*@return-thegeneratedkey(ornull)
*@throwsSQLException-iftheinsertfails
*/
publicObjectinsert(SessionScopesessionScope,Stringid,Objectparam)throwsSQLException{
ObjectgeneratedKey=null;
MappedStatementms=getMappedStatement(id);
Transactiontrans=getTransaction(sessionScope);
booleanautoStart=trans==null;
try{
//开始事务
trans=autoStartTransaction(sessionScope,autoStart,trans);
SelectKeyStatementselectKeyStatement=null;
if(msinstanceofInsertStatement){
selectKeyStatement=((InsertStatement)ms).getSelectKeyStatement();
}
//Herewegettheoldvalueforthekeyproperty.We'llwantitlaterifforsomereasonthe
//insertfails.
ObjectoldKeyValue=null;
StringkeyProperty=null;
booleanresetKeyValueOnFailure=false;
//对于oracle适用于执行insert之前执行selectKey获取id值
if(selectKeyStatement!=null&&!selectKeyStatement.isRunAfterSQL()){
keyProperty=selectKeyStatement.getKeyProperty();
oldKeyValue=PROBE.getObject(param,keyProperty);
//sequnce获取id的值
generatedKey=executeSelectKey(sessionScope,trans,ms,param);
resetKeyValueOnFailure=true;
}
StatementScopestatementScope=beginStatementScope(sessionScope,ms);
try{
//执行sql语句
ms.executeUpdate(statementScope,trans,param);
}catch(SQLExceptione){
//uh-oh,theinsertfailed,soifwesettheresetflagearlier,we'llputtheoldvalue
//back...
if(resetKeyValueOnFailure)PROBE.setObject(param,keyProperty,oldKeyValue);
//...andstillthrowtheexception.
throwe;
}finally{
endStatementScope(statementScope);
}
//对于mysql适用于执行完insert后,获取id值
if(selectKeyStatement!=null&&selectKeyStatement.isRunAfterSQL()){
generatedKey=executeSelectKey(sessionScope,trans,ms,param);
}
//提交事务
autoCommitTransaction(sessionScope,autoStart);
}finally{
//结束事务
autoEndTransaction(sessionScope,autoStart);
}
returngeneratedKey;
}