📜 Node 使用 达梦数据库
先创建一个 node 项目。
npm init -y
1
然后安装对应的依赖
npm install -g node-gyp
npm install iconv-lite snappy
npm install dmdb
1
2
3
2
3
+ dmdb@1.0.5537
added 67 packages from 46 contributors in 4.72s
2 packages are looking for funding
run `npm fund` for details
1
2
3
4
5
2
3
4
5
这样就成功了
demo 对应版本:
{
"dependencies": {
"dmdb": "^1.0.5537",
"iconv-lite": "^0.6.3",
"snappy": "^7.0.1"
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
dmdb 使用了 c++ ,安装的时候会根据你的 os 生成
node_modules/dmdb/node_modules/snappy/build/Release/binding.node。如果你部署的环境 不 能 访 问 外 网 ,就会产生一个问题:你在 Mac 上生成的
binding.node在 Linux 是不能使用的。这一点需要注意。
创建测试表
构建一个测试用的表。
DataDrip 可以连接 DM 数据库。
create table demo(
`id` bigint unsigned NOT NULL AUTO_INCREMENT ,
`text` VARCHAR COMMENT 'todo',
primary key (id)
)
1
2
3
4
5
6
2
3
4
5
6
代码
首先 先准备 数据库的配置信息
const dbConfig = {
user: "CCPMAIN38",
pwd: "2b780262db7951c5a4adf20e8ea78dea", // pwd 不要有特殊字符
host: "10.14.65.107",
port: "5238",
};
1
2
3
4
5
6
2
3
4
5
6
达梦是一个用户一个库,所以配置就这四个就够了。
密码要注意一下,不要使用特殊字符,如#,除非你想看见 Error。
如果一定要用复杂的密码,可以使用 UUID。
然后是 连接数据库 的代码
const dm = require("dmdb");
class DmDB {
#pool;
constructor() {}
// 初始化连接池
init = async () => {
const { user, pwd, host, port } = dbConfig;
this.#pool = await dm.createPool({
connectString: `dm://${user}:${pwd}@${host}:${port}?autoCommit=false`,
poolMax: 10,
poolMin: 1,
});
};
getConnection = async () => {
return await this.#pool.getConnection();
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
最后编写 CURD 的测试代码
const db = new DmDB();
(async () => {
await db.init();
const conn = await db.getConnection();
const sql = `INSERT INTO demo(text) VALUES ('试试就试试')`;
const create = await conn.execute(sql);
console.log(create);
const select = `select * from demo`;
const query = await conn.execute(select);
console.log(query);
await conn.commit();
})().catch(console.log);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
注意这个 conn.commit() , 不 commit ,数据库不会实际生效!
完整的 Demo
const dm = require("dmdb");
const dbConfig = {
user: "test",
pwd: "123123", // pwd 不要有特殊字符
host: "10.14.65.107",
port: "5236",
};
class DmDB {
#pool;
constructor() {}
// 初始化连接池
init = async () => {
const { user, pwd, host, port } = dbConfig;
this.#pool = await dm.createPool({
connectString: `dm://${user}:${pwd}@${host}:${port}?autoCommit=false`,
poolMax: 10,
poolMin: 1,
});
};
getConnection = async () => {
return await this.#pool.getConnection();
};
}
const db = new DmDB();
(async () => {
await db.init();
const conn = await db.getConnection();
const sql = `INSERT INTO demo(text) VALUES ('试试就试试')`;
const create = await conn.execute(sql);
console.log(create);
const select = `select * from demo`;
const query = await conn.execute(select);
console.log(query);
await conn.commit();
})().catch(console.log);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
官方 Demo
参考
/*该例程实现插入数据,修改数据,删除数据,数据查询等基本操作。*/
// 引入 dmdb 包
var db = require("dmdb");
var fs = require("fs");
var pool, conn;
async function example() {
try {
pool = await createPool();
conn = await getConnection();
await insertTable();
await updateTable();
await queryTable();
await queryWithResultSet();
await deleteTable();
} catch (err) {
console.log(err);
} finally {
try {
await conn.close();
await pool.close();
} catch (err) {}
}
}
example();
/* 创建连接池 */
async function createPool() {
try {
return db.createPool({
connectString:
"dm://CCPMAIN:HY#witccp#123@10.14.65.107:5238?autoCommit=false",
poolMax: 10,
poolMin: 1,
});
} catch (err) {
throw new Error("createPool error: " + err.message);
}
}
/* 获取数据库连接 */
async function getConnection() {
try {
return pool.getConnection();
} catch (err) {
throw new Error("getConnection error: " + err.message);
}
}
/* 往产品信息表插入数据 */
async function insertTable() {
try {
var sql =
"INSERT INTO production.product(name,author,publisher,publishtime," +
"product_subcategoryid,productno,satetystocklevel,originalprice,nowprice,discount," +
"description,photo,type,papertotal,wordtotal,sellstarttime,sellendtime) " +
"VALUES(:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17);";
var blob = fs.createReadStream("c:\\三国演义.jpg");
await conn.execute(sql, [
{ val: "三国演义" },
{ val: "罗贯中" },
{ val: "中华书局" },
{ val: new Date("2005-04-01") },
{ val: 4 },
{ val: "9787101046121" },
{ val: 10 },
{ val: 19.0 },
{ val: 15.2 },
{ val: 8.0 },
{
val: "《三国演义》是中国第一部长篇章回体小说,中国小说由短篇发展至长篇的原因与说书有关。",
},
{ val: blob },
{ val: "25" },
{ val: 943 },
{ val: 93000 },
{ val: new Date("2006-03-20") },
{ val: new Date("1900-01-01") },
]);
} catch (err) {
throw new Error("insertTable error: " + err.message);
}
}
/* 修改产品信息表数据 */
async function updateTable() {
try {
var sql =
"UPDATE production.product SET name = :name " + "WHERE productid = 11;";
// 按名称绑定变量
return conn.execute(sql, { name: { val: "三国演义(上)" } });
} catch (err) {
throw new Error("updateTable error: " + err.message);
}
}
/* 删除产品信息表数据 */
async function deleteTable() {
try {
var sql = "DELETE FROM production.product WHERE productid = 11;";
return conn.execute(sql);
} catch (err) {
throw new Error("deleteTable error: " + err.message);
}
}
/* 查询产品信息表 */
async function queryTable() {
try {
var sql =
"SELECT productid,name,author,publisher,photo FROM production.product";
var result = await conn.execute(sql);
var lob = result.rows[result.rows.length - 1][4];
var buffer = await readLob(lob);
// Lob 对象使用完需关闭
await lob.close();
console.log(buffer);
return result;
} catch (err) {
throw new Error("queryTable error: " + err.message);
}
}
/* 读取数据库返回的 Lob 对象 */
function readLob(lob) {
return new Promise(function (resolve, reject) {
var blobData = Buffer.alloc(0);
var totalLength = 0;
lob.on("data", function (chunk) {
totalLength += chunk.length;
blobData = Buffer.concat([blobData, chunk], totalLength);
});
lob.on("error", function (err) {
reject(err);
});
lob.on("end", function () {
resolve(blobData);
});
});
}
/* 结果集方式查询产品信息表 */
async function queryWithResultSet() {
try {
var sql = "SELECT productid,name,author,publisher FROM production.product";
var result = await conn.execute(sql, [], { resultSet: true });
var resultSet = result.resultSet;
// 从结果集中获取一行
result = await resultSet.getRow();
while (result) {
console.log(result);
result = await resultSet.getRow();
}
} catch (err) {
throw new Error("queryWithResultSet error: " + err.message);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
其他
> snappy@6.3.5 install /Users/qins/Documents/git/hy-demo/blog/1/node_modules/dmdb/node_modules/snappy
> prebuild-install || node-gyp rebuild
1
2
2