Vert.x JDBC Client

原文档:Vert.x JDBC Client

使用 Vert.x JDBC Client,可以让我们的 Vert.x 应用程序通过异步的方式,与任何支持 JDBC 的数据库进行交互。

Vert.x JDBC Client 的接口定义为 JDBCClient

要使用Vert.x JDBC Client,需要添加下面的依赖:

  • Maven (在 pom.xml 文件中):
  1. <dependency>
  2. <groupId>io.vertx</groupId>
  3. <artifactId>vertx-jdbc-client</artifactId>
  4. <version>3.4.1</version>
  5. </dependency>
  • Gradle (在 build.gradle 文件中):
  1. compile 'io.vertx:vertx-jdbc-client:3.4.1'

创建 Vert.x JDBC Client 对象

接下来,我们一起来看下创建 Vert.x JDBC Client 对象的几种方式。

默认使用共享的数据源

大部分情况下,我们希望在不同的 Vert.x JDBC Client 对象之间,共享一个数据源。

考虑这样一种情况:我们在部署 Verticle 时,设置了 Verticle 拥有多个实例化的对象,但是我们希望每个 Verticle 实例能够共享同一个数据源,而不是单独为每个 Verticle 实例设置不同的数据源。

要解决上面的问题,我们可以这么做:

  1. JDBCClient client = JDBCClient.createShared(vertx, config);

只有在第一次调用 JDBCClient.createShared 方法的时候,才会真正的根据 config 参数创建一个数据源。

之后再调用此方法,只会返回一个新的 Vert.x JDBC Client 对象,但使用的是相同的数据源。这时 config 参数也就不再有作用。

指定数据源名称

我们还可以像下面这样,在创建一个 Vert.x JDBC Client 对象的时候指定数据源的名称:

  1. JDBCClient client = JDBCClient.createShared(vertx, config, "MyDataSource");

如果不同的 Vert.x JDBC client 对象使用了相同的Vert.x 对象和相同的数据源名称,那么它们将共享数据源。

同样的(与默认使用共享的数据源),只有在第一次调用JDBCClient.createShared方法的时候,才会真正的根据 config 参数创建一个数据源。

之后再调用此方法,只会返回一个新的 Vert.x JDBC Client 对象,但使用的是相同的数据源。这时 config 参数也就不再有作用。

当我们希望不同含义的 Vert.x JDBC Client 对象拥有不同的数据源时,可以采用这种方式来创建它的对象。比如它们要与不同的数据源进行交互。

创建不共享数据源的 Vert.x JDBC Client 对象

在大部分情况下,我们会希望在不同的 Vert.x JDBC Client 对象之间共享数据源。但有时候,却恰恰相反。

这时,可以调用 JDBCClient.createNonShared 方法:

  1. JDBCClient client = JDBCClient.createNonShared(vertx, config);

每次调用此方法,就相当于在调用 JDBCClient.createShared 方法时加上了具有唯一名称的数据源参数。

指定数据源

如果我们已经存在一个数据源,也可以在创建 Vert.x JDBC Client 对象的时候就直接指定它:

  1. JDBCClient client = JDBCClient.create(vertx, dataSource);

关闭客户端

我们可以较长时间的持有 Vert.x JDBC Client 对象(比如在 Verticle 的整个生命周期里),可一旦不再使用它后,就应该关闭它。

在多个 Vert.x JDBC Client 对象共享数据源的情况下,这个数据源对象维护着一个引用计数器。一旦此数据源最后一个引用关闭后,这个数据源也就关闭了。

在 Verticle 中自动关闭

我们在 Verticle 中创建的 Vert.x JDBC Client 对象,会在这些 Verticle 卸载(undeploy)的时候自动关闭。

获取数据库连接

在创建 Vert.x JDBC Client 对象后,我们可以通过 getConnection 方法来获取一个数据库连接。

此方法从连接池中获取一个数据库连接,并返回给回调方法:

  1. client.getConnection(res -> {
  2. if (res.succeeded()) {
  3. SQLConnection connection = res.result();
  4. connection.query("SELECT * FROM some_table", res2 -> {
  5. if (res2.succeeded()) {
  6. ResultSet rs = res2.result();
  7. // 用结果集results进行其他操作
  8. }
  9. });
  10. } else {
  11. // 获取连接失败 - 处理失败的情况
  12. }
  13. });

获取的这个连接,是接口 SQLConnection 的一个实现。但是 SQLConnection 是一个通用接口,不只是在 Vert.x JDBC Client 中有用到。

更多详细内容,可以参考文档 Vert.x Common SQL Interface

配置参数

在 Vert.x JDBC Client 创建或者部署的时候,我们应该把对应的配置参数传给它。

常用的配置参数有下面这些:

  • provider_class

    此参数确定管理数据库连接池的实现类,默认是io.vertx.ext.jdbc.spi.impl.C3P0DataSourceProvider 。如果我们想使用其他的类,可以自己设置这个参数,但参数对应的类,必须实现接口DataSourceProvider

  • row_stream_fetch_size

    为了提升性能,SQLRowStream 设置有内部缓存。默认缓存大小为 128

若我们使用的是 Vert.x 默认的 C3P0(DataSourceProvider),可以使用下面的配置参数:

  • url

    数据库 JDBC 连接地址

  • driver_class

    JDBC 驱动

  • user

    数据库用户名

  • password

    数据库密码

  • max_pool_size

    连接池最大连接数,默认15

  • initial_pool_size

    连接池初始连接数,默认3

  • min_pool_size

    连接池最小连接数

  • max_statements

    预处理SQL语句最小缓存数,默认 0

  • max_statements_per_connection

    每个数据库连接的最大预处理SQL缓存数,默认0

  • max_idle_time

    空闲连接保留时间,默认0 (代表一直保留)

其它连接池实现:

  • BoneCP
  • Hikari

类似于 C3P0,上面的连接池也可以通过传递一个 JsonObject 对象来配置参数。考虑这样一种情况,应用程序要运行在一个 Vert.x 环境中,但我们却不想通过 fat jar 的方式来部署,且在没有权限把 JDBC 驱动包加到 Vert.x lib 目录下的时候,建议使用 BoneCP,并在命令行上加上-cp标示。

如果想要配置 C3P0 更多的参数,我们可以在 classpath 下添加文件c3p0.properties

例如:

  1. JsonObject config = new JsonObject()
  2. .put("url", "jdbc:hsqldb:mem:test?shutdown=true")
  3. .put("driver_class", "org.hsqldb.jdbcDriver")
  4. .put("max_pool_size", 30);
  5. JDBCClient client = JDBCClient.createShared(vertx, config);

需要注意,Hikari 使用的配置参数不一样:

  • jdbcUrl 数据库 JDBC 连接地址
  • driverClassName JDBC 驱动类名
  • maximumPoolSize 连接池最大连接数
  • username 数据库用户名 (password 数据库密码)

可以阅读 Hikari documentationBoneCP documentation 来了解更多关于两个数据源的知识。

JDBC 驱动

如果使用默认的DataSourceProvider实现类(C3P0实现),我们要把JDBC 驱动jar包放在编译路径下。

如果我们的 Vert.x 应用程序打包成 fat jar,要确保 JDBC 驱动包含在里面。如果我们的 Vert.x 应用程序通过 vertx 命令行启动,要确保 JDBC 驱动包在 ${VERTX_HOME}/lib 路径里面。

使用不同的连接池时,可能会稍有不一样。

数据类型

由于 Vert.x 使用 JSON 作为标准的消息格式,这使得客户端在接受数据类型时受到很多限制。我们只能从 JsonObject 获得下面的数据类型:

  • null
  • boolean
  • number
  • string

时间类型 (TIME, DATE, TIMESTAMP) 可以自动转换。需要注意的是,我们可以选择性的使用 UUID 的转换。虽然大部分数据库都支持 UUID,可并不是所有都支持,比如说 MySQL 就不支持。这种情况下,建议使用 VARCHAR(36) 类型的字段。对于其他支持 UUID 的数据库来说,使用下面的参数后,可以对 UUID 进行自动类型转换。

  1. { "castUUID": true }

这样,UUID 将会被作为原生类型(译者注:java.util.UUID)来处理。

作为 OSGI 应用程序

Vert.x JDBC Client 也可以作为 OSGI 应用程序。但是,必须首先部署它所有的依赖。但有些连接池要求必须从 classpath 加载 JDBC 驱动,这样的就不能作为 OSGI 应用程序。


原文档更新于2017-03-15 15:54:14 CET