Skip to content

MyXOF/HyperSQL

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 

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”

public int start() {
  //ignore some codes..

  serverThread = new ServerThread("HSQLDB Server ");

  if (isDaemon) {
    serverThread.setDaemon(true);
  }

  serverThread.start();

  //ignore some codes..

  return previousState;
}

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

private void run() {

  //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 use
    openServerSocket();
  } catch (Exception e) {
    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.InterruptedIOException iioe) {}
    }
  } catch (IOException ioe) {
    if (getState() == ServerConstants.SERVER_STATE_ONLINE) {
      setServerError(ioe);
      printError(this + ".run()/handleConnection(): ");
      printStackTrace(ioe);
    }
  } catch (Throwable t) {
    printWithThread(t.toString());
  } finally {
    shutdown(false);    // or maybe getServerError() != null?
  }
}

public void handleConnection(Socket s) {
 
  Thread   t;
  Runnable r;
  String   ctn;

  //ignore some codes...

  if (serverProtocol == ServerConstants.SC_PROTOCOL_HSQL) {
    r   = new ServerConnection(s, this);
    ctn = ((ServerConnection) r).getConnectionThreadName();
  } else {
    r   = new WebServerConnection(s, (WebServer) this);
    ctn = ((WebServerConnection) r).getConnectionThreadName();
  }

  t = new Thread(serverConnectionThreadGroup, r, ctn);

  t.start();
  printWithThread("handleConnection() exited");
}

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

private void odbcExecDirect(String inStatement)  throws RecoverableOdbcFailure, IOException {
  //ignore some codes...

  Result r = Result.newExecuteDirectRequest();

  r.setPrepareOrExecuteProperties(
    statement, 0, 0, StatementTypes.RETURN_COUNT, 0,
    ResultProperties.defaultPropsValue,
    ResultConstants.RETURN_NO_GENERATED_KEYS, null, null);

  Result rOut = session.execute(r);

  //ignore some codes...
}

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

case ResultConstants.EXECDIRECT : {
  Result result = executeDirectStatement(cmd);

  result = performPostExecute(cmd, result);
  return result;
}
case ResultConstants.BATCHEXECDIRECT : {
  isBatch = true;

  Result result = executeDirectBatchStatement(cmd);

  result = performPostExecute(cmd, result);
  return result;
}

对于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进行操作。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class HyperSQLTest {
	
	public static void main(String[] args) throws SQLException {
		Connection conn = null;
        String sql;

        String url = "jdbc:hsqldb:hsql://127.0.0.1:9001";
        try {

        	Class.forName("org.hsqldb.jdbcDriver");
            System.out.println("成功加载HyperSQL驱动程序");
            conn = DriverManager.getConnection(url);
            Statement stmt = conn.createStatement();
            
            sql = "create table student(NO char(20),name varchar(20),primary key(NO))";
            int result = 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";
                ResultSet rs = stmt.executeQuery(sql);// executeQuery会返回结果的集合,否则返回空值
                System.out.println("学号\t姓名");
                while (rs.next()) {
                    System.out.println(rs.getString(1) + "\t" + rs.getString(2));// 入如果返回的是int类型可以用getInt()
                }
            }
        } catch (SQLException e) {
            System.out.println("HyperSQL操作错误");
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.close();
        }
	}
}

About

HyperSQL source code. A maven project

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages