# @cubejs-backend/jdbc 中文文档

规范地址：https://npmcn.com/package/%40cubejs-backend/jdbc/

版本：0\.9\.0
npm 元数据更新时间：2026-06-16T19:23:33.434Z
中文译文更新时间：2026-11-11T04:12:24.628Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40cubejs-backend/jdbc
原文对照：https://npmcn.com/package/%40cubejs-backend/jdbc/?lang=original
项目主页：https://github.com/cube-js/node-jdbc#readme
源码仓库：https://github.com/cube-js/node-jdbc

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：6.6 MB，28 个文件
- 模块格式：CommonJS
- TypeScript 类型：未声明
- Node.js 要求：\>=20
- 运行依赖：4 个
- 首次发布：2023-06-28T18:40:41.143Z
- 最新版本发布：2026-06-16T19:23:33.109Z
- 近 30 天下载量：28974（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：5（近 12 个月 1 个）

## 中文简介

节点模块 JDBC 包装器

## 安装

```sh
npm install @cubejs-backend/jdbc
```

也可以使用：`pnpm add @cubejs-backend/jdbc`、`yarn add @cubejs-backend/jdbc`、`bun add @cubejs-backend/jdbc`

## README

# 节点-jdbc

JDBC 节点的API 包装器

## 正在寻找更活跃的维护者或 sponss

你可能已经注意到了,我无法在几年内积极维持这个项目. 该项目看来将由 很多人,所以我愿意增加合作者, 他们有兴趣更积极的维护。 你们可以 传话给我 [jason.g.ozias@gmail.com (中文(简体) )](mailto:jason.g.ozias@gmail.com)。 。 。 .

如果我收到足够的赞助商利息 我会转而积极维护这个项目.

