《使用nodejs连接mysql数据库》

7,006 阅读6分钟

上边我们熟悉了如何用docker拉取远程的mysql,以及进入这个数据库然后连接。并且在命令行操作数据库,比如查看,或者操作数据库中的表。

也可以用node js操作数据库。只不过node的原生模块里并没有集成mysql,需要额外安装一个mysql模块: 搜索nodejs mysql,就是这个库的github官网

当我们用docker安装好MYSQL数据库后,该怎么访问呢?访问到数据库只有一种方法,就是通过网络发送SQL命令,由MYSQL服务器执行后再返回结果。

我们可以在命令行窗口直接输入命令操作MYSQL服务器。对于node js程序,要想访问MYSQL也是通过网络发送SQL命令给MYSQL服务器。那么这个可以访问到MYSQL服务器的软件包通常称为MYSQL驱动程序。 不同的编程语言也需要实现各自的驱动程序的,所以本次我们用的就是node js实现的mysql软件包。这是目前使用最广泛的开源驱动程序。

1. 安装

yarn add mysql

2. 连接数据库

按照官网的例子,创建一个test.js,

const mysql      = require('mysql');
const connection = mysql.createConnection({
  host     : 'localhost',	//连接的数据库地址。(默认:localhost)
  user     : 'me',		//mysql的连接用户名
  password : 'secret',		// 对应用户的密码
  database : 'my_db'  		//所需要连接的数据库的名称(可选)
});

connection.connect();

connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
});

connection.end();

首先引入mysql模块。使用mysql.createConnection创建一个连接对象。提供要连接的MySQL服务器上的详细信息。接受一个对象作为参数,需要传host,user等参数。

这里要想连接成功,就要先在本地用docker拉取一个mysql。因为我下载的是旧版的docker,也就是docker toolbox,所以要把host对应的'localhost'替换成我启动docker quickstart后得到的那个IP。也可以在命令行用docker-machine ip得到。如果是新版docker或者max linux系统,就不用替换。

接下来在连接对象上调用connect方法连接到MYSQL数据库服务器。

connection.query方法可以用来查询,并且执行任意正确的sql语句。接受第一个参数就是一个sql语句字符串,第二个参数是执行sql语句后的回调函数。

最后用connection.end()关闭连接。

这个mysql库就相当于一个mysql客户端,通过发送一些sql命令到服务器,由服务器从数据库里读/写数据,然后把读到的数据再发回来。

3. 创建数据库,表

//test.js
const mysql= require('mysql');
const connection = mysql.createConnection({
    host: '192.168.99.100',
    port:3306,
    user: 'root',
    password: '123456',
});

connection.connect();

connection.query('CREATE DATABASE IF NOT EXISTS mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;', function (error, results, fields) {
    if (error) throw error;
    console.log('创建数据库')
    console.log(results)
});

connection.query('use mydb;')

connection.query(`CREATE TABLE IF NOT EXISTS myuser(
        name text,
        age int
    )`, function (error, results, fields) {
    if (error) throw error;
    console.log('创建表')
    console.log(results)
});

connection.end();

1. 创建数据库的sql语句

还是用connection.query执行创建数据库的sql语句。这个sql语句完整的写法:'CREATE DATABASE IF NOT EXISTS mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;'

创建数据库,然后要写IF NOT EXISTS 如果不存在就创建,存在自然就不需创建了。后边跟着要创建的数据库的名字。

永远不要使用mysql的utf-8,因为这个bug还没有修复,要用utf8mb4这种编码。

2. 创建表

要想创建一个表,就要先进入某个数据库,在这个数据库里创建表。否则就会报错。

connection.query('use mydb;')

这个sql语句可以看到和命令行里的一样,use 某个数据库。

如果直接创建表:CREATE TABLE IF NOT EXISTS myuser 会报错,说表里至少要有一列数据;所以创建表的同时要往里写入一些数据,语法就是用()包起,直接写在表名后。外边的包字符串的''也要改成一对反引号。

3. 运行

然后运行node test.js 这样就是成功了:

4. 命令行验证

在命令行里依次连接,进入mysql,用show databases;命令查看现有数据库,可以看到 mydb数据库被创建了。

然后使用这个数据库use mydb; 查看这个数据库里的表 show tables; 查看某个表的具体内容,会展示表中的列及其所有属性 describe myuser; 可以看到我们创建了myuser这个表,和写入表内的数据

4. ORM 和Sequelize

如果直接使用这个mysql包提供的接口访问数据库,我们编写的代码就比较底层,因为是直接写SQL命令来访问的。

其实数据库的表是一个二维表,可以有多行多列。这个表的结构可以映射成一个JS对象,每一行都可以用一个对象来表示。每个列的字段就是对象里的每个属性。这个就是ORM技术:Object-Relational Mapping 就是把关系数据库的表结构映射到对象上

那由谁来做这个转换呢?就是ORM框架,Sequelize就是这种ORM框架,可以让我们读写JS对象,它帮我们把对象变成表中的每行。

Sequelize官方文档

按照文档来做,实现的都比较简单。

const { Sequelize,Model, DataTypes} = require('sequelize');

const sequelize = new Sequelize('HU', 'root', '123456', {
    host: '192.168.99.100',
    dialect: 'mysql'
});

class User extends Model {}
User.init({
    username: DataTypes.STRING,
    age:DataTypes.INTEGER
}, { sequelize, modelName: 'user' });

(async () => {
    await sequelize.sync();
    const jane = await User.create({
    username: 'janedoe',
    birthday: new Date(1980, 6, 20)
    });
  
    const users_name = await User.findAll({
        where: {
            username:'huanqi'
        }
    });
    console.log("All users:", JSON.stringify(users_name, null, 2));
})();

Sequelize的核心概念就是模型。在Sequelize里,模型就是一个继承了Model的类,它相当于数据库里的一张表的结构。由这个类创建出来的一个实例对象,相当于表里的一行。

首先new Sequelize创建一个sequelize连接对象,包含了连接到的mysql数据库的信息。然后声明一个模型叫User。用User.init对这个模型初始化,就是对表初始化,有哪些属性(列)及其数据类型。第二个参数就是要连接的对象。

sequelize.sync()用来同步我们这个模型和表,因为可能表已经存在,或者有不同的列,所以要先同步一下。

User.create 用模型创建一个实例对象,就是在表中添加一行数据。这个都是异步的,相当于一个promise,所以用await非常简洁。

User.findAll 用于查询