九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
在Sequelize中使用遷移

http://www.manongjc.com/detail/56-tqgkihqhanllyyo.html

本文章向大家介紹在Sequelize中使用遷移,主要內(nèi)容包括其使用實(shí)例、應(yīng)用技巧、基本知識(shí)點(diǎn)總結(jié)和需要注意事項(xiàng),具有一定的參考價(jià)值,需要的朋友可以參考一下。

Sequelize是Nodejs生態(tài)中一個(gè)比較出名的ORM框架。通過ORM框架,可以使用對(duì)象來操作數(shù)據(jù)庫表數(shù)據(jù),提高了開發(fā)效率和代碼可讀性,也方便后期維護(hù)。

今天主要介紹通過遷移[Migration]來創(chuàng)建數(shù)據(jù)庫,表。

遷移的好處,可以類比git。通過每次創(chuàng)建遷移文件,來支持更新,回滾數(shù)據(jù)庫表結(jié)構(gòu),也方便協(xié)同開發(fā),也避免人工手動(dòng)去直接修改數(shù)據(jù)庫,用代碼自動(dòng)管理。換個(gè)電腦,也不用去拷貝數(shù)據(jù)庫,直接運(yùn)行遷移就可以完全恢復(fù)開發(fā)環(huán)境,極大減輕了心智負(fù)擔(dān)。

1. 創(chuàng)建項(xiàng)目, 安裝node package依賴

mkdir node_work cd node_work mkdir appnpm init -ynpm i sequelize-cli sequelize mysql2 koa

2. 初始化Sequelize

npx sequelize init

運(yùn)行之后,會(huì)產(chǎn)生四個(gè)目錄:

config, migrations, models, seeders

config:

{ 'development': { 'username': 'root', 'password': 'root', 'database': 'app_development', 'host': '127.0.0.1', 'port': 8889, 'dialect': 'mysql', 'timezone': '+08:00' }, 'test': { 'username': 'root', 'password': null, 'database': 'app_test', 'host': '127.0.0.1', 'dialect': 'mysql' }, 'production': { 'username': 'root', 'password': null, 'database': 'app_production', 'host': '127.0.0.1', 'dialect': 'mysql' }}

環(huán)境env => {配置}

不同環(huán)境,對(duì)應(yīng)不同的配置,也可以自定義環(huán)境,比如home

env指的是process.env.NODE_ENV,

可以通過設(shè)置環(huán)境變量來改變,比如export NODE_ENV=production;

遷移時(shí)候,也可以指定環(huán)境:npx sequelize db:migrate --env production,來連接production對(duì)應(yīng)配置的數(shù)據(jù)庫

創(chuàng)建數(shù)據(jù)庫:

npx sequelize db:create

說明npx是npm5.2之后,自帶的一個(gè)命令??梢圆挥萌职惭bsequelize,使用時(shí)候,如果本地沒有,就去npm倉庫下載;下載完后或者本地已經(jīng)下載過,就運(yùn)行腳本命令。這樣可以避免本地全局包過期,環(huán)境問題,每次都使用最新版本

migrations: 遷移文件

npx sequelize model:generate --name User --attributes username:string

執(zhí)行后,會(huì)生成20180918055558-create-user.js遷移文件,和models/user.js模型文件

其他字段可以在遷移文件中補(bǔ)全,最后再運(yùn)行npx sequelize db:migrate,就可以在數(shù)據(jù)庫中看到生成了users表

'use strict';  module.exports = {
    up: (queryInterface, Sequelize) => {      return queryInterface.createTable('Users', {
        id: {
          allowNull: false,
          autoIncrement: true,
          primaryKey: true,
          type: Sequelize.INTEGER
        },
        username: {
          type: Sequelize.STRING(20),
          allowNull: false
        },
        password: {
          type: Sequelize.CHAR(32),
          allowNull: false
        },
        createdAt: {
          allowNull: false,
          type: Sequelize.DATE
        },
        updatedAt: {
          allowNull: false,
          type: Sequelize.DATE
        }
      }, {
        tableName: 'users',
        charset: 'utf8mb4',
        collate: 'utf8mb4_bin',
        define: {
          timestamps: true
        }
      }).then(() => {        // 添加索引
        return queryInterface.addIndex('users', {
          name: 'username',
          unique: true,
          fields: ['username']
        });
      });
    },    
    // 回退時(shí)執(zhí)行,刪除表
    down: (queryInterface, Sequelize) => {      return queryInterface.dropTable('Users');
    }
  };

