SelectStatement(MappedStatement).executeQueryWithCallback{
...
String sqlString = sql.getSql(statementScope, parameterObject);
...
}
SelectStatement(MappedStatement).executeQueryWithCallback(StatementScope, Connection, Object, Object, RowHandler, int, int) line: 161
SelectStatement(MappedStatement).executeQueryForList(StatementScope, Transaction, Object, int, int) line: 138
SqlMapExecutorDelegate.queryForList(SessionScope, String, Object, int, int) line: 556
SqlMapExecutorDelegate.queryForList(SessionScope, String, Object) line: 541
SqlMapSessionImpl.queryForList(String, Object) line: 118
SqlMapClientTemplate$3.doInSqlMapClient(SqlMapExecutor) line: 298
SqlMapClientTemplate.execute(SqlMapClientCallback) line: 209
SqlMapClientTemplate.executeWithListResult(SqlMapClientCallback) line: 249
SqlMapClientTemplate.queryForList(String, Object) line: 296
CdnStatDaoiBatis.getProductTrafficTop5List(List<Map<String,Integer>>) line: 51
delete 호출시
getSqlMapClientTemplate().delete("removeData", param);내부적으로는 update 를 호출한다.
// SqlMapClientTemplate.java
public int delete(final String statementName, final Object parameterObject)
throws DataAccessException {
Integer result = (Integer) execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return new Integer(executor.delete(statementName, parameterObject));
}
});
return result.intValue();
});
// SqlMapClientTemplate.java
public Object execute(SqlMapClientCallback action) throws DataAccessException {
...
try{
return action.doInSqlMapClient(session);
} ...
finally {
try {
if (springCon != null) {
if (transactionAware) {
springCon.close();
}
else {
DataSourceUtils.doReleaseConnection(springCon, dataSource);
}
}
}
catch (Throwable ex) {
logger.debug("Could not close JDBC Connection", ex);
}
}
...
finally{
...
if (ibatisCon == null) {
session.close();
}
// SqlMapSessionImpl.java
public int delete(String id, Object param) throws SQLException {
return delegate.delete(sessionScope, id, param);
}
// SqlMapExecutorDelegate.java
public int delete(SessionScope sessionScope, String id, Object param) throws SQLException {
return update(sessionScope, id, param);
}
// SqlMapExecutorDelegate.java
public int update(SessionScope sessionScope, String id, Object param) throws SQLException {
...
Transaction trans = getTransaction(sessionScope);
boolean autoStart = trans == null;
try {
trans = autoStartTransaction(sessionScope, autoStart, trans);
...
try {
rows = ms.executeUpdate(statementScope, trans, param);
...
}
autoCommitTransaction(sessionScope, autoStart);
// MappedStatement.java
public int executeUpdate(StatementScope statementScope, Transaction trans, Object parameterObject) throws SQLException {
...
statementScope.getSession().setCommitRequired(true);
try {
parameterObject = validateParameter(parameterObject);
Sql sql = getSql();
...
String sqlString = sql.getSql(statementScope, parameterObject);
...
rows = sqlExecuteUpdate(statementScope, trans.getConnection(), sqlString, parameters);
// MappedStatement.java
public Sql getSql() {
return sql;
}
// MappedStatement.java
protected int sqlExecuteUpdate(StatementScope statementScope, Connection conn, String sqlString, Object[] parameters) throws SQLException {
if (statementScope.getSession().isInBatch()) {
...
} else {
return getSqlExecutor().executeUpdate(statementScope, conn, sqlString, parameters);
// SqlExecutor.java
public int executeUpdate(StatementScope statementScope, Connection conn, String sql, Object[] parameters) throws SQLException {
...
try {
...
ps = prepareStatement(statementScope.getSession(), conn, sql);
...
setStatementTimeout(statementScope.getStatement(), ps);
...
statementScope.getParameterMap().setParameters(statementScope, ps, parameters);
...
ps.execute();
rows = ps.getUpdateCount();
} finally {
closeStatement(statementScope.getSession(), ps);
}
// SqlExecutor.java
private static PreparedStatement prepareStatement(SessionScope sessionScope, Connection conn, String sql) throws SQLException {
...
if (sessionScope.hasPreparedStatementFor(sql)) {
...
} else {
PreparedStatement ps = conn.prepareStatement(sql);
...
return ps;
// ParameterMap.java
public void setParameters(StatementScope statementScope, PreparedStatement ps, Object[] parameters) throws SQLException {
...
if (parameterMappings != null) {
for (int i = 0; i < parameterMappings.length; i++) {
ParameterMapping mapping = parameterMappings[i];
...
if (mapping.isInputAllowed()) {
setParameter(ps, mapping, parameters, i);
}
}
}
ref. 1 에 따르면, iBatis 는 autocommit 을 사용하지 않는다. 그리고 setCommitRequired() 은 AutoCommit 과는 관계없는 것이라고 한다. 자세한 내용은 ref.1 을 참고하자.
MyBatis 페이지에서 auto-commit 을 설정해서 session 을 여는 방법이 나온다. default 는 auto-commit 을 사용하지 않는 것이라고 한다.
- MyBatis > SqlSessions > SqlSessionFactory > auto-commit
Method 이름
이상하게 method 하나를 만들었는데 auto-commit 이 되지 않았다. 이유는 method 이름에 있었다. AOP 의 설정이 아래와 같이 되어있어서 아래 조건에 맞지 않는 service 의 method 는 auto-commit 설정이 적용되지 않았던 것이었다.aop 설정에 관해서는 나중에 알아보도록 하자.
//spring.xml <!-- database --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="init*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="udt*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="set*" propagation="REQUIRED" rollback-for="Exception"/> <tx:method name="change*" propagation="REQUIRED" rollback-for="Exception"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="requiredTx" expression="execution(public * com.mine..service..*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="requiredTx" /> </aop:config>
Insert 후 Primary Key 를 받아오기
ref. 3, 4, 5 을 참고하자.
<insert id="insertVipData" parameterClass="VipInfo">
INSERT INTO db1.test1 (user_id, c_id) VALUES (#USER_ID#, #C_ID#);
<selectKey keyProperty="ID" resultClass="Integer">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
public class CdnStatVipInfo implements Serializable {
...
private int ID; // ID
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
References
- Autocommit not properly handled in Ibatis, Jan 19, 2007
- 스프링 트래잭션 롤백이 되지 않을 때 확인 사항, 2013/03/05
- [MySQL, iBATIS] LAST_INSERT_ID(), insert 후 PK 값 사용하기, 2010/01/25
- iBATIS - Create Operation
- iBatis에서 myBatis로 변경시 selectKey에 대한 변경사항, Posted 2013/05/04 12:08
댓글 없음:
댓글 쓰기