Sequelize是Nodejs生态系统中著名的ORM框架。通过ORM框架,可以使用对象操作数据库表数据,提高开发效率和代码可读性,方便后期维护。今天我们主要介绍通过迁移[Migration]创建数据库和表。迁移的好处可以与git相提并论。通过每次创建一个迁移文件来支持数据库表结构的更新和回滚,也便于协同开发,也避免了人工手动修改数据库,用代码自动管理。如果换了电脑,就不用复制数据库了。直接运行迁移就可以完全恢复开发环境,大大减轻了精神负担。1.创建项目,安装node包依赖mkdirnode_workcdnode_workmkdirappnpminit-ynpmisequelize-clisequelizemysql2koa2。初始化Sequelizenpxsequelizeinit运行后会生成四个目录:config、migrations、models、seedersconfig:{"development":{"username":"root","password":"root","database":"app_development","host":"127.0.0.1","port":8889,"dialect":"mysql","timezone":"+08:00"},"test":{"username":"root",“密码”:空,“数据库”:“app_test”,“主机”:“127.0.0.1”,“方言”:“mysql”},“生产”:{“用户名”:“root”,“密码”:null,"database":"app_production","host":"127.0.0.1","dialect":"mysql"}}环境env=>{Configuration}不同的环境对应不同的配置,也可以自定义环境.比如homeenv就是指process.env.NODE_ENV,可以通过设置环境变量来改变,比如exportNODE_ENV=production;migration这个时候还可以指定环境:npxsequelizedb:migrate--envproduction来连接production配置对应的数据库。创建数据库:npxsequelizedb:create表示npx是npm5.2自带的命令。你不需要全局安装sequelize。使用时,如果本地没有,可以去npm仓库下载;下载后或者如果您已经在本地下载了它,请运行脚本命令。这样可以避免局部全局包过期和环境问题,每次迁移都使用最新版本:迁移文件npxsequelizemodel:generate--nameUser--attributesusername:string执行后得到20180918055558-create-user.js迁移文件会生成,models/user.js模型文件的其他字段可以在migration文件中完成,最后运行npxsequelizedb:migrate,可以看到数据库中生成了users表'usestrict';module.exports={up:(queryInterface,Sequelize)=>{returnqueryInterface.createTable('Users',{id:{allowNull:false,autoIncrement:true,primaryKey:true,type:Sequelize.INTEGER},username:{类型:Sequelize.STRING(20),allowNull:false},密码:{type:Sequelize.CHAR(32),allowNull:false},createdAt:{allowNull:false,类型:Sequelize.DATE},updatedAt:{allowNull:false,type:Sequelize.DATE}},{tableName:'users',charset:'utf8mb4',collat??e:'utf8mb4_bin',define:{timestamps:true}}).then(()=>{//添加索引returnqueryInterface.addIndex('users',{name:'username',unique:true,fields:['username']});});},//在回退期间执行,向下删除表:(queryInterface,Sequelize)=>{returnqueryInterface.dropTable('Users');}};执行迁移:npxsequelizedb:migratenpxsequelizedb:migrate:all撤消迁移:npxsequelizedb:migrate:undo最近的npxsequelizedb:migrate:undo:allnpxsequelizedb:migrate:undo:all--toXXXXXXXXXXXXXX-create-posts.js--from,--to参数,可以指定迁移文件models:模型文件model:generate生成的模型在这个目录下'usestrict';module.exports={up:(queryInterface,Sequelize)=>{returnqueryInterface.createTable('Users',{id:{allowNull:false,autoIncrement:true,primaryKey:true,type:Sequelize.INTEGER},username:{type:Sequelize.STRING(20),allowNull:false},密码:{类型:Sequelize.CHAR(32),allowNull:false},createdAt:{allowNull:false,类型:Sequelize.DATE},updatedAt:{allowNull:false,类型:Sequelize.DATE}},{tableName:'users',charset:'utf8mb4',collat??e:'utf8mb4_bin',}).then(()=>{returnqueryInterface.addIndex('users',{name:'username',unique:true,fields:['用户名']});});},down:(queryInterface,Sequelize)=>{returnqueryInterface.dropTable('Users');}};模型对象创建,默认值会自动赋值,更新createdAt,updatedAt两个时间戳字段下面给出一个完整的例子。Seeders:填充数据文件创建种子文件:npxsequelizeseed:generate--namedemo-user执行后会得到20180918090545-demo-user.js'usestrict';constmd5=require('md5')module.exports={up:(queryInterface,Sequelize)=>{returnqueryInterface.bulkInsert('Users',[{用户名:'Kimoo',密码:md5('123456'),createdAt:newDate(),updatedAt:newDate(),},{用户名:'Reci',密码:md5('123321'),createdAt:newDate(),updatedAt:newDate(),}],{});},down:(queryInterface,Sequelize)=>{/*在这里添加恢复命令。返回正确处理异步性的承诺。示例:returnqueryInterface.bulkDelete('Person',null,{});*/returnqueryInterface.bulkDelete('Users',null,{});}};填充数据:npxsequelizedb:seed:all撤消数据:npxsequelizedb:seed:undo最新的npxsequelizedb:seed:undo--seedname-of-seed-as-in-dataspecificnpxsequelizedb:seed:你ndo:all3。实体实现app.js(asyncfunction(){constKoa=require('koa');constKoaStaticCache=require('koa-static-cache');constKoaBodyParser=require('koa-bodyparser');constrouter=require('./routers/main');constSession=require('koa-session');constapp=newKoa();//app.keys=newKeyGrip(['我是一个新的秘密','我像乌龟'],'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','*');//awaitnext();//});app.use(KoaStaticCache('./public',{prefix:'public',gzip:true}));app.use(KoaBodyParser());app.use(router.routes());app.listen(8088);})();models/index.js'usestrict';constfs=require('fs');constpath=require('path');constSequelize=require('sequelize');constbasename=path.basename(__filename);constenv=process.env.NODE_ENV||'development';constconfig=require(__dirname+'/../config/config.json')[env];constdb={};letsequelize;if(config.use_env_variable){sequelize=newSequelize(process.env[config.use_env_variable],config);}else{sequelize=newSequelize(config.database,config.username,config.password,config);}//自动导入models文件夹下的所有文件,比如user.js模型文件//自动加载模型并执行//letusers=require('./users');//letUsersModel=users(sequelize,Sequelize);//db[UsersModel.name]=UsersModel;//db['Users']=UsersModel;//下面自动通过fs加载所有文件并执行。同时将生成的模型对象挂载到db对象下,最后返回fs.readdirSync(__dirname).filter(file=>{return(file.indexOf('.')!==0)&&(file!==basename)&&(file.slice(-3)==='.js');}).forEach(file=>{constmodel=sequelize['import'](path.join(__dirname,文件));db[型号.名称]=型号;});Object.keys(db).forEach(modelName=>{if(db[modelName].associate){db[modelName].associate(db);}});db.sequelize=sequelize;db.Sequelize=Sequelize;module.exports=db;routers/main.jsconstKoaRouter=require('koa-router');constmd5=require('md5');constModels=require('../models');constSequelize=require('sequelize');constrouter=newKoaRouter();router.post('/register',asyncctx=>{//console.log(ctx.request.body);letusername=ctx.request.body.username.trim();letpassword=ctx.request.body.password.trim();letrepassword=ctx.request.body.repassword.trim();if(username==''||password==''||repassword==''){returnctx.body={code:1,data:'用户名或密码不能为空'}}if(password!=repassword){returnctx.body={code:2,data:'两次输入的密码不同'}}letuser=awaitModels.Users.findOne({其中:{用户名}});if(user!==null){returnctx.body={code:3,data:'当以前用户已经被注册了'}}letnewUser=awaitModels.Users.build({username,password:md5(password)})。节省();ctx.body={code:0,data:{id:newUser.get('id'),username:newUser.get('username')}}});router.post('/login',asyncctx=>{letusername=ctx.request.body.username;letpassword=ctx.request.body.password;letuser=awaitModels.Users.findOne({其中:{username}});if(user===null){returnctx.body={code:1,data:'不存在该用户'}}if(user.get('password')!==md5(password)){returnctx.body={code:1,data:'密码错误'}}//ctx.cookies.set('uid',user.get('id'),{//httpOnly:false//});//服务器发送一个同意的cookie以表明它当前已登录//ctx.cookies。set('uid',user.get('id'),{////httpOnly,表示当前cookie是否允许客户端操作(js),如果为true,则说明这个cookie可以使用http协议//httpOnly:true,//signed:true//});ctx.cookies.set('用户名',user.get('用户名'),{httpOnly:false});ctx.session.uid=1;ctx.body={code:0,data:{id:user.get('id'),username:user.get('username')}}});})module.exports=router;4.测试界面,注册用户,添加数据可以在postman中测试界面,地址http://localhost:8088/register,注册用户节点app.js
