h2database源码浅析:SQL语句的执行
最近想好好了解一下数据库的原理,下载了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的一个派生类:
- 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; } //... }
+++++++++++++++++++++++++++++++++++++++++++
如本文存在任何侵权部分,请及时告知,我会第一时间删除!
转载本博客原创文章,请附上原文@cnblogs的网址!
QQ: 5854165 我的开源项目 欢迎大家一起交流编程架构技术&大数据技术! +++++++++++++++++++++++++++++++++++++++++++
如本文存在任何侵权部分,请及时告知,我会第一时间删除!
转载本博客原创文章,请附上原文@cnblogs的网址!
QQ: 5854165 我的开源项目 欢迎大家一起交流编程架构技术&大数据技术! +++++++++++++++++++++++++++++++++++++++++++