使用Sequelize(orm)操作 MySQL (1)

由于MongoDB无法支持事务性, 最近公司决定将数据库从MongoDB转移到MySQL. 同时为了方便操作MySQL, 我需要选择一个orm(Object Relationship Model) 框架来开发,在 orm2sequelize 这两个github上star数最高的两个框架中我选择了后者. 因为 sequelize 所有的api返回的都是promise, 可以用 co 很方便的操作.
接着通过 sequelize 官方文档学习它的运用,由于sequelize官方文档内容太多太杂, 并且是英文文档, 在这里我整理一下常用的知识点和api, 方便公司同事查看, 也方便日后查询.

安装

node安装模块就简单了,不多说:

$ npm install sequelize --save
$ npm install co --save
$ npm install mysql --save

测试模板

'use strict';
let co = require('co');
let _ = require('underscore');

/*数据库连接及表定义部分代码放此处*/

co(function*() {
  /*增删改查操作放此处*/
}).catch(function (error) {
  console.log(error);
});

连接数据库

安装和启动 MySQL 我就不讲了, 不是本文范围, 直接贴连接 MySQL 的代码:

let Sequelize = require('sequelize');

let Database = new Sequelize(
  'test',                  // 要连接的数据库
  'username',              // 数据库用户名
  'password',              // 密码
  {
    'dialect': 'mysql',  // 数据库使用mysql
    'host': 'localhost', // 数据库服务器ip
    'port': 3306,        // 数据库运行端口
    'timestamp': true    // 这个参数为true是MySQL会自动给每条数据添加createdAt和updateAt字段
  }
);

表的定义

注意sequelize提供的常用数据类型有STRING, BOOLEAN, INTEGER, TEXT, FLOAT, DATE, UUID

let User = Database.define('User', {
  phone: {
    type: Sequelize.STRING,      //字段类型string
    allowNull: false,            //是否允许为空
    unique: true                 //是否唯一
  },
  avatar: {
    type: Sequelize.STRING,
    defaultValue: 'http://xxxx.com/default_avatar.png' //设置默认值
  },
  gender: {
    type: Sequelize.INTEGER,
    defaultValue: 0
  },
  name: {
    type: Sequelize.STRING,
    defaultValue: function () {
      return '用户' + parseInt(Math.random() * 1000);
    } //默认值可以通过函数返回
  }
});

没有数据关联时的增删改查

// 方法1:build后对象只存在于内存中,调用save后才操作database
let user = User.build({
  phone: '12345678912'     //其他三个字段会自动设置为默认值
});
user = yield user.save();
console.log(user.dataVaules);        //sequelize返回的文档数据在dataVaules字段中
//console.log(user.get({plain: true})); 也可以通过设置plain:true来直接获取文档数据

// 方法2:直接操作database
let user = yield User.create({
  phone: '12345678912'
});
console.log(user.dataValues);

// 批量增加数据
yield User.bulkCreate([
  {phone: '12345678912'},
  {phone: '12345678913'},
  {phone: '12345678914'}
]);
yield user.destroy();

//按条件删除多条
yield user.destroy({
  where: {id: [1,2,3]}
});
//直接修改
yield user.update({name: 'qqstar'});

//调用save修改
user.name = 'qqstar';
yield user.save();

//只应用传入数据的部分字段
yield user.update({
  {name: 'qqstar', gender: 2},
  {'fields': ['name']}
});        //只修改name字段, gender字段不修改, 客户端传过来的数据多余时很有用
查找全部
let users = yield User.findAll();
查找并计数
let userCount = yield User.findAndCountAll();
查找并排序
let users = yield User.findAll({
  order: [
    ['name', 'DESC']   //按名字降序排列
    // ['name', 'ASC']  按名字升序排列
    // [['count', 'DESC'], ['name', 'ASC']]  按数量倒序排列,数量相同的按照名字排序
  ]
});
查找一条
let user = yield User.findOne({name: 'qqstar'});
let user = yield User.findById(1);
只返回特定字段
let users = yield User.findAll({
  attributes: ['name', 'gender']
});
字段重命名
let users = yield User.findAll({
  attributes: [
    id, ['name', 'nickName']
  ]
});            //返回数据中name会变成nickName
比较操作符
let users = yield User.findAll({
  where: {
    id: {
      $eq: 1,                // id = 1
      $ne: 2,                // id != 2
      $gt: 6,                // id > 6
      $gte: 6,               // id >= 6
      $lt: 10,               // id < 10
      $lte: 10,              // id <= 10
      $between: [6, 10],     // 6 <= id <= 10
      $notBetween: [11, 15], // id < 11 或 id > 15
      $in: [1, 2],           // id == 1 || id == 2
      $notIn: [3, 4]         // id != 3 && id != 4
    },
    name: {
      $like: '%a%',          // name 匹配 '%a%'
      $notLike: '%a'         // name 不匹配 '%a'
    }
  }
});
条件操作符
//$AND
let users = yield User.findAll({
  where: {
    $and: [
      {id: [1, 2], name: 'qqstar'},
      {gender: 0}
    ]
  }
});
//$OR
let users = yield User.findAll({
    where: {
        $or: [
            {id: [1, 2], name: 'qqstar'},
            {id: [1, 2], name: 'test'}
        ]
    }
});
0%