Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

MyXOF/HyperSQL

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
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

Morty Proxy This is a proxified and sanitized view of the page, visit original site.