h2database 源码分析1-核心类

DataChangeStatement类表示数据修改的类。

d7709c6f97c9dba84c36b55ebdb2279a885.jpg

预编译对象,包括比较重要的select

bf228d81d5dcf9c75de80e19666937235e6.jpg

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

28e0395c392a9e25ef69b810bfba05d4d50.jpg

command继承类CommandContainer包括了Prepared对象。

ba6373541e5a72514cd4a2ccc027e1a9bc1.jpg

解析Expression表达式

7742c9f8338b9bf20cf63043426cd50ede1.jpg

数据类型VersionedValue

263b5232b02d32d2b6f76abd7f5d8b1ce41.jpg

结果集,其中继承ResultSet的是JdbcResultSet,ResultInterface不是一个根。但JdbcResultSet种包括ResultInterface对象

00caa78fa29e300eff07cc2ebacc40ccdb3.jpg

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' 调用关系如下

29bc0f584916472b82985515eeecfbdf7bc.jpg

真正执行对比的方法为:

5a8653410915f529a9fe5fe10eadc0fcc56.jpg

没有索引的查询条件为

e411c5e39960d558d3a4d6d33c28c6015f5.jpg

7ca2cbf7d3de2ae6e20bed414f7769ebd14.jpg

 

创建对象过程:

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()来判断是否满足过滤条件。

转载于:https://my.oschina.net/secisland/blog/3066523

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值