[![sponsor](https://img.shields.io/github/sponsors/crazysacx?logo=github-sponsors)](https://github.com/sponsors/CraZySacX)

## 最新版本

-   0.7.6 (单位:千美元)

## 安装

-   释放 : `npm i --save jdbc`
-   发展: `npm i --save jdbc@next` (这将从主分支安装代码).

请访问 [节点-jdbc](https://www.npmjs.org/package/jdbc) 关于安装 npm 的信息.

## 状态

[![Build Status](https://travis-ci.org/CraZySacX/node-jdbc.svg?branch=master)](https://travis-ci.org/CraZySacX/node-jdbc)

## 主要 API 重构

-   **一个实例来统治全部(JVM)**

[节点-java](https://github.com/joeferner/node-java) 只有一个JVM实例 由于这个事实,任何JVM选项 和阶级的设置 必须发生 在第一个java呼叫之前。 我创造了一个 小包裹 (jinst.js) 来帮忙。 例如,见下文 用途。 我通常会把这个添加到每个文件 可能是一个切入点。 这个 [单位测试](https://github.com/CraZySacX/node-jdbc/tree/master/test) 这样的设置,因为不能保证秩序.

```javascript
var jinst = require('jdbc/lib/jinst');

// isJvmCreated will be true after the first java call.  When this happens, the
// options and classpath cannot be adjusted.
if (!jinst.isJvmCreated()) {
  // Add all java options required by your project here.  You get one chance to
  // setup the options before the first java call.
  jinst.addOption("-Xrs");
  // Add all jar files required by your project here.  You get one chance to
  // setup the classpath before the first java call.
  jinst.setupClasspath(['./drivers/hsqldb.jar',
                        './drivers/derby.jar',
                        './drivers/derbyclient.jar',
                        './drivers/derbytools.jar']);
}
```

-   **连接集合**

每个人都得到一个游泳池了。 默认没有额外配置, 池 是一个可以保留/释放的连接。 目前 池配置有两个选项: `minpoolsize` 财务报告和审定财务报表 `maxpoolsize`如果 `minpoolsize` 当池子被初始化时, `minpoolsize` 连接 将被创建。 若为 `maxpoolsize` 设置( 默认值为 `minpoolsize`, (中文(简体) ), 你试图保留一个连接 没有可用的,游泳池 将会成长 这可能会发生,直到 `maxpoolsize` 连接已经 保留。 组合在配置后应初始化 `initialize()` 函数。 JDBC 连接随后可以被获取 `reserve()` 函数并返回与 `release()` 函数. 下面是显示这种行为的游泳池的单位测试.

```javascript
var _ = require('lodash');
var nodeunit = require('nodeunit');
var jinst = require('../lib/jinst');
var Pool = require('../lib/pool');

if (!jinst.isJvmCreated()) {
  jinst.addOption("-Xrs");
  jinst.setupClasspath(['./drivers/hsqldb.jar',
                        './drivers/derby.jar',
                        './drivers/derbyclient.jar',
                        './drivers/derbytools.jar']);
}

var config = {
  url: 'jdbc:hsqldb:hsql://localhost/xdb',
  user : 'SA',
  password: '',
  minpoolsize: 2,
  maxpoolsize: 3
};

var testpool = null;
var testconn = null;

module.exports = {
  setUp: function(callback) {
    if (testpool === null) {
      testpool = new Pool(config);
    }
    callback();
  },
  testinitialize: function(test) {
    // Initialize the pool (create minpoolsize connections)
    testpool.initialize(function(err) {
      test.expect(1);
      test.equal(null, err);
      test.done();
    });
  },
  testreserve: function(test) {
    // Reserve a connection.
    testpool.reserve(function(err, conn) {
      test.expect(4);
      test.equal(null, err);
      test.ok(conn && typeof conn == 'object');
      test.equal(testpool._pool.length, 1);
      test.equal(testpool._reserved.length, 1);
      testconn = conn;
      test.done();
    });
  },
  testrelease: function(test) {
    // Release a connection.
    testpool.release(testconn, function(err, conn) {
      test.expect(3);
      test.equal(null, err);
      test.equal(testpool._pool.length, 2);
      test.equal(testpool._reserved.length, 0);
      testconn = null;
      test.done();
    });
  },
  testreserverelease: function(test) {
    // Reserve then release a connection.
    testpool.reserve(function(err, conn) {
      if (err) {
        console.log(err);
      } else {
        testpool.release(conn, function(err) {
          test.expect(3);
          test.equal(null, err);
          test.equal(testpool._pool.length, 2);
          test.equal(testpool._reserved.length, 0);
          test.done();
        });
      }
    });
  },
  testreservepastmin: function(test) {
    // Reserve connections past minpoolsize.  This will grow the pool.
    var conns = [];
    for(i = 0; i < 3; i++) {
      testpool.reserve(function(err, conn) {
        conns.push(conn);
        if (i == 3) {
          test.expect(2);
          test.equal(testpool._pool.length, 0);
          test.equal(testpool._reserved.length, 3);
          _.each(conns, function(conn) {
            testpool.release(conn, function(err) {});
          });
          test.done();
        }
      });
    }
  },
  testovermax: function(test) {
    // Reserve connections past maxpoolsize.  This will max out the pool, and
    // throw an error when the last reserve request is made.
    var conns = [];
    for(i = 0; i < 4; i++) {
      testpool.reserve(function(err, conn) {
        if (err) {
          if (i == 3) {
            test.expect(3);
            test.ok(err);
            test.equal(testpool._reserved.length, 3);
            test.equal(testpool._pool.length, 0);
            _.each(conns, function(conn) {
              testpool.release(conn, function(err) {});
            });
            test.done();
          } else {
            console.log(err);
          }
        } else {
          conns.push(conn);
        }
      });
    }
  }
};
```

-   **完全包装连接 API**

Java Connection API几乎已经完全被包裹了. 见 [连接.js](https://github.com/CraZySacX/node-jdbc/blob/master/lib/connection.js) 用于完整函数列表.

```javascript
conn.setAutoCommit(false, function(err) {
  if (err) {
    callback(err);
  } else {
    callback(null);
  }
});
```

-   **结果集处理与语句执行分离**

结果集处理已从语句执行中分离出来,以便 更加灵活。 执行选定查询返回的结果集可以 仍然被处理成对象数组 `toObjArray()` 函数 结果对象 .

```javascript
// Select statement example.
conn.createStatement(function(err, statement) {
  if (err) {
    callback(err);
  } else {
    statement.executeQuery("SELECT * FROM blah;", function(err, resultset) {
      if (err) {
        callback(err)
      } else {
        // Convert the result set to an object array.
        resultset.toObjArray(function(err, results) {
          if (results.length > 0) {
            console.log("ID: " + results[0].ID);
          }
          callback(null, resultset);
        });
      }
    });
  }
});
```

-   **甲骨文和闭幕发言**

如果您正在经历"ORA-01000:最大开放光标已超过"的出错,可以通过以:

```javascript
statement.close()
```

-   **自动关闭离线连接**

如果你通过一个 **最大值** 属性在新连接池的配置中, `pool.reserve()` 将关闭 stale 连接, 并返回足够新连接, 或新连接 . **最大值** 可以是代表自上次使用连接以来的最大毫秒数的数字,即连接仍然被视为活着(不给数据库额外调用以检查连接是否有效)。 若为 **最大值** 是一个 falsy 值, 或者在配置中没有, 此特性没有生效 。 这个功能是有用的,当连接在一段时间后从服务器侧自动关闭时,当不宜使用连接保存功能时.

## 使用量

下文列举了一些小的例子。 我也创造了一个 [节点实例-jdbc](https://github.com/CraZySacX/node-jdbc-example) 有更详尽实例的项目.

### 初始化

```javascript
var JDBC = require('jdbc');
var jinst = require('jdbc/lib/jinst');

if (!jinst.isJvmCreated()) {
  jinst.addOption("-Xrs");
  jinst.setupClasspath(['./drivers/hsqldb.jar',
                        './drivers/derby.jar',
                        './drivers/derbyclient.jar',
                        './drivers/derbytools.jar']);
}

var config = {
  // Required
  url: 'jdbc:hsqldb:hsql://localhost/xdb',

  // Optional
  drivername: 'my.jdbc.DriverName',
  minpoolsize: 10,
  maxpoolsize: 100,

  // Note that if you sepecify the user and password as below, they get
  // converted to properties and submitted to getConnection that way.  That
  // means that if your driver doesn't support the 'user' and 'password'
  // properties this will not work.  You will have to supply the appropriate
  // values in the properties object instead.
  user: 'SA',
  password: '',
  properties: {}
};

// or user/password in url
// var config = {
//   // Required
//   url: 'jdbc:hsqldb:hsql://localhost/xdb;user=SA;password=',
//
//   // Optional
//   drivername: 'my.jdbc.DriverName',
//   minpoolsize: 10
//   maxpoolsize: 100,
//   properties: {}
// };

// or user/password in properties
// var config = {
//   // Required
//   url: 'jdbc:hsqldb:hsql://localhost/xdb',
//
//   // Optional
//   drivername: 'my.jdbc.DriverName',
//   minpoolsize: 10,
//   maxpoolsize: 100,
//   properties: {
//     user: 'SA',
//     password: ''
//     // Other driver supported properties can be added here as well.
//   }
// };

var hsqldb = new JDBC(config);

hsqldb.initialize(function(err) {
  if (err) {
    console.log(err);
  }
});
```

### 保留连接、 执行查询、 释放连接

```javascript
// This assumes initialization as above.
// For series execution.
var asyncjs = require('async');

hsqldb.reserve(function(err, connObj) {
  // The connection returned from the pool is an object with two fields
  // {uuid: <uuid>, conn: <Connection>}
  if (connObj) {
    console.log("Using connection: " + connObj.uuid);
    // Grab the Connection for use.
    var conn = connObj.conn;

    // Adjust some connection options.  See connection.js for a full set of
    // supported methods.
    asyncjs.series([
      function(callback) {
        conn.setAutoCommit(false, function(err) {
          if (err) {
            callback(err);
          } else {
            callback(null);
          }
        });
      },
      function(callback) {
        conn.setSchema("test", function(err) {
          if (err) {
            callback(err);
          } else {
            callback(null);
          }
        });
      }
    ], function(err, results) {
      // Check for errors if need be.
      // results is an array.
    });

    // Query the database.
    asyncjs.series([
      function(callback) {
        // CREATE SQL.
        conn.createStatement(function(err, statement) {
          if (err) {
            callback(err);
          } else {
            statement.executeUpdate("CREATE TABLE blah "
                                  + "(id int, name varchar(10), date DATE, "
                                  + " time TIME, timestamp TIMESTAMP);",
                                  function(err, count) {
              if (err) {
                callback(err);
              } else {
                callback(null, count);
              }
            });
          }
        });
      },
      function(callback) {
        conn.createStatement(function(err, statement) {
          if (err) {
            callback(err);
          } else {
            statement.executeUpdate("INSERT INTO blah "
                                  + "VALUES (1, 'Jason', CURRENT_DATE, "
                                  + "CURRENT_TIME, CURRENT_TIMESTAMP);",
                                  function(err, count) {
              if (err) {
                callback(err);
              } else {
                callback(null, count);
              }
            });
          }
        });
      },
      function(callback) {
        // Update statement.
        conn.createStatement(function(err, statement) {
          if (err) {
            callback(err);
          } else {
            statement.executeUpdate("UPDATE blah "
                                  + "SET id = 2 "
                                  + "WHERE name = 'Jason';",
                                  function(err, count) {
              if (err) {
                callback(err);
              } else {
                callback(null, count);
              }
            });
          }
        });
      },
      function(callback) {
        // Select statement example.
        conn.createStatement(function(err, statement) {
          if (err) {
            callback(err);
          } else {
            // Adjust some statement options before use.  See statement.js for
            // a full listing of supported options.
            statement.setFetchSize(100, function(err) {
              if (err) {
                callback(err);
              } else {
                statement.executeQuery("SELECT * FROM blah;",
                                       function(err, resultset) {
                  if (err) {
                    callback(err)
                  } else {
                    resultset.toObjArray(function(err, results) {
                      if (results.length > 0) {
                        console.log("ID: " + results[0].ID);
                      }
                      callback(null, resultset);
                    });
                  }
                });
              }
            });
          }
        });
      },
      function(callback) {
        conn.createStatement(function(err, statement) {
          if (err) {
            callback(err);
          } else {
            statement.executeUpdate("DELETE FROM blah "
                                  + "WHERE id = 2;", function(err, count) {
              if (err) {
                callback(err);
              } else {
                callback(null, count);
              }
            });
          }
        });
      },
      function(callback) {
        conn.createStatement(function(err, statement) {
          if (err) {
            callback(err);
          } else {
            statement.executeUpdate("DROP TABLE blah;", function(err, count) {
              if (err) {
                callback(err);
              } else {
                callback(null, count);
              }
            });
          }
        });
      }
    ], function(err, results) {
      // Results can also be processed here.
      // Release the connection back to the pool.
      hsqldb.release(connObj, function(err) {
        if (err) {
          console.log(err.message);
        }
      });
    });
  }
});
```

## 常见问题

### @cubejs-backend/jdbc 是什么？

节点模块 JDBC 包装器

### 如何安装 @cubejs-backend/jdbc？

在项目目录运行 npm install @cubejs-backend/jdbc，或使用 pnpm add / yarn add / bun add。

### @cubejs-backend/jdbc 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/cubejs-backend\_\_jdbc 是否存在。

### @cubejs-backend/jdbc 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @cubejs-backend/jdbc 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=20。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @cubejs-backend/jdbc 可以商用吗？

@cubejs-backend/jdbc 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @cubejs-backend/jdbc 的下载量有多少？

根据 npm 官方下载统计，@cubejs-backend/jdbc 在 2026/10/11 – 2026/11/09 这 30 天内被下载 28,974 次，日均约 966 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @cubejs-backend/jdbc 还在维护吗？

最新版本 0\.9\.0 发布于 2026/06/17（4 个月前）；至今共发布 5 个版本，其中过去 12 个月发布了 1 个；首次发布于 2023/06/29。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

