sequelize结合sequelize-cli使用

sequelize结合sequelize-cli使用

文章目录

  • sequelize结合sequelize-cli使用
      • 基本配置
          • sequelize安装
          • 查看有哪些命令
          • 初始化
          • 配置数据库
      • 基本使用
          • 创建和删除数据库
          • 创建模型和迁移文件
          • 运行迁移文件生成数据表
          • 撤销迁移
          • 创建种子文件
          • 修改种子文件内容
          • 运行种子文件
          • 数据类型
          • 字段属性
          • 添加索引
          • 迁移文件添加外键约束
          • 模型内容
          • 模型get和set
          • 数据的增删改查
            • 查询数据
            • 创建数据
            • 更新数据
            • 字段自增和自减
            • 删除数据
          • 限制条件获取数据(Op)
          • limit, offset, order and group
          • 读取指定字段(attribute)
          • 排除一些字段(attribute)
          • hasMany一对多
          • belongsTo 多对一
          • belongsToMany 多对多
          • 分页

基本配置

sequelize安装
yarn add sequelize
yarn add sequelize-cli
yarn add mysql2
查看有哪些命令
.\node_modules\.bin\sequelize
初始化
.\node_modules\.bin\sequelize init
# 生成对应的文件夹
# config 配置文件夹
# migrations 迁移文件夹
# models 模型文件夹
# seeders 种子文件夹
配置数据库
// config -> config.json
// 三种开发环境的, 只是取一种, 开发环境
"development": {
    "username": "root",
    "password": "root",
    "database": "sequelize_db",
    "host": "127.0.0.1",
    "dialect": "mysql",
    "operatorsAliases": false // 删除这一行, 上一行的逗号也去掉
},

基本使用


创建和删除数据库
 # 设置数据库默认编码为utf8
.\node_modules\.bin\sequelize db:create --charset 'utf8'
.\node_modules\.bin\sequelize db:drop
创建模型和迁移文件
# create 和 generate 都可以
# 如果表的字段很多的话, 那么命令行就写一两个, 后面可以在文件里面更改
.\node_modules\.bin\sequelize model:create --name User --attributes username:string,password:string
运行迁移文件生成数据表
.\node_modules\.bin\sequelize db:migrate
撤销迁移
# 撤销上一次迁移
.\node_modules\.bin\sequelize db:migrate:undo

# 撤销指定迁移
.\node_modules\.bin\sequelize db:migrate:undo --name xxx

# 撤销所有迁移 
.\node_modules\.bin\sequelize db:migrate:undo:all
创建种子文件
.\node_modules\.bin\sequelize seed:create --name users-seed
修改种子文件内容
// down 也要有
'use strict';
module.exports = {
    up: (queryInterface, Sequelize) => {
        const usersArr = [];
        for (let i = 2; i <= 10; i++) {
            usersArr.push({
                username: `user${i}`,
                password: `user${i}`,
                email: `user${i}@qq.com`
            })
        }
        // users => 表名
        return queryInterface.bulkInsert('users', usersArr, {});
    },
    down: (queryInterface, Sequelize) => {
        return queryInterface.bulkDelete('users', null, {});
    }
};
运行种子文件
# 如果运行过一次, 再次运行就会报错, 除非删除上一次填充的种子文件
.\node_modules\.bin\sequelize db:seed:all # 也可以指定文件命令和迁移命令类似
数据类型

参考网站

// 迁移文件
Sequelize.STRING // varchar(255)
Sequelize.STRING(50)

Sequelize.INTEGER

Sequelize.TEXT  

Sequelize.BIGINT              
Sequelize.BIGINT(11) 

Sequelize.FLOAT                       // FLOAT
Sequelize.FLOAT(11)                   // FLOAT(11)
Sequelize.FLOAT(11, 10)               // FLOAT(11,10)

Sequelize.DOUBLE                      // DOUBLE
Sequelize.DOUBLE(11)                  // DOUBLE(11)
Sequelize.DOUBLE(11, 10)              // DOUBLE(11,10)

Sequelize.DECIMAL                     // DECIMAL
Sequelize.DECIMAL(10, 2)              // DECIMAL(10,2)

