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

来源:互联网 发布:淘宝 买家秀图 编辑:程序博客网 时间:2024/06/12 00:29

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

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

@Testpublic void testExternalDb() throws Exception{Class.forName("org.h2.Driver");Connection conn = DriverManager.getConnection("jdbc:h2:./testdb", "sa", "");// add application code hereStatement 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的一个派生类:
  • 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过滤:

  • 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;}//...}


0 0
原创粉丝点击