如何基于POST正文创建动态插入语句

时间:2019-07-15 18:12:01

标签: mysql node.js mysqljs

根据值user_type,主体对象中属性的数量不同。

如果user_type job_seeker ,则主体对象具有以下属性->用户名,user_type,名称,电子邮件,密码,简历,resume_date_time,salary_expectation。我已经创建了像这样的硬编码插入语句->

insert into users (username, user_type, name, email, password, resume, resume_date_time, salary_expectation) values (?, ?, ?, ?, ?, ?, ?, ?);

如果user_type雇主,则正文对象具有以下属性->用户名,user_type,名称,电子邮件,密码,company_name,company_profile。这种情况下的插入语句是->

insert into users (username, user_type, name, email, password, company_name, company_profile) values (?, ?, ?, ?, ?, ?, ?);

因此,如何根据变化的编号创建动态插入查询。 POST请求的正文中有哪些属性?

2 个答案:

答案 0 :(得分:1)

此问题由mysqljs模块为您处理,因此您无需考虑过多或过度设计。提供插入有效载荷作为对象,其中键与表字段名称共享相同的命名。您提供的任何内容都将在插入内容中使用。如果您未提供字段,则它将遵循数据库模式中的表默认值(id将自动填充并递增,如果您采用这种方式设置,created_at,{{1 }}或其他类似的日期字段,如果在未提供任何值的情况下将某个字段设置为使用默认值,则将使用该默认值。)

有关更多详细信息,请参见此处的文档:https://github.com/mysqljs/mysql#escaping-query-values

下面是使用您提供的两种方案的示例。

timestamp

如果在将var mysql = require('mysql'); var connection = mysql.createConnection({ host: 'localhost', user: 'me', password: 'secret', database: 'my_db' }); connection.connect(); let job_seeker = { username: 'j.smith', user_type: 'job_seeker', name: 'john smith', email: 'j.smith@example.com', password: 'keyboard_cat', resume: true, resume_date_time: '2109-01-01', salary_expectation: 100000 }; let employer = { username: 'b.burke', user_type: 'employer', name: 'betty burke', email: 'b.burke@example.com', password: 'admin_cat', company_name: 'Acme Inc.', company_profile: 'http://acme.example.com/about_us/' }; connection.query('INSERT INTO users SET ?', job_seeker, function(error, results, fields) { if (error) throw error; console.log(results.insertId); }); connection.query('INSERT INTO users SET ?', employer, function(error, results, fields) { if (error) throw error; console.log(results.insertId); }); // if a scenario exists where you might encounter unique key conflicts, consider using a query model that will update on duplicates: connection.query('INSERT INTO users SET ? ON DUPLICATE KEY UPDATE', employer, function(error, results, fields) { if (error) throw error; console.log(results.insertId); }); // this would update every field provided in the employer object. If you didn't want to update every fields, you'd have to list out only the fields you'd like to update: connection.query('INSERT INTO users SET ? ON DUPLICATE KEY UPDATE name = VALUES(name)', employer, function(error, results, fields) { if (error) throw error; console.log(results.insertId); }); // in the above example, only the name field will be updated if a duplicate is found, even though the full employer object is provided. 主体传递到代码中的这一步之前对其进行适当的构造,则可以节省一些时间,而无需进行任何额外的工作或对象构造或操作,就可以使它流经查询功能。

基于评论进行编辑

如果您的计划是要包含一些查询参数,则可能要使用和更新而不是INSERT。无论哪种方式,我们都可以以此为例来说明POST模块提供的动态功能。

每次使用mysqljs时,它都是一个占位符,它映射到该函数后面的数组索引。

在我链接的文档部分中,您可以看到一个示例,其中4 ?映射到后面的数组中提供的4个值。您只需要确保数组中值的顺序与对应于其问号的正确顺序对齐即可。

如果我们想用一个对象在一个查询中解决所有问题,我们可以给?对象增加一些复杂性,使其包含我们查询所需的所有信息。使用您的示例,请考虑以下几点:

POST

注意::您有时会看到我使用// you could define the following object as we have for this example, or it could be coming right from req.body let update_payload = { table_name = 'users', query_field = 'email', query_value = 'j.smith.old@example.com', job_seeker = { username: 'j.smith', user_type: 'job_seeker', name: 'john smith', email: 'j.smith.new@example.com', password: 'keyboard_cat_new', resume: true, resume_date_time: '2109-01-01', salary_expectation: 100000 } }; connection.query('UPDATE ?? SET ? WHERE ?? = ? ', [update_payload.table_name, update_payload.job_seeker, update_payload.query_field, update_payload.query_value], function(error, results, fields) { if (error) throw error; console.log(results); }); // expected console output… OkPacket { fieldCount: 0, affectedRows: 1, insertId: 0, serverStatus: 2, warningCount: 0, message: '(Rows matched: 1 Changed: 1 Warnings: 0', protocol41: true, changedRows: 1 } ,而其他时候我使用??。这是模块的功能,提供转义以防止SQL注入。根据数据库配置,体系结构,字段类型和个人安全策略的具体情况,在何时何地使用单一与双重使用的必要性会有所不同,并且需要使用自己的代码库进行测试。

答案 1 :(得分:0)

这不是一个好答案,但是它可以正常工作,因此可以解决这个小小的问题,但是如果有人知道,请发布答案。

let keys = [];
let values = [];
let escapedsql = [];
Object.keys(req.body).forEach(key => {
    keys.push(key);
    values.push(req.body[key]);
    escapedsql.push('?')
})
let postBody = 'insert into users (' + keys.join() + ') values (' + escapedsql.join() + ')';
let sql = connection.format(postBody, values);