Sequelize.DATE                        // DATETIME for mysql / sqlite, TIMESTAMP WITH TIME ZONE for postgres
Sequelize.DATE(6)                     // DATETIME(6) for mysql 5.6.4+. Fractional seconds support with up to 6 digits of precision
Sequelize.DATEONLY                    // DATE without time.
Sequelize.BOOLEAN                     // TINYINT(1)

Sequelize.ENUM('value 1', 'value 2')  // An ENUM with allowed values 'value 1' and 'value 2'

Sequelize.JSON                        // JSON column. PostgreSQL, SQLite and MySQL only.
字段属性

官方网站

// 迁移文件 设计数据表的
{
	allowNull: false, // 是否允许为空
	autoIncrement: true, // 字段是否是自增类型
	primaryKey: true, // 字段是否是主键
	type: Sequelize.INTEGER // 字段是整型
    defaultValue: null, // 字段默认值
    unique: true // 唯一索引
}
添加索引
// 迁移文件, 也可以在这里添加唯一索引
up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Users', {
      
    }).then(()=>{
      // ===================普通索引=======================================
       
      return queryInterface.addIndex('users', ['email'])
        
      // ===================普通索引=======================================
        
      /* return queryInterface.addIndex('users', {
        name: 'email-index',
        fields: ['email']
      }) */
        
      // =======================唯一索引====================================
       /* return queryInterface.addIndex('users', ['username'], {
        unique: true
      }) */
        
      // ========================唯一索引====================================
      /* return queryInterface.addIndex('users', {
        name: 'username',
        unique: true,
        fields: ['username']
      }); */
    });
  },
迁移文件添加外键约束

参考网站

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Articles', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      title: {
        type: Sequelize.STRING
      },
      authorid: {
        type: Sequelize.INTEGER,
          // 第一种方法
        /*   references: {
            model: {
              tableName: 'users'
            },
            key: 'id',
          } */
      }
    }).then(() => {
        // 填充测试数据时候, 有外键约束就会报错, 除非把外键字段一起填充
      return queryInterface.addConstraint('articles', ['authorid'], {
        type: 'foreign key',
        name: 'article-constraint',
        references: {
          table: 'users',
          field: 'id'
        },
        // Mysql外键约束之CASCADE、SET NULL、RESTRICT、NO ACTION
        // What should happen when the referenced key is updated. One of CASCADE, RESTRICT, SET DEFAULT, SET NULL or NO ACTION
        onDelete: 'CASCADE',
        onUpdate: 'CASCADE',
      })
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Articles');
  }
};
模型内容
// user模型
'use strict';
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    username: DataTypes.STRING,
    password: DataTypes.STRING,
    email: DataTypes.STRING
  }, {
    timestamps: false
  });
  User.associate = function (models) {
    // associations can be defined here
    models.User.hasMany(models.Article, {
      as: 'articles',
      foreignKey: 'authorid',
      sourceKey: 'id'
    })
  };
  return User;
};

// article模型
'use strict';
module.exports = (sequelize, DataTypes) => {
  const Article = sequelize.define('Article', {
    title: DataTypes.STRING,
    content: DataTypes.TEXT,
    hit: DataTypes.INTEGER,
    authorid: {
      type: DataTypes.INTEGER,
      async get() {
        const aid = this.getDataValue('authorid')
        const user = await sequelize.model('User').findByPk(aid)
        console.log(user.dataValues.username);
      }
    },
    createdAt: DataTypes.DATE,
    updatedAt: DataTypes.DATE
  }, {});
  Article.associate = function (models) {
    // associations can be defined here
    models.Article.belongsTo(models.User, {
      // 主表删除的时候从表记录也跟着删除, 如果是NUll那么就用NULL填充(条件: 这个字段允许为NULL)
      onDelete: 'CASCADE',
      as: 'user',
      foreignKey: 'authorid',
      /*  foreignKey: {
         fieldName: 'userId',
         allowNull: false
       }, */
      targetKey: 'id'
    })
  };
  return Article;
};
模型get和set
// get
publish: {
    /*
    type: DataTypes.ENUM,
    values: ['happy', 'sad', 'neutral']
    */
    type: DataTypes.ENUM('0', '1'),
	get() {
        const p = this.getDataValue('publish')
        return p == 0 ? '未发表' : '发表'
    }
}

// set
token: {
    type: DataTypes.STRING,
    set(val) {
        return this.setDataValue('token', `chenjiang${val}`.toUpperCase())
    }
}

数据的增删改查

参考网站

