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);
}
}
往下还有更底层的实现下次再写附上栈