H2数据库更新表字段源码分析

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);
        }
    }

往下还有更底层的实现下次再写附上栈
在这里插入图片描述

发布了6 篇原创文章 · 获赞 3 · 访问量 424

猜你喜欢

转载自blog.csdn.net/weixin_44819430/article/details/104698276