查询数据
const models = require('../models/index');

// 通过主键获取数据
const user = await models.User.findByPk(1)

// 获取所有数据
const users = await models.User.findAll()

// 获取所有数据并统计条数
const users = await models.User.findAndCountAll()

// 获取模型关联的数据
const users = await models.User.findAll({
    include: [{
        model: models.Article,
        as: 'articles',
        where: {
            hit: {
                [Op.lt]: 10
            }
        }
    }]
})

// 获取一条数据(指定条件)
const user = await models.User.findOne({
    where: {
        'username': 'user4'
    }
})

// 获取数据如果没有就创建
const user = await models.User.findOrCreate({
    where: {
        username: 'user101'
    },
    defaults:{
        username: 'user101',
        password: 'user101',
        email: '[email protected]'
    }
})
创建数据
// 创建数据
const user = await models.User.create({
    username: 'user102',
    password: 'user102',
    email: '[email protected]'
})

// 批量创建数据
const usersArr = []
for (let i = 20; i < 30; i++) {
    usersArr.push({
        username: `user${i}`,
        password: `user${i}`,
        email: `user${i}@qq.com`
    })
}
const users = await models.User.bulkCreate(usersArr)

更新数据
// 更新数据
const user = await models.User.findOne({
    where: {
        username: 'user3'
    }
})
user.update({
    username: 'userupdate'
})

// 更新数据
const user = await models.User.update({
    'username': 'gooduser'
}, {
    where: {
        'username': 'user4'
    }
})
字段自增和自减
const article = await models.Article.findByPk(3)

// 自增
const result = await article.increment('hit')

// 自减
const result = await article.decrement('hit')
删除数据
// 删除数据
const user = await models.User.findByPk(2)
user.destroy()

// 删除数据
const user = await models.User.destroy({
    where: {
        'username': 'user3'
    }
})
限制条件获取数据(Op)
// 引入Op模块
const models = require('../models/index')
const Op = models.Sequelize.Op // 大写Sequelize

Project.findAll({
  where: {
    id: {
      [Op.and]: {a: 5},           // AND (a = 5)
      [Op.or]: [{a: 5}, {a: 6}],  // (a = 5 OR a = 6)
      [Op.gt]: 6,                // id > 6
      [Op.gte]: 6,               // id >= 6
      [Op.lt]: 10,               // id < 10
      [Op.lte]: 10,              // id <= 10
      [Op.ne]: 20,               // id != 20
      [Op.between]: [6, 10],     // BETWEEN 6 AND 10
      [Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15
      [Op.in]: [1, 2],           // IN [1, 2]
      [Op.notIn]: [1, 2],        // NOT IN [1, 2]
      [Op.like]: '%hat',         // LIKE '%hat'
      [Op.notLike]: '%hat',       // NOT LIKE '%hat'
      [Op.iLike]: '%hat',         // ILIKE '%hat' (case insensitive)  (PG only)
      [Op.notILike]: '%hat',      // NOT ILIKE '%hat'  (PG only)
      [Op.overlap]: [1, 2],       // && [1, 2] (PG array overlap operator)
      [Op.contains]: [1, 2],      // @> [1, 2] (PG array contains operator)
      [Op.contained]: [1, 2],     // <@ [1, 2] (PG array contained by operator)
      [Op.any]: [2,3]            // ANY ARRAY[2, 3]::INTEGER (PG only)
    },
    status: {
      [Op.not]: false           // status NOT FALSE
    }
  }
}
                
Project.findOne({
  where: {
    name: 'a project',
    [Op.or]: [
      { id: [1,2,3] },
      { id: { [Op.gt]: 10 } }
    ]
  }
})

Project.findOne({
  where: {
    name: 'a project',
    id: {
      [Op.or]: [
        [1,2,3],
        { [Op.gt]: 10 }
      ]
    }
  }
})
limit, offset, order and group
const user = await models.User.findAll({
    offset: 2, // 跳过两条, 然后再读取
    limit: 2, // 获取数量,
})

const user = await models.User.findAll({
    order: [
        ['id', 'desc'] // 按id, 倒序
    ]
})

const user = await models.Article.findAll({
    group: 'authorid'
})
读取指定字段(attribute)
const users = await models.User.findAll({
    where: {
        'username': 'user2'
    },
    attributes: ['id', 'username', 'email', ['token', 'token别名']] 
    //SELECT token AS token别名
})

排除一些字段(attribute)
// 排除一些字段
const user = await models.User.findAll({
    attributes: {
        exclude: ['password']
    }
})
hasMany一对多
'use strict';
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    username: DataTypes.STRING,
    password: DataTypes.STRING
  }, {});
  User.associate = function (models) {
    // associations can be defined here
    models.User.hasMany(models.Article, {
      as: 'articles', // 在读取数据时候include 里面也要同时指定 as: 'articles'
      foreignKey: 'authorid',
      sourceKey: 'id' // 默认是id可以省略不写
    })
  };
  return User;
};

