H2數據庫更新表
重複的步驟就不貼了 dml語句都要經過CommandContainer中的update方法咱就直接從這進
@Override
public int update() {
recompileIfRequired();
setProgress(DatabaseEventListener.STATE_STATEMENT_START);
start();
session.setLastScopeIdentity(ValueNull.INSTANCE);
prepared.checkParameters();
//入口
int updateCount = prepared.update();
prepared.trace(startTimeNanos, updateCount);
setProgress(DatabaseEventListener.STATE_STATEMENT_END);
return updateCount;
}
Update類中的update方法
//上面的代碼有點多 主要是將新字段和舊字段放到rows中如下圖
table.updateRows(this, session, rows);
if (table.fireRow()) {
rows.invalidateCache();
for (rows.reset(); rows.hasNext();) {
Row o = rows.next();
Row n = rows.next();
table.fireAfterRow(session, o, n, false);
}
}
Table中的updateRows方法
public void updateRows(Prepared prepared, Session session, RowList rows) {
// in case we need to undo the update
Session.Savepoint rollback = session.setSavepoint();
// 移出老字段
int rowScanCount = 0;
for (rows.reset(); rows.hasNext();) {
if ((++rowScanCount & 127) == 0) {
prepared.checkCanceled();
}
Row o = rows.next();
rows.next();
try {
//刪除
removeRow(session, o);
} catch (DbException e) {
if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1) {
session.rollbackTo(rollback, false);
session.startStatementWithinTransaction();
rollback = session.setSavepoint();
}
throw e;
}
session.log(this, UndoLogRecord.DELETE, o);
}
// 添加新字段
for (rows.reset(); rows.hasNext();) {
if ((++rowScanCount & 127) == 0) {
prepared.checkCanceled();
}
rows.next();
Row n = rows.next();
try {
addRow(session, n);
} catch (DbException e) {
if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1) {
session.rollbackTo(rollback, false);
session.startStatementWithinTransaction();
rollback = session.setSavepoint();
}
throw e;
}
session.log(this, UndoLogRecord.INSERT, n);
}
}
MVTable中的移除字段方法 添加和移除差不多 這裏值寫了移除
//MVTable中的方法
@Override
public void removeRow(Session session, Row row) {
lastModificationId = database.getNextModificationDataId();
Transaction t = getTransaction(session);
long savepoint = t.setSavepoint();
try {
for (int i = indexes.size() - 1; i >= 0; i--) {
Index index = indexes.get(i);
//調用移除方法
index.remove(session, row);
}
} catch (Throwable e) {
t.rollbackToSavepoint(savepoint);
throw DbException.convert(e);
}
analyzeIfRequired(session);
}
MVPrimaryIndex實現了index接口
@Override
public void remove(Session session, Row row) {
if (mvTable.getContainsLargeObject()) {
for (int i = 0, len = row.getColumnCount(); i < len; i++) {
Value v = row.getValue(i);
if (v.isLinkedToTable()) {
session.removeAtCommit(v);
}
}
}
//獲得存儲數據的map
TransactionMap<Value, Value> map = getMap(session);
try {
//開始刪除
Value old = map.remove(ValueLong.get(row.getKey()));
if (old == null) {
throw DbException.get(ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1,
getSQL() + ": " + row.getKey());
}
} catch (IllegalStateException e) {
throw mvTable.convertException(e);
}
}
往下還有更底層的實現下次再寫附上棧