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