2.5.1、数据库初始化

维基数据库模式由一个单独的Pages表组成,其中包含以下列:

类型 描述
Id Integer 主键
Name Charactors 维基页面的名称, 必须是独一无二的
Content Text 维基页面的Markdown文本

数据库操作将是典型的创建,读取,更新,删除操作。为简单起见,我们将相应的SQL查询作为MainVerticle类的静态字段存储。 请注意,它们是用HSQLDB能理解的SQL方言编写的, 但是其他关系数据库可能不一定支持:

private static final String SQL_CREATE_PAGES_TABLE = "create table if not exists Pages (Id integer identity primary key, Name varchar(255) unique, Content clob)";
private static final String SQL_GET_PAGE = "select Id, Content from Pages where Name = ?"; (1)
private static final String SQL_CREATE_PAGE = "insert into Pages values (NULL, ?, ?)";
private static final String SQL_SAVE_PAGE = "update Pages set Content = ? where Id = ?";
private static final String SQL_ALL_PAGES = "select Name from Pages";
private static final String SQL_DELETE_PAGE = "delete from Pages where Id = ?";

查询中的?号是占位符,用于在执行查询时传递数据,且可让Vert.x JDBC客户端防止SQL注入。

应用的Verticle需要持有作为数据库连接的JDBCClient对象(来自io.vertx.ext.jdbc包)的引用。我们使用MainVerticle中的一个字段存储这个引用,我们也使用来自org.slf4j包包的类创建一个通用日志记录器:

private JDBCClient dbClient;
private static final Logger LOGGER = LoggerFactory.getLogger(MainVerticle.class);

以下是prepareDatabase方法的完整实现。 它尝试获取一个JDBC客户端连接, 然后如果Pages表不存在,则执行SQL查询以创建Pages表:

  private Future<Void> prepareDatabase() {
    Future<Void> future = Future.future();
    dbClient = JDBCClient.createShared(vertx, new JsonObject()  (1)
      .put("url", "jdbc:hsqldb:file:db/wiki")   (2)
      .put("driver_class", "org.hsqldb.jdbcDriver")   (3)
      .put("max_pool_size", 30));   (4)

    dbClient.getConnection(ar -> {    (5)
      if (ar.failed()) {
        LOGGER.error("Could not open a database connection", ar.cause());
        future.fail(ar.cause());    (6)
      } else {
        SQLConnection connection = ar.result();   (7)
        connection.execute(SQL_CREATE_PAGES_TABLE, create -> {
          connection.close();   (8)
          if (create.failed()) {
            LOGGER.error("Database preparation error", create.cause());
            future.fail(create.cause());
          } else {
            future.complete();  (9)
          }
        });
      }
    });

    return future;
  }
  1. createShared创建一个共享连接,以便在vertx已知的Verticles之间共享,一般来说,这是一件好事;

  2. JDBC客户端连接是通过传递一个Vert.x JSON对象来实现的。这里的url是JDBC URL;

  3. 就像url一样,driver_class是特定于正在使用的JDBC驱动程序,指向驱动程序类;

  4. max_pool_size是并发连接数。我们在这里选择了30,但只是一个任意数;

  5. 获取连接是一个异步操作,给我们一个AsyncResult <SQLConnection>。然后必须进行测试以查看是否可以建立连接(实际上AsyncResult是Future的超级接口);

  6. 如果无法获取SQL连接,则Future的方法将会失败,失败的内容是通过cause方法提供的AsyncResult提供的异常;

  7. SQLConnection是AsyncResult成功的结果。我们可以使用它来执行SQL查询;

  8. 在检查SQL查询是否成功之前,我们必须通过调用close来释放它,否则JDBC客户端连接池最终可能会耗尽;

  9. 成功完成Future的方法。

Vert.x项目支持的SQL数据库模块目前不提供超出传递SQL查询(例如,对象关系映射器)的任何内容,因为它们专注于提供对数据库的异步访问。 然而,没有什么禁止使用来自社区的更先进的模块,我们特别建议检查社区其它的项目,如这个jooq的Vert.x生成器或POJO映射器。

results matching ""

    No results matching ""