Nodejs 若不存在则插入,存在则更新,如何实现?
Nodejs 若不存在则插入,存在则更新,如何实现?
需要更新的列表长度未知。 其他语言的话一个循环同步的写下来,非常容易。
用node写异步的就觉得比较忧伤了,我给出自己的做法,也看看大家遇到这样的需求是怎么做的。
var list = ["a", "b", "c"];
var tasks = [];
var result;
list.forEach(function(item) {
tasks.push(function() {
var qs = “select * from table where name=”" + item + “”";
db.query(qs, function(err, rows) {
var flag;
if(err) {
throw err;
}
if(rows[0]) {
flag = true;
} else {
flag = false;
};
result = {
name: name,
flag: flag
};
}
done();
})
});
tasks.push(function(done) {
if(result.flag) {
qs = “update table set name=”" + result.name + “” where id=" + result.id;
} else {
db.query(“insert into table set name=”" + result.name “”");
}
db.query(“insert into table set name=”" + result.name “”");
});
});
为了实现Node.js中若记录不存在则插入、存在则更新的需求,我们可以利用Promise或者async/await来简化异步操作。下面是一个使用async/await
结合Promise
的方式,以及一个使用knex
库(一个SQL查询构建器)的示例。
使用原生Promise和async/await
首先,我们定义一个函数用于处理单个项的插入或更新逻辑:
const { promisify } = require('util');
const dbQuery = promisify(db.query).bind(db);
async function upsertItem(name) {
const checkQuery = `SELECT * FROM table WHERE name = ?`;
const [rows] = await dbQuery(checkQuery, [name]);
if (rows.length > 0) {
// 更新
const updateQuery = `UPDATE table SET name = ? WHERE id = ?`;
await dbQuery(updateQuery, [name, rows[0].id]);
} else {
// 插入
const insertQuery = `INSERT INTO table (name) VALUES (?)`;
await dbQuery(insertQuery, [name]);
}
}
// 使用示例
(async () => {
try {
const list = ["a", "b", "c"];
for (const item of list) {
await upsertItem(item);
}
console.log("所有项目已处理完成。");
} catch (error) {
console.error("发生错误:", error);
}
})();
使用Knex库
knex
库提供了一种更简洁的方式来编写数据库查询,并支持事务管理等高级功能。以下是使用knex
的示例:
const knex = require('knex')({
client: 'mysql',
connection: {
host : '127.0.0.1',
user : 'your_database_user',
password : 'your_database_password',
database : 'your_database_name'
}
});
async function upsertItem(name) {
await knex.transaction(async trx => {
const existingRow = await knex('table').where('name', name).first();
if (existingRow) {
await knex('table').where('id', existingRow.id).update({ name });
} else {
await knex('table').insert({ name });
}
});
}
// 使用示例
(async () => {
try {
const list = ["a", "b", "c"];
for (const item of list) {
await upsertItem(item);
}
console.log("所有项目已处理完成。");
} catch (error) {
console.error("发生错误:", error);
}
})();
在这两个示例中,我们都使用了async/await
来简化异步操作的流程。通过这种方式,可以确保每个项目的插入或更新操作都能正确执行,而无需担心回调地狱的问题。
为了实现Node.js中若不存在则插入,存在则更新的需求,我们可以使用async/await
来简化异步逻辑,并结合Promise
来处理数据库查询的结果。以下是一个基于此方法的示例:
const async = require('async');
const db = require('./database'); // 假设这里已经配置好了数据库连接
const list = ["a", "b", "c"];
async function processList(list) {
for (let item of list) {
try {
const row = await new Promise((resolve, reject) => {
db.query(`SELECT * FROM table WHERE name="${item}"`, (err, rows) => {
if (err) return reject(err);
resolve(rows[0]);
});
});
if (row) {
// 存在则更新
await new Promise((resolve, reject) => {
db.query(`UPDATE table SET name="${item}" WHERE id=${row.id}`, (err) => {
if (err) return reject(err);
resolve();
});
});
} else {
// 不存在则插入
await new Promise((resolve, reject) => {
db.query(`INSERT INTO table SET name="${item}"`, (err) => {
if (err) return reject(err);
resolve();
});
});
}
} catch (error) {
console.error(error);
}
}
}
processList(list).catch(console.error);
以上代码中,我们首先通过SELECT
查询判断数据是否存在。如果存在,则执行UPDATE
语句进行更新;如果不存在,则执行INSERT
语句插入新数据。
注意:上述代码未对SQL注入进行防护,实际生产环境中应使用参数化查询或ORM库(如Sequelize、Mongoose)来避免SQL注入攻击。