最近用vuejs+eggjs+mysql寫了一個項目,後來爲了優化,公司又決定加redis。然而之前沒接觸過,只能一步一步摸索,
從一開始以爲egg只能綁定一個特定的數據庫mysql的,網上查閱了好多資料才知道可以同時綁定mysql和redis。
先說說大概流程:vue前端搭建===》egg後端搭建===》egg引入mysql、Sequelize和redis(這兩個庫得在本地先建) ===》egg+mysql+redis寫接口 ===》 vue前端讀數據。
其中redis讀數據因爲是第一次接觸,比較難,上手之後比用mysql簡單方便多了。
vue和egg搭建我就不多寫了,按照官網直接來就好,現在側重寫eggjs同時用mysql和redis。
一、egg引入mysql和redis:
1)用Sequelize來連msyql:
npm install --save egg-sequelize mysql2
在 config/plugin.js 中引入 egg-sequelize 插件
exports.sequelize = {
enable: true,
package: 'egg-sequelize',
};
在 config/config.default.js
中編寫 sequelize 配置
2)egg裏分別寫controller、model、service項目代碼,這裏就不一一寫了,按照官網來,規則一般都是
a) controller控制用戶輸入和返回相應的結果,寫接口的路由也是根據這裏的路徑來寫的
比如:get類型的接口:router.get('/api/data1', controller.data1.data1Function); 其中/api/data1是給前端的接口路徑,
data1是controller裏對應的文件名,data1Function是對應文件裏對應請求數據的函數。
而且controller裏面的函數直接請求service裏的函數來請求數據,比如controller裏的一個函數:
所以egg請求流程:路由裏的接口調用controller裏的函數,controller函數再調用service裏的函數,獲取數據:路由router ==》controller ==》service
class AController extends Controller { async activeOrgDay() { const { ctx } = this; const result = await ctx.service.aService.getData();
//其中service是文件夾名,aService是service文件夾裏的一個文件名,getData()是這個文件裏請求數據庫數據的函數
ctx.body = result; } }
b) model是mysql表裏的映射,mysql一個表對應一個model裏的文件,而且裏面的數據類型要和mysql裏的一一對應。
c) service是處理邏輯,請求數據庫數據的。由controller裏的函數觸發這裏。既然是請求數據的,這裏也可以寫相應的redis。
3)egg引入redis,和引入mysql一樣。分別在config/plugin.js和config/config.default.js里加配置:
config/plugin.js文件裏
module.exports = { sequelize: { enable: true, package: 'egg-sequelize', }, redis: { enable: true, package: 'egg-redis', }, cors: { enable: true, package: 'egg-cors', }, jwt: { enable: true, package: 'egg-jwt', }, };
config/config.default.js文件裏
4)用redis獲取數據。在egg配置好redis後就可以直接在文件裏使用,而且不需要和Sequelize那樣在model裏寫數據庫映射。比如:獲取zset數據,直接在service的文件裏寫
let dataInfo = (await this.app.redis.zrevrange('dataKey', 0, -1, 'withscores')).toString();//zrevrange是獲取zset數據的,toString()是把獲取的數據轉爲字符串型
//這裏需要注意的是上面說service是通過controller裏觸發的,所以通過redis獲取數據,直接在controller新建個文件用來觸發service裏獲取redis數據的函數就好。
//......數據已經拿到,再處理成返回給前端格式的就好啦,怎麼處理方法有各種,這裏就不多寫了。
return ctx.body = {
以上就是用redis獲取數據。
二、redis相關知識:redis有string、list、hash、zset、set等,具體操作請參照右側的鏈接,我下面寫的也是裏面的:https://blog.csdn.net/altaba/article/details/101692857
以下是常見的nodejs 中使用redis,使用簡單:
首先安裝 npm install redis --save
demo
var redis = require('redis'); var client = redis.createClient('6379', '127.0.0.1'); client.auth("password"); client.set('hello','This is a value'); client.expire('hello',10) //設置過期時間 client.exists('key') //判斷鍵是否存在 client.del('key1') client.get('hello');
//stirng
命令 行爲 返回值 使用示例(略去回調函數) set 設置存儲在給定鍵中的值 OK set('key', 'value') get 獲取存儲在給定鍵中的值 value/null get('key') del 刪除存儲在給定鍵中的值(任意類型) 1/0 del('key') incrby 將鍵存儲的值加上整數increment incrby('key', increment) decrby 將鍵存儲的值減去整數increment decrby('key', increment) incrbyfloat 將鍵存儲的值加上浮點數increment incrbyfloat('key', increment) append 將值value追加到給定鍵當前存儲值的末尾 append('key', 'new-value') getrange 獲取指定鍵的index範圍內的所有字符組成的子串 getrange('key', 'start-index', 'end-index') setrange 將指定鍵值從指定偏移量開始的子串設爲指定值 setrange('key', 'offset', 'new-string')
//list
命令 行爲 返回值 使用示例(略去回調函數) rpush 將給定值推入列表的右端 當前列表長度 rpush('key', 'value1' [,'value2']) (支持數組賦值) lrange 獲取列表在給定範圍上的所有值 array lrange('key', 0, -1) (返回所有值) lindex 獲取列表在給定位置上的單個元素 lindex('key', 1) lpop 從列表左端彈出一個值,並返回被彈出的值 lpop('key') rpop 從列表右端彈出一個值,並返回被彈出的值 rpop('key') ltrim 將列表按指定的index範圍裁減 ltrim('key', 'start', 'end')
eg: let dataInfo = (await this.app.redis.lrange(key,0,-1)).toString(); //toString要不要根據自己
//set
命令 行爲 返回值 使用示例(略去回調函數) sadd 將給定元素添加到集合 插入元素數量 sadd('key', 'value1'[, 'value2', ...]) (不支持數組賦值)(元素不允許重複) smembers 返回集合中包含的所有元素 array(無序) smembers('key') sismenber 檢查給定的元素是否存在於集合中 1/0 sismenber('key', 'value') srem 如果給定的元素在集合中,則移除此元素 1/0 srem('key', 'value') scad 返回集合包含的元素的數量 sacd('key') spop 隨機地移除集合中的一個元素,並返回此元素 spop('key') smove 集合元素的遷移 smove('source-key'dest-key', 'item') sdiff 返回那些存在於第一個集合,但不存在於其他集合的元素(差集) sdiff('key1', 'key2'[, 'key3', ...]) sdiffstore 將sdiff操作的結果存儲到指定的鍵中 sdiffstore('dest-key', 'key1', 'key2' [,'key3...]) sinter 返回那些同事存在於所有集合中的元素(交集) sinter('key1', 'key2'[, 'key3', ...]) sinterstore 將sinter操作的結果存儲到指定的鍵中 sinterstore('dest-key', 'key1', 'key2' [,'key3...]) sunion 返回那些至少存在於一個集合中的元素(並集) sunion('key1', 'key2'[, 'key3', ...]) sunionstore 將sunion操作的結果存儲到指定的鍵中 sunionstore('dest-key', 'key1', 'key2' [,'key3...])
//hash (用的比較多)
命令 行爲 返回值 使用示例(略去回調函數) hset 在散列裏面關聯起給定的鍵值對 1(新增)/0(更新) hset('hash-key', 'sub-key', 'value') (不支持數組、字符串) hget 獲取指定散列鍵的值 hget('hash-key', 'sub-key') hgetall 獲取散列包含的鍵值對 json hgetall('hash-key') hdel 如果給定鍵存在於散列裏面,則移除這個鍵 hdel('hash-key', 'sub-key') hmset 爲散列裏面的一個或多個鍵設置值 OK hmset('hash-key', obj) hmget 從散列裏面獲取一個或多個鍵的值 array hmget('hash-key', array) hlen 返回散列包含的鍵值對數量 hlen('hash-key') hexists 檢查給定鍵是否在散列中 1/0 hexists('hash-key', 'sub-key') hkeys 獲取散列包含的所有鍵 array hkeys('hash-key') hvals 獲取散列包含的所有值 array hvals('hash-key') hincrby 將存儲的鍵值以指定增量增加 返回增長後的值 hincrby('hash-key', 'sub-key', increment) (注:假如當前value不爲爲字符串,則會無輸出,程序停止在此處) hincrbyfloat 將存儲的鍵值以指定浮點數增加
egg: let dataInfo = await this.app.redis.hgetall('bigdata:datamonitor:consume:city');
//zset
命令 行爲 返回值 使用示例(略去回調函數) zadd 將一個帶有給定分支的成員添加到有序集合中 zadd('zset-key', score, 'key') (score爲int) zrange 根據元素在有序排列中的位置,從中取出元素 zrangebyscore 獲取有序集合在給定分值範圍內的所有元素 zrem 如果給定成員存在於有序集合,則移除 zcard 獲取一個有序集合中的成員數量 有序集的元素個數 zcard('key')
egg: let dataInfo = (await this.app.redis.zrevrange('{bigdata:datamonitor}:consume_count_org', 0, 8, 'withscores')).toString();
//keys命令組
命令 行爲 返回值 使用示例(略去回調函數) del 刪除一個(或多個)keys 被刪除的keys的數量 del('key1'[, 'key2', ...]) exists 查詢一個key是否存在 1/0 exists('key') expire 設置一個key的過期的秒數 1/0 expire('key', seconds) pexpire 設置一個key的過期的毫秒數 1/0 pexpire('key', milliseconds) expireat 設置一個UNIX時間戳的過期時間 1/0 expireat('key', timestamp) pexpireat 設置一個UNIX時間戳的過期時間(毫秒) 1/0 pexpireat('key', milliseconds-timestamp) persist 移除key的過期時間 1/0 persist('key') sort 對隊列、集合、有序集合排序 排序完成的隊列等 sort('key'[, pattern, limit offset count]) flushdb 清空當前數據庫