h2database源码浅析:SQL语句的执行

时间:2022-08-04 17:45:38

最近想好好了解一下数据库的原理,下载了h2database的源码,准备好好看看。此过程的一些想法,暂且记下来,权当做读码笔记吧!

为了调试准备的测试用例:

	@Test
public void testExternalDb() throws Exception
{
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:./testdb", "sa", "");
// add application code here
Statement stmt = conn.createStatement();
stmt.executeUpdate("DROP TABLE TEST IF EXISTS");
stmt.executeUpdate("CREATE TABLE TEST(ID INT PRIMARY KEY,NAME VARCHAR(255));");
stmt.executeUpdate("INSERT INTO TEST VALUES(100, 'Damn,World');");
stmt.executeUpdate("INSERT INTO TEST VALUES(200, 'Hello,H2');");
stmt.executeUpdate("INSERT INTO TEST VALUES(150, 'Hello,World');");
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST where ID>120 and NAME like 'Hello%'");
while (rs.next())
{
System.out.println(rs.getInt("ID") + "," + rs.getString("NAME"));
}
conn.close();
}

以下为个人的一些猜测,后面会慢慢验证:

  • h2说到底就是内存数据库,其文件版本只是内存内容的持久化,持久化在conn.close()的时候发生;
  • SQL语句会被h2解析成Prepared对象,然后再调用它的update()方法,其中:
    • DDL会编译成DefineCommand
    • DML会编译成Query, Update, Delete等对象
  • 作为例子,CreateTable是DefineCommand的一个派生类:
    aaarticlea/png;base64,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" alt="" style="font-size: 14px;" />
  • Query有2个派生类:Select和SelectUnion
  • Select.query()代码如下:
    		while (topTableFilter.next())
    {
    setCurrentRowNumber(rowNumber + 1);
    if (condition == null || Boolean.TRUE.equals(condition.getBooleanValue(session)))
    {
    Value[] row = new Value[columnCount];
    for (int i = 0; i < columnCount; i++)
    {
    Expression expr = expressions.get(i);
    row[i] = expr.getValue(session);
    } //...
    result.addRow(row);
    rowNumber++;
    //...
    }
    }
  • 可以看到,Select包含一个TableFilter,TableFilter表示待查询的表,它同时包含一个indexConditions,用以实现index过滤:
    aaarticlea/png;base64,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" width="500" alt="" />
  • TableFilter.next()会调用IndexCursor.next(),IndexCursor是根据index得到的记录迭代器,其中find()方法相当于初始化,如针对ID>120会计算出firstRow指向{ID=150}这条记录;
  • TableFilter可以理解成一级过滤(根据索引进行过滤),condition可以理解成二级过滤;
  • condition的类型是Condition,测试用例里的查询会表示成一个ConditionAndOr对象;
  • LocalResult对应于一个查询结果的cache(难道不是延迟加载???),保存了所有的rows,并提供next()方法;
  • Select.query()方法会将查询结果写入LocalResult中,并返回该LocalResult;
  • JdbcStatement会将LocalResult包装成一个JdbcResultSet,返回给JDBC客户端;
    public class JdbcResultSet extends TraceObject implements ResultSet
    {
    //...
    public boolean next() throws SQLException
    {
    try
    {
    debugCodeCall("next");
    checkClosed();
    return nextRow();
    }
    catch (Exception e)
    {
    throw logAndConvert(e);
    }
    } private boolean nextRow()
    {
    boolean next = result.next();
    if (!next && !scrollable)
    {
    result.close();
    }
    return next;
    } //...
    }