執(zhí)行遷移:

npx sequelize db:migratenpx sequelize db:migrate:all

撤銷遷移:

npx sequelize db:migrate:undo 最近一次的npx sequelize db:migrate:undo:allnpx sequelize db:migrate:undo:all --to XXXXXXXXXXXXXX-create-posts.js

--from, --to 參數(shù),可以指定遷移文件

models: 模型文件

model:generate生成的model都在這個(gè)目錄中

'use strict';module.exports = { up: (queryInterface, Sequelize) => { return queryInterface.createTable('Users', { id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER }, username: { type: Sequelize.STRING(20), allowNull: false }, password: { type: Sequelize.CHAR(32), allowNull: false }, createdAt: { allowNull: false, type: Sequelize.DATE }, updatedAt: { allowNull: false, type: Sequelize.DATE } }, { tableName: 'users', charset: 'utf8mb4', collate: 'utf8mb4_bin', }).then(() => { return queryInterface.addIndex('users', { name: 'username', unique: true, fields: ['username'] }); }); }, down: (queryInterface, Sequelize) => { return queryInterface.dropTable('Users'); } };

模型對(duì)象創(chuàng)建,默認(rèn)會(huì)自動(dòng)賦值,更新createdAt, updatedAt兩個(gè)timestamps字段。下邊會(huì)給出完整示例。

seeders: 填充數(shù)據(jù)文件

創(chuàng)建seed文件:

npx sequelize seed:generate --name demo-user

執(zhí)行之后,會(huì)得到20180918090545-demo-user.js

'use strict';const md5 = require('md5')module.exports = { up: (queryInterface, Sequelize) => { return queryInterface.bulkInsert('Users', [ { username: 'Kimoo', password: md5('123456'), createdAt: new Date(), updatedAt: new Date(), }, { username: 'Reci', password: md5('123321'), createdAt: new Date(), updatedAt: new Date(), } ], {}); }, down: (queryInterface, Sequelize) => { /* Add reverting commands here. Return a promise to correctly handle asynchronicity. Example: return queryInterface.bulkDelete('Person', null, {}); */ return queryInterface.bulkDelete('Users', null, {}); } };

填充數(shù)據(jù):

npx sequelize db:seed:all

撤銷數(shù)據(jù):

npx sequelize db:seed:undo 最近一次的npx sequelize db:seed:undo --seed name-of-seed-as-in-data 具體某個(gè)npx sequelize db:seed:undo:all

3. 具體實(shí)踐

app.js

(async function() {    const Koa = require('koa');    const KoaStaticCache = require('koa-static-cache');    const KoaBodyParser = require('koa-bodyparser');    const router = require('./routers/main');    const Session = require('koa-session');    const app = new Koa();    // app.keys = new KeyGrip(['im a newer secret', 'i like turtle'], 'sha256');

    app.keys = ['app'];

    app.use( Session({
        key: 'koa:sess',
        maxAge: 86400000,
        autoCommit: true,
        overwrite: true,
        httpOnly: true,
        signed: true,
        rolling: false,
        renew: false
    }, app) );    // app.use( async (ctx, next) => {
    //     ctx.set('Access-Control-Allow-Origin','*');
    //     await next();
    // } );

    app.use( KoaStaticCache('./public', {
        prefix: 'public',
        gzip: true
    }) );

    app.use( KoaBodyParser() );

    app.use( router.routes() );

    app.listen(8088);

})();

models/index.js

'use strict';const fs = require('fs');const path = require('path');const Sequelize = require('sequelize');const basename = path.basename(__filename);const env = process.env.NODE_ENV || 'development';const config = require(__dirname + '/../config/config.json')[env];const db = {};let sequelize;if (config.use_env_variable) { sequelize = new Sequelize(process.env[config.use_env_variable], config); } else { sequelize = new Sequelize(config.database, config.username, config.password, config); }// 自動(dòng)導(dǎo)入 models 文件夾下的所有文件,比如user.js這個(gè)模型文件// 自動(dòng)加載模型并執(zhí)行// let users = require('./users');// let UsersModel = users(sequelize, Sequelize);// db[UsersModel.name] = UsersModel; // db['Users'] = UsersModel;// 下面通過fs自動(dòng)加載所有的文件,并執(zhí)行,同時(shí)生成的模型對(duì)象掛載到db對(duì)象下面,最后返回出去fs .readdirSync(__dirname) .filter(file => { return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); }) .forEach(file => { const model = sequelize['import'](path.join(__dirname, file)); db[model.name] = model; });Object.keys(db).forEach(modelName => { if (db[modelName].associate) { db[modelName].associate(db); } }); db.sequelize = sequelize; db.Sequelize = Sequelize;module.exports = db;

routers/main.js

const KoaRouter = require('koa-router');const md5 = require('md5');const Models = require('../models');const Sequelize = require('sequelize');const router = new KoaRouter();

router.post('/register', async ctx => {    // console.log(ctx.request.body);
    let username = ctx.request.body.username.trim();    let password = ctx.request.body.password.trim();    let repassword = ctx.request.body.repassword.trim();    if (username=='' || password == '' || repassword == '') {        return ctx.body = {
            code: 1,
            data: '用戶名或密碼不能為空'
        }
    }    if (password != repassword) {        return ctx.body = {
            code: 2,
            data: '兩次輸入的密碼不一致'
        }
    }    let user = await Models.Users.findOne({        where: {
            username
        }
    });    if (user !== null) {        return ctx.body = {
            code: 3,
            data: '當(dāng)前用戶已經(jīng)被注冊(cè)了'
        }
    }    let newUser = await Models.Users.build({
        username,
        password: md5(password)
    }).save();

    ctx.body = {
        code: 0,
        data: {
            id: newUser.get('id'),
            username: newUser.get('username')
        }
    }

  });

  router.post('/login', async ctx => {      let username = ctx.request.body.username;      let password = ctx.request.body.password;      let user = await Models.Users.findOne({          where: {
              username
          }
      });      if (user === null) {          return ctx.body = {
              code: 1,
              data: '不存在該用戶'
          }
      }      if (user.get('password') !== md5(password)) {          return ctx.body = {
              code: 1,
              data: '密碼錯(cuò)誤'
          }
      }      
      // ctx.cookies.set('uid', user.get('id'), {
      //     httpOnly: false
      // });

      // 服務(wù)端發(fā)送一個(gè)約定好的cookie,來表示當(dāng)前是登錄
      // ctx.cookies.set('uid', user.get('id'), {
      //     // httpOnly,表示當(dāng)前的cookie是否允許客戶端進(jìn)行操作(js),如果為true,那么就表示這個(gè)cookie是能用戶http協(xié)議的數(shù)據(jù)傳輸
      //     httpOnly: true,
      //     signed: true
      // });
      ctx.cookies.set('username', user.get('username'), {
          httpOnly: false
      });

      ctx.session.uid = 1;

      ctx.body = {
          code: 0,
          data: {
              id: user.get('id'),
              username: user.get('username')
          }
      }
  });

})

module.exports = router;

4. 測(cè)試接口,注冊(cè)用戶,添加數(shù)據(jù)

可以在postman中測(cè)試接口,地址http://localhost:8088/register,注冊(cè)用戶

node app.js
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
前端-接入層注入問題
5 基于Koa的egg.js企業(yè)級(jí)后端框架使用
SMARTY模板中如何使用get,post,request,cookies,session,server變量
一個(gè)完整的Node.js RESTful API
你必須要知道的babel二三事
修改ANativeWindow 使用OPENGL EGL
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服