h2database 源碼分析-核心類

DataChangeStatement類表示數據修改的類。

預編譯對象,包括比較重要的select

命令執行CommandInterface,比較重要的接口是ResultInterface executeQuery(int maxRows, boolean scrollable);

command繼承類CommandContainer包括了Prepared對象。

解析Expression表達式

數據類型VersionedValue

結果集,其中繼承ResultSet的是JdbcResultSet,ResultInterface不是一個根。但JdbcResultSet種包括ResultInterface對象

jdbcdemo

        Class.forName("com.mysql.jdbc.Driver");
 
        //獲取連接
        String url = "jdbc:mysql://localhost:3306/jdbc";
        String user = "root";
        String password = "password";
        Connection conn = DriverManager.getConnection(url, user, password);
 
        //得到運行環境
        Statement st = conn.createStatement();
 
        //執行SQL
        String sql = "select * from myuser";
        ResultSet rs = st.executeQuery(sql);

我們看下核心的方法st.executeQuery(sql),在h2中如何實現的

    public ResultSet executeQuery(String sql) throws SQLException {
        try {
            int id = getNextId(TraceObject.RESULT_SET);
            if (isDebugEnabled()) {
                debugCodeAssign("ResultSet", TraceObject.RESULT_SET, id,
                        "executeQuery(" + quote(sql) + ")");
            }
            synchronized (session) {
                checkClosed();
                closeOldResultSet();
                sql = JdbcConnection.translateSQL(sql, escapeProcessing);
                CommandInterface command = conn.prepareCommand(sql, fetchSize);
                ResultInterface result;
                boolean lazy = false;
                boolean scrollable = resultSetType != ResultSet.TYPE_FORWARD_ONLY;
                boolean updatable = resultSetConcurrency == ResultSet.CONCUR_UPDATABLE;
                setExecutingStatement(command);
                try {
                    result = command.executeQuery(maxRows, scrollable);
                    lazy = result.isLazy();
                } finally {
                    if (!lazy) {
                        setExecutingStatement(null);
                    }
                }
                if (!lazy) {
                    command.close();
                }
                resultSet = new JdbcResultSet(conn, this, command, result, id,
                        closedByResultSet, scrollable, updatable);
            }
            return resultSet;
        } catch (Exception e) {
            throw logAndConvert(e);
        }
    }

查詢的調用關係如下:

st.executeQuery(sql)->CommandInterface.executeQuery(maxRows, scrollable)->Prepared.query(maxrows)->Select.queryWithoutCache(maxRows,target)

tableFilter負責查詢數據庫記錄,然後isConditionMet負責判斷條件是否符合,符合條件後,拼接成一個row,然後返回。

        protected Value[] fetchNextRow() {
            //查找記錄
            while ((sampleSize <= 0 || rowNumber < sampleSize) && topTableFilter.next()) {
                setCurrentRowNumber(rowNumber + 1);
                // This method may lock rows
                //isConditionMet判斷查詢條件是否符合過濾條件
                if (forUpdate ? isConditionMetForUpdate() : isConditionMet()) {
                    ++rowNumber;
                    Value[] row = new Value[columnCount];
                    for (int i = 0; i < columnCount; i++) {
                        Expression expr = expressions.get(i);
                        row[i] = expr.getValue(getSession());
                    }
                    return row;
                }
            }
            return null;
        }

有索引查詢一個條件的函數,例如usercode='a' 調用關係如下

真正執行對比的方法爲:

沒有索引的查詢條件爲

 

創建對象過程:

TcpServerThread-》得到Session(Engine.createSession())-》得到Command(session.prepareLocal(sql))-》common由Parser產生(parser.prepareCommand(sql)),對查詢開說parse就是Select對象。

得到command對象後,查詢結果是result = command.executeQuery(maxRows, false);-》CommandContainer.query()->prepared.query(maxrows);然後調用select.queryFlat().->LazyResultQueryFlat.fetchNextRow()->TableFilter.next()獲取數據,獲取數據後調用Expression.getBooleanValue()來判斷是否滿足過濾條件。

 

數據庫是由一個二維表組成的,二維表就包括行,列和一個格子,這個格子就是數據庫中數據結構對外展示的最小單元。

value就是表示這個最小單元的對象。

SearchRow就表示一行,但行用的地方比較少,主要用的備份恢復,表操作等。

查詢結果主要是在SimpleResult這個對象中,從類中可以看出,主要的內容是列的描述信息和值的信息。這裏的column主要內部用的。在描述表對象中也有一個Column。兩個不是一個對象。

表對象的描述,主要介紹表結構,包括列信息,索引信息等

遊標是在數據庫中也是非常重要的概念,很多取數據都要通過遊標來完成,訪問數據前必須調用next方法

所有數據庫對象的基類,比如一個表,一個索引或者一個用戶。

所有數據對象的基類DbObjectBase

正常的查詢用:query的繼承類Select.queryWithoutCache(int limit, ResultTarget target);

然後調用TableFilter過濾。

然後具體解析用的是Expression體系。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章