Skip to content

Latest commit

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

HyperSQL

Build Status

包含了HyperSQL项目的源码,已经转化为Maven项目,可以用Eclipse或者IDEA直接导入。

代码分析

Server

org.hssqldb.server.Server是启动的入口,运行这个类在控制台里会出现下面的输出:

[Server@28d93b30]: Startup sequence initiated from main() method
[Server@28d93b30]: Could not load properties from file
[Server@28d93b30]: Using cli/default properties only
[Server@28d93b30]: Initiating startup sequence...
[Server@28d93b30]: Server socket opened successfully in 6 ms.
[Server@28d93b30]: Database [index=0, id=0, db=file:test, alias=] opened successfully in 3233 ms.
[Server@28d93b30]: Startup sequence completed in 3241 ms.
[Server@28d93b30]: 2018-01-31 11:19:44.077 HSQLDB server 2.3.5 is online on port 9001
[Server@28d93b30]: To close normally, connect and execute SHUTDOWN SQL
[Server@28d93b30]: From command line, use [Ctrl]+[C] to abort abruptly

输出信息中比较有用的是[Server@28d93b30]: 2018-01-31 11:19:44.077 HSQLDB server 2.3.5 is online on port 9001 这一行,这表明服务器现在监听9001端口,之后如果要用JDBC去连接,端口就是9001。

程序内部将启动一个后台线程serverThread,名字是“HSQLDB Server”

publicintstart() {
//ignore some codes..serverThread = newServerThread("HSQLDB Server ");
if (isDaemon) {
serverThread.setDaemon(true);
}
serverThread.start();
//ignore some codes..returnpreviousState;
}

在serverThread启动的过程中会打开socket连接,用于处理外部的请求。对于每到来的一个请求,都会创建一个线程进行处理。

privatevoidrun() {
//ignore some codes...try {
// Faster init first:// It is huge waste to fully open the databases, only// to find that the socket address is already in useopenServerSocket();
} catch (Exceptione) {
setServerError(e);
printError("run()/openServerSocket(): ");
printStackTrace(e);
shutdown(true);
return;
}
//ignore some codes...try {
/* * This loop is necessary for UNIX w/ Sun Java 1.3 because * in that case the socket.close() elsewhere will not * interrupt this accept(). */while (socket != null) {
try {
handleConnection(socket.accept());
} catch (java.io.InterruptedIOExceptioniioe) {}
}
} catch (IOExceptionioe) {
if (getState() == ServerConstants.SERVER_STATE_ONLINE) {
setServerError(ioe);
printError(this + ".run()/handleConnection(): ");
printStackTrace(ioe);
}
} catch (Throwablet) {
printWithThread(t.toString());
} finally {
shutdown(false); // or maybe getServerError() != null?
}
}
publicvoidhandleConnection(Sockets) {
Threadt;
Runnabler;
Stringctn;
//ignore some codes...if (serverProtocol == ServerConstants.SC_PROTOCOL_HSQL) {
r = newServerConnection(s, this);
ctn = ((ServerConnection) r).getConnectionThreadName();
} else {
r = newWebServerConnection(s, (WebServer) this);
ctn = ((WebServerConnection) r).getConnectionThreadName();
}
t = newThread(serverConnectionThreadGroup, r, ctn);
t.start();
printWithThread("handleConnection() exited");
}

在ServerConnection类中,最终转到了odbcExecDirect函数里面的session.execute(r)方法对SQL语句进行处理。

privatevoidodbcExecDirect(StringinStatement) throwsRecoverableOdbcFailure, IOException {
//ignore some codes...Resultr = Result.newExecuteDirectRequest();
r.setPrepareOrExecuteProperties(
statement, 0, 0, StatementTypes.RETURN_COUNT, 0,
ResultProperties.defaultPropsValue,
ResultConstants.RETURN_NO_GENERATED_KEYS, null, null);
ResultrOut = session.execute(r);
//ignore some codes...
}

在Session的execute方法里面EXECDIRECT和BATCHEXECDIRECT分别代表单条执行SQL语句和批量执行SQL语句所对应的逻辑。executeXXXStatement方法负责解析SQL语句并执行,performPostExecute方法负责将结果返回。

caseResultConstants.EXECDIRECT : {
Resultresult = executeDirectStatement(cmd);
result = performPostExecute(cmd, result);
returnresult;
}
caseResultConstants.BATCHEXECDIRECT : {
isBatch = true;
Resultresult = executeDirectBatchStatement(cmd);
result = performPostExecute(cmd, result);
returnresult;
}

对于SQL解析部分,HyperSQL里面没有采用流行的开源工具antlr而是自己实现了解析,这里不做过多分析。

JDBC

如果想通过JDBC连接HyperSQL,首先需要在pom文件中加入下面的依赖:

<!-- https://mvnrepository.com/artifact/org.hsqldb/hsqldb -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.4.0</version>
</dependency>

之后可以通过标准的SQL语句对HyperSQL进行操作。

importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.ResultSet;
importjava.sql.SQLException;
importjava.sql.Statement;
publicclassHyperSQLTest {
publicstaticvoidmain(String[] args) throwsSQLException {
Connectionconn = null;
Stringsql;
Stringurl = "jdbc:hsqldb:hsql://127.0.0.1:9001";
try {
Class.forName("org.hsqldb.jdbcDriver");
System.out.println("成功加载HyperSQL驱动程序");
conn = DriverManager.getConnection(url);
Statementstmt = conn.createStatement();
sql = "create table student(NO char(20),name varchar(20),primary key(NO))";
intresult = stmt.executeUpdate(sql);// executeUpdate语句会返回一个受影响的行数,如果返回-1就没有成功if (result != -1) {
System.out.println("创建数据表成功");
sql = "insert into student(NO,name) values('2012001','123')";
result = stmt.executeUpdate(sql);
sql = "insert into student(NO,name) values('2012002','123')";
result = stmt.executeUpdate(sql);
sql = "select * from student";
ResultSetrs = stmt.executeQuery(sql);// executeQuery会返回结果的集合,否则返回空值System.out.println("学号\t姓名");
while (rs.next()) {
System.out.println(rs.getString(1) + "\t" + rs.getString(2));// 入如果返回的是int类型可以用getInt()
}
}
} catch (SQLExceptione) {
System.out.println("HyperSQL操作错误");
e.printStackTrace();
} catch (Exceptione) {
e.printStackTrace();
} finally {
conn.close();
}
}
}

About

HyperSQL source code. A maven project

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages