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;

}

相关推荐