// 获取数据
const users = await models.User.findAll({
    include: [{
        model: models.Article,
        as: 'articles',
    }],
})

belongsTo 多对一
'use strict';
module.exports = (sequelize, DataTypes) => {
  const Article = sequelize.define('Article', {
    title: DataTypes.STRING
  }, {});
  Article.associate = function (models) {
    // associations can be defined here
    models.Article.belongsTo(models.User, {
      // 主表删除的时候从表记录也跟着删除, 如果是NUll那么就用NULL填充(条件: 这个字段允许为NULL)
      onDelete: 'CASCADE'
      as: 'user', // 在读取数据时候include 里面也要同时指定 as: 'user'
      foreignKey: 'authorid',
      /*  foreignKey: {
         fieldName: 'authorid',
         allowNull: false
       }, */
      targetKey: 'id' // 默认是id可以省略不写
    })
  };
  return Article;
};

// 获取数据
const articles = await models.Article.findAll({
    include: [{
        model: models.User,
        as: 'user',
    }],
})

belongsToMany 多对多
// 学生表
'use strict';
module.exports = (sequelize, DataTypes) => {
  const Student = sequelize.define('Student', {
    study_no: {
      type: DataTypes.STRING,
      primaryKey: true
    },
    name: DataTypes.STRING
  }, {
    timestamps: false
  });
  Student.associate = function (models) {
    // associations can be defined here
    Student.belongsToMany(models.Course, {
      as: 'courses',
      through: models.Student_Course,
      foreignKey: 's_id'
    })
  };
  return Student;
};

// 课程表
'use strict';
module.exports = (sequelize, DataTypes) => {
  const Course = sequelize.define('Course', {
    name: DataTypes.STRING
  }, {
    timestamps: false
  });
  Course.associate = function (models) {
    // associations can be defined here
    Course.belongsToMany(models.Student, {
      through: models.Student_Course,
      foreignKey: 'c_id'
    })
  };
  return Course;
};

// 中间表
'use strict';
module.exports = (sequelize, DataTypes) => {
  const Student_Course = sequelize.define('Student_Course', {
    s_id: DataTypes.STRING,
    c_id: DataTypes.INTEGER
  }, {
    timestamps: false
  });
  Student_Course.associate = function (models) {
    // associations can be defined here
  };
  return Student_Course;
};

// 获取数据
const students = await models.Student.findAll({
    include: [{
        model: models.Course,
        as: 'courses',
        through: { // 除去中间表
            attributes: []
        }
    }],
})
分页
router.get('/posts/:page/:limit', async (req, res) => {
    // let {name = 1} = {name: 'undefined'} //undefined
    let {
        page = 1, limit = 5
    } = req.params

    let offset = (Number(page) - 1) * limit
    const posts = await models.Post.findAndCountAll({
        attributes: {
            exclude: ['updatedAt', 'createdAt']
        },
        offset,
        limit: Number(limit),
        order: [
            ['id', 'desc']
        ]
    })
    return res.status(200).json(posts)
})

// vue element-ui
export default {
    name: "app",
    data() {
        return {
            posts: [],
            page: {
                limit: 5,
                page: 1,
                total: 0,
                size: 5
            }
        };
    },
    methods: {
        fetch() {
            this.$http
                .get(`posts/${this.page.page}/${this.page.limit}`)
                .then(res => {
                    this.posts = res.data.rows;
                    this.page.total = res.data.count;
                });
        },
        handleSizeChange(val) {
            this.page.limit = val;
            this.fetch();
        },
        handleCurrentChange(val) {
            this.page.page = val;
            this.fetch();
        }
    },
    created() {
        this.fetch();
    }
};

你可能感兴趣的:(#,NodeJs学习)