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()來判斷是否滿足過濾條件。
數據庫是由一個二維表組成的,二維表就包括行,列和一個格子,這個格子就是數據庫中數據結構對外展示的最小單元。
value就是表示這個最小單元的對象。
SearchRow就表示一行,但行用的地方比較少,主要用的備份恢復,表操作等。
查詢結果主要是在SimpleResult這個對象中,從類中可以看出,主要的內容是列的描述信息和值的信息。這裏的column主要內部用的。在描述表對象中也有一個Column。兩個不是一個對象。
表對象的描述,主要介紹表結構,包括列信息,索引信息等
遊標是在數據庫中也是非常重要的概念,很多取數據都要通過遊標來完成,訪問數據前必須調用next方法
所有數據庫對象的基類,比如一個表,一個索引或者一個用戶。
所有數據對象的基類DbObjectBase
正常的查詢用:query的繼承類Select.queryWithoutCache(int limit, ResultTarget target);
然後調用TableFilter過濾。
然後具體解析用的是Expression體系。