04 NodeJs访问MySql 数据库

本文详细介绍了在Node.js中使用原生MySQL驱动、ORM库(如Sequelize和TypeORM)、QueryBuilder、适配器以及GraphQL等技术访问MySQL数据库的方法,包括操作流程和示例代码,重点强调了直接连接与连接池的区别和各自的优缺点。
摘要由CSDN通过智能技术生成

在NodeJs中访问Mysql数据库

一、MySql数据库中访问数据库形式:

在Node.js中访问MySQL数据库有多种形式,以下是其中的一些常见方式:

  1. 原生MySQL驱动:使用Node.js的原生MySQL驱动来连接和操作数据库。这是最早的方式,但在许多现代应用中,由于其复杂性,它可能不是首选。
  2. Sequelize ORM:Sequelize是一个流行的Node.js ORM(对象关系映射)库,它允许你使用JavaScript对象来操作数据库。通过定义模型和它们之间的关系,你可以方便地进行CRUD操作。
  3. TypeORM:这是另一个流行的Node.js ORM,与Sequelize类似,但有一些不同的特性和用法。
  4. Query Builder:一些库如knex提供了一个查询构建器,允许你以链式方式构建复杂的数据库查询。
  5. Adapters:对于一些框架(如Express),有专门的数据库适配器,如express-mysql-session,它为Express应用提供了MySQL会话存储。
  6. ORM-Drivers:一些ORM(如TypeORM)有自己的数据库驱动,这些驱动通常提供与特定数据库的连接和操作功能。
  7. GraphQL:GraphQL与MySQL结合使用时,你可以定义数据模型和查询,然后使用GraphQL服务器从MySQL数据库检索数据。
  8. ORM-Generators:有些工具可以自动生成基于数据库结构的Node.js代码,例如TypeScript类和模型。
  9. Native Bindings:对于某些数据库,可能有Node.js的native bindings可用,这些bindings直接与数据库的API交互,可能比纯JavaScript实现更快。

二、原生MySQL驱动访问方法

原生MySQL驱动通过执行SQL语句对数据库进行查询、修改等操作,其需要熟悉SQL语法,复杂度随SQL语句的复杂度而变化;然而原生MySQL驱动访问方法的好处有以下几点:
a. 灵活性和控制力:原生MySQL驱动允许开发者直接与MySQL数据库交互,可以执行任何有效的SQL查询,提供了最大程度的灵活性和控制力。
b. 性能:由于它直接与MySQL数据库交互,因此在某些情况下,原生驱动可能会比其他封装层提供更好的性能。
c. 简单易用:对于简单的查询和操作,原生驱动提供了简洁的API,使得读写数据变得相对容易。
d. 社区支持:由于原生MySQL驱动是Node.js官方支持的数据库驱动之一,它拥有庞大的社区和丰富的资源,遇到问题时可以获得大量的帮助和解决方案。
e. 跨平台性:原生MySQL驱动可以在任何支持Node.js的平台上运行,具有很好的跨平台性。

1. 操作流程
创建数据库连接
访问数据库
执行查询语句
解析查询结果
关闭数据库连接
执行修改语句
解析执行结果

在访问数据库前首先需要创建NodeJs与Mysql数据库的连接,之后再通过该连接来访问数据库;在创建数据库连接时有两种形式:
直接创建数据库连接,通过指定数据信息,直接创建一个连接,用完后关闭连接;
数据库连接池的形式,在程序开始前创建数据库连接池,当需要访问数据库时从连接池中获取一个连接,用完返还给连接池;通过连接池规避了每次创建数据库连接的时间开支,同时也避免了程序因创建大量数据库链接造成的资源消耗。

2.代码实现

首先安装NodeJs访问Mysql数据库的组件:mysql

npm install mysql  

2.1 以连接的形式访问数据库

