背景:
在使用ibatis插入数据进数据库的时候,会用到一些sequence的数据,有些情况下,在插入完成之后还需要将sequence的值返回,然后才能进行下一步的操作。
使用ibatis的selectKey就可以得到sequence的值,同时也会将值返回。不过对于不同的数据库有不同的操作方式。
对于oracle:
<insert id="insertUser" parameterClass="ibatis.User">
<selectKey resultClass="long" keyProperty="id">
select SEQ_USER_ID.nextval as id from dual
</selectKey>
insert into user
(id,name,password)
values
(#id#,#name#,#password#)
</insert>
该句话执行完之后,传进来的参数User对象DO里的id字段就会被赋值成sequence的值。
对于mysql
<insert id="insertUser" parameterClass="ibatis.User">
insert into user
(name,password)
values
(#name#,#password#)
<selectKey resultClass="long" keyProperty="id">
SELECT LAST_INSERT_ID() AS ID
</selectKey>
</insert>
将selectKey放在insert之后,通过LAST_INSERT_ID() 获得刚插入的自动增长的id的值。
附上ibatis源码:
//-- Basic Methods /** * Call an insert statement by ID * * @param sessionScope - the session * @param id - the statement ID * @param param - the parameter object * @return - the generated key (or null) * @throws SQLException - if the insert fails */ public Object insert(SessionScope sessionScope, String id, Object param) throws SQLException { Object generatedKey = null; MappedStatement ms = getMappedStatement(id); Transaction trans = getTransaction(sessionScope); boolean autoStart = trans == null; try { //开始事务 trans = autoStartTransaction(sessionScope, autoStart, trans); SelectKeyStatement selectKeyStatement = null; if (ms instanceof InsertStatement) { selectKeyStatement = ((InsertStatement) ms).getSelectKeyStatement(); } // Here we get the old value for the key property. We'll want it later if for some reason the // insert fails. Object oldKeyValue = null; String keyProperty = null; boolean resetKeyValueOnFailure = false; if (selectKeyStatement != null && !selectKeyStatement.isRunAfterSQL()) { keyProperty = selectKeyStatement.getKeyProperty(); oldKeyValue = PROBE.getObject(param, keyProperty); generatedKey = executeSelectKey(sessionScope, trans, ms, param); resetKeyValueOnFailure = true; } StatementScope statementScope = beginStatementScope(sessionScope, ms); try { ms.executeUpdate(statementScope, trans, param); }catch (SQLException e){ // uh-oh, the insert failed, so if we set the reset flag earlier, we'll put the old value // back... if(resetKeyValueOnFailure) PROBE.setObject(param, keyProperty, oldKeyValue); // ...and still throw the exception. throw e; } finally { endStatementScope(statementScope); } if (selectKeyStatement != null && selectKeyStatement.isRunAfterSQL()) { generatedKey = executeSelectKey(sessionScope, trans, ms, param); } //提交事务 autoCommitTransaction(sessionScope, autoStart); } finally { //结束事务 autoEndTransaction(sessionScope, autoStart); } return generatedKey; }