美文网首页NodejsSequelize
node里MySQL使用Sequelize

node里MySQL使用Sequelize

作者: 浮若年华_7a56 | 来源:发表于2022-07-09 16:22 被阅读0次

    node如何访问MySQL?
    通过网络发送SQL,然后MySQL执行后返回结果
    我们可以在命令行窗口输入mysql -u root -p,然后输入root口令后,就连接到了MySQL服务器。因为没有指定--host参数,所以我们连接到的是localhost,也就是本机的MySQL服务器。
    输入exit退出MySQL命令行模式。

    对于Node.js程序,访问MySQL也是通过网络发送SQL命令给MySQL服务器。这个访问MySQL服务器的软件包通常称为MySQL驱动程序。不同的编程语言需要实现自己的驱动,MySQL官方提供了Java、.Net、Python、Node.js、C++和C的驱动程序,官方的Node.js驱动目前仅支持5.7以上版本,而我们上面使用的命令行程序实际上用的就是C驱动。

    目前使用最广泛的MySQL Node.js驱动程序是开源的mysql,可以直接使用npm安装。
    如果直接使用mysql包提供的接口,我们编写的代码就比较底层,例如,查询代码:

    connection.query('SELECT * FROM users WHERE id = ?', ['123'], function(err, rows) {
      if (err) {
          // error
      } else {
          for (let row in rows) {
              processRow(row);
          }
      }
    });
    

    考虑到数据库表是一个二维表,包含多行多列,例如一个pets的表:

    mysql> select * from pets;
    +----+--------+------------+
    | id | name | birth |
    +----+--------+------------+
    | 1 | Gaffey | 2007-07-07 |
    | 2 | Odie | 2008-08-08 |
    +----+--------+------------+
    2 rows in set (0.00 sec)
    每一行可以用一个JavaScript对象表示,例如第一行:

    {
      "id": 1,
      "name": "Gaffey",
      "birth": "2007-07-07"
    

    }
    这就是传说中的ORM技术:Object-Relational Mapping,把关系数据库的表结构映射到对象上。是不是很简单?

    但是由谁来做这个转换呢?所以ORM框架应运而生。

    我们选择Node的ORM框架Sequelize来操作数据库。这样,我们读写的都是JavaScript对象,Sequelize帮我们把对象变成数据库中的行。

    用Sequelize查询pets表,代码像这样:

    Pet.findAll()
     .then(function (pets) {
         for (let pet in pets) {
           console.log(`${pet.id}: ${pet.name}`);
       }
     }).catch(function (err) {
       // error
     });
    

    在使用Sequlize操作数据库之前,我们先在MySQL中创建一个表来测试。我们可以在test数据库中创建一个pets表。test数据库是MySQL安装后自动创建的用于测试的数据库。在MySQL命令行执行下列命令:

    grant all privileges on test.* to 'www'@'%' identified by 'www';
    
    use test;
    
    create table pets (
      id varchar(50) not null,
      name varchar(100) not null,
      gender bool not null,
      birth varchar(10) not null,
      createdAt bigint not null,
      updatedAt bigint not null,
      version bigint not null,
      primary key (id)
    ) engine=innodb;
    

    第一条grant命令是创建MySQL的用户名和口令,均为www,并赋予操作test数据库的所有权限。

    第二条use命令把当前数据库切换为test。

    第三条命令创建了pets表。

    使用Sequelize操作MySQL需要先做两件准备工作:

    第一步,创建一个sequelize对象实例:

    const Sequelize = require('sequelize');
    const config = require('./config');
    
    var sequelize = new Sequelize(config.database, config.username, config.password, {
      host: config.host,
      dialect: 'mysql',
      pool: {
        max: 5,
        min: 0,
        idle: 30000
      }
    });
    

    第二步,定义模型Pet,告诉Sequelize如何映射数据库表:

    var Pet = sequelize.define('pet', {
      id: {
        type: Sequelize.STRING(50),
        primaryKey: true
      },
      name: Sequelize.STRING(100),
      gender: Sequelize.BOOLEAN,
      birth: Sequelize.STRING(10),
      createdAt: Sequelize.BIGINT,
      updatedAt: Sequelize.BIGINT,
      version: Sequelize.BIGINT
    }, {
        timestamps: false
    });
    

    用sequelize.define()定义Model时,传入名称pet,默认的表名就是pets。第二个参数指定列名和数据类型,如果是主键,需要更详细地指定。第三个参数是额外的配置,我们传入{ timestamps: false }是为了关闭Sequelize的自动添加timestamp的功能。所有的ORM框架都有一种很不好的风气,总是自作聪明地加上所谓“自动化”的功能,但是会让人感到完全摸不着头脑。

    接下来,我们就可以往数据库中塞一些数据了。我们可以用Promise的方式写:

    var now = Date.now();
    
    Pet.create({
      id: 'g-' + now,
      name: 'Gaffey',
      gender: false,
      birth: '2007-07-07',
      createdAt: now,
      updatedAt: now,
      version: 0
    }).then(function (p) {
      console.log('created.' + JSON.stringify(p));
    }).catch(function (err) {
      console.log('failed: ' + err);
    });
    

    也可以用await写:

    (async () => {
      var dog = await Pet.create({
        id: 'd-' + now,
        name: 'Odie',
        gender: false,
        birth: '2008-08-08',
        createdAt: now,
        updatedAt: now,
        version: 0
      });
        console.log('created: ' + JSON.stringify(dog));
    })();
    

    查询数据时,用await写法如下:

    (async () => {
      var pets = await Pet.findAll({
          where: {
              name: 'Gaffey'
          }
      });
      console.log(`find ${pets.length} pets:`);
      for (let p of pets) {
        console.log(JSON.stringify(p));
      }
    })();
    

    如果要更新数据,可以对查询到的实例调用save()方法:

    (async () => {
      var p = await queryFromSomewhere();
      p.gender = true;
      p.updatedAt = Date.now();
      p.version ++;
      await p.save();
    })();
    

    如果要删除数据,可以对查询到的实例调用destroy()方法:

    (async () => {
      var p = await queryFromSomewhere();
      await p.destroy();
    })();
    

    运行代码,可以看到Sequelize打印出的每一个SQL语句,便于我们查看:

    Executing (default): INSERT INTO `pets` (`id`,`name`,`gender`,`birth`,`createdAt`,`updatedAt`,`version`) VALUES ('g-1471961204219','Gaffey',false,'2007-07-07',1471961204219,1471961204219,0);
    

    Model
    我们把通过sequelize.define()返回的Pet称为Model,它表示一个数据模型。

    我们把通过Pet.findAll()返回的一个或一组对象称为Model实例,每个实例都可以直接通过JSON.stringify序列化为JSON字符串。但是它们和普通JSON对象相比,多了一些由Sequelize添加的方法,比如save()和destroy()。调用这些方法我们可以执行更新或者删除操作。

    所以,使用Sequelize操作数据库的一般步骤就是:

    首先,通过某个Model对象的findAll()方法获取实例;

    如果要更新实例,先对实例属性赋新值,再调用save()方法;

    如果要删除实例,直接调用destroy()方法。

    注意findAll()方法可以接收where、order这些参数,这和将要生成的SQL语句是对应的。

    相关文章

      网友评论

        本文标题:node里MySQL使用Sequelize

        本文链接:https://www.haomeiwen.com/subject/kygbbrtx.html