//通过回调模拟同步执行
const mysql = require('mysql');    
// 创建连接配置  
const connectionConfig = {  
  host: 'localhost',  
  user: 'root',  
  password: '123456',  
  database: 'video_site',
  debug: false // 开启调试模式,会输出详细的SQL执行日志   
};  
  
// 获取用户信息的同步函数(实际上内部仍然是异步的)  
function getUserInfoSync(callback) {  
  // 创建新的连接  
  const connection = mysql.createConnection(connectionConfig);  
    
  // 连接到数据库  
  connection.connect((error) => {  
    if (error) {  
      callback(error, null);  
      return;  
    }  
  
    // 执行查询  
    connection.query('SELECT * FROM users', (error, results) => {  
      // 关闭连接  
      connection.end();  
  
      if (error) {  
        callback(error, null);  
      } else {  
        callback(null, results);  
      }  
    });  
  });  
}  
  
// 主函数  
function main() {    
  getUserInfoSync((error, userInfo) => {  
    if (error) {  
      console.error('Error retrieving user:', error);  
    } else {  
      console.log('User Info:', userInfo);
      for( i = 0; i < userInfo.length; ++i)  
      {
        console.log('User Info:', userInfo[i]);
      }
    }  
  });  
}  
  
// 调用主函数  
main();

//输出
User Info: (3) [RowDataPacket, RowDataPacket, RowDataPacket]
DBTest.js:90
User Info: RowDataPacket {ID: 1, UserName: 'u1', Email: 'e1', Pwd: '123', Tel: '12345678901',}
DBTest.js:93
User Info: RowDataPacket {ID: 2, UserName: 'u2', Email: 'e2', Pwd: '12345', Tel: '12345678',}
DBTest.js:93
User Info: RowDataPacket {ID: 3, UserName: 'u3', Email: 'e3', Pwd: '123456', Tel: '1234567',}

2.2 以连接池的形式访问数据库

下面示例中所有函数均为异步函数

const mysql = require('mysql');
const connectionConfig = {  
  connectionLimit: 10, // 连接池最大连接数  
  host: 'localhost',  
  user: 'root',  
  password: '123456',  
  database: 'video_site',
  debug: false // 开启调试模式,会输出详细的SQL执行日志   
};  

  
// 查询数据库的示例函数  
function getUserInfo(id) {  
  // 创建一个连接池  
  const pool = mysql.createPool(connectionConfig);  
  // 从连接池中获取连接  
  pool.getConnection((err, connection) => {  
    if (err) {  
      if (err.code === 'PROTOCOL_CONNECTION_LOST') {  
        console.error('Database connection was closed.')  
      }  
      if (err.code === 'ER_CON_COUNT_ERROR') {  
        console.error('Database has too many connections.')  
      }  
      if (err.code === 'ECONNREFUSED') {  
        console.error('Database connection was refused.')  
      }  
    }  
  
    if (connection) {  
      // 执行查询  
      connection.query('SELECT * FROM users where id = ?', [id],(error, results, fields) => {  
        // 查询完成后,释放连接  
        connection.release();
        if (error) {  
          console.error('Query error:', error);  
          return;  
        }  
  
        // 输出查询结果  
        console.log('Query results:', results);  
      });
         
    }  
  });  
}  
  
id = 1;
// 调用示例函数  
getUserInfo(id);

//输出结果
User Info: (1) [RowDataPacket]
DBTest2.js:43
arg1:
(1) [RowDataPacket]
0:
RowDataPacket {ID: 1, UserName: 'u1', Email: 'e1', Pwd: '123', Tel: '12345678901',}
length:
1
[[Prototype]]:
Array(0)
[[Prototype]]:
Object

2.3 小结

  1. 无论使用数据库连接池还是直接使用数据库连接其数据库操作代码只有取得连接时有差异,其它部分均相同;
  2. 当执行的SQL语句中需参数时,在SQL语句需要参数位置以?(问题)进行占位,然后再将参数按顺序添加到后面。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依旧阳光的老码农

一毛一次,一次一毛

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值