Sequelize是Node.js v4及更高版本的基於promise的ORM。它支持方言PostgreSQL,MySQL,SQLite和MSSQL,並具備堅實的事務支持,關係,讀取複製等等。Egg官方也有egg-sequelize的插件,因此這裏使用它來進行代碼中全部SQL操做.html
添加並開啓sequelize插件:node
// {workdir}/config/plugin.js // 掛在到app下,經過app.sequelize使用 exports.sessionRedis = { enable: true, package: "egg-sequelize" };
啓動前建立表:redis
// {workdir}/app.js module.exports = app => { app.beforeStart(async function () { await app.model.sync({ force: false }); // false 爲不覆蓋 true會刪除再建立 }); };
添加model文件:npm
// {workdir}/app/model/user.js 必定要使用此目錄 // 掛在到ctx下經過 ctx.model.User.fn()使用 module.exports = app => { const { STRING, INTEGER, DATE, BIGINT } = app.Sequelize; const User = app.model.define("user", { login: STRING, id: { type: BIGINT(11), autoIncrement:true, primaryKey : true, unique : true }, role: { type: INTEGER, default: 0 }, name: STRING(30), passwd: STRING(32), age: INTEGER, last_sign_in_at: DATE, created_at: DATE, updated_at: DATE }); return User; };
存在問題 添加外鍵沒有解決
文檔中能夠經過app.createAnonymousContext()
建立一個匿名ctx,但這裏報錯,因此沒法獲取其它model,這裏設置外鍵須要promise
sequelize經常使用API:session
Model.findOne({ where: {filed: 'value'} }).then(...) // query Model.create({ filed1: 'value', filed2: 'value' }).then(...) // create Model.destroy() // delete // ...
官方文檔地址: http://docs.sequelizejs.com
中文APIapp
Egg已經內置了Seesion插件,經過ctx.session
能夠直接使用,
能夠將session自定義外部存儲,實現以下async
// {workdir}/app.js module.exports = app => { app.sessionStore = { * get (key) { // return value; }, * set (key, value, maxAge) { // set key to store }, * destroy (key) { // destroy key }, }; };
但這裏使用了egg-redis
和egg-session-redis
兩個插件來將session存儲到redis中.
啓用插件:fetch
// {workdir}/config/plugin.js exports.sessionRedis = { enable: true, package: "egg-session-redis" }; exports.redis = { enable: true, package: "egg-redis" };
插件配置:ui
// {workdir}/config/config.default.js const database = "egg"; const redisHost = "192.168.189.130"; const dbHost = "localhost"; module.exports = appInfo => { const config = {}; config.redis = { // 單個redis client: { port: 6379, // Redis port host: redisHost, // Redis host password: "", db: 0 } }; config.sessionRedis = { key: "EGG_SESSION", maxAge: 24 * 3600 * 1000, // 1 天 httpOnly: true, encrypt: false }; return config; };
session使用實例:
// {workdir}/app/controller/auth.js ... async login(ctx) { ctx.validate(userRule); const user = await ctx.service.auth.login(ctx.request.body); ctx.assert(user, "用戶名或密碼錯誤"); const token = await app.genToken(user.id, ctx.request.ip); ctx.session.user = user.id; ctx.session.token = token.id; ctx.status = 204; } ...
token主要用來記錄一些用戶登陸的信息,存儲在db中.
首先定義token的model:
// {workdir}/app/model/token.js module.exports = app => { const { STRING, DATE, BIGINT, BOOLEAN } = app.Sequelize; const Token = app.model.define("token", { id: { type: BIGINT(11), autoIncrement:true, primaryKey : true, unique : true }, user: BIGINT(11), expire: DATE, ip: STRING, valid: BOOLEAN }); return Token; };
token DB 操做的service層代碼:
// {workdir}/app/service/token.js const moment = require("moment"); module.exports = app => { class Token extends app.Service { async fetchOne (id) { const token = await this.ctx.model.Token.find({ where: { id: id } }); return token; } async genToken (userId, ip) { const expire = new Date(moment().add(1, "days")); const token = await this.model.Token.create({ expire, ip, user: userId, valid: true }); return token; }; } return Token; };
登陸後session中記錄token的id ....在中間件中添加token驗證 ....