vuejs前端+eggjs後端+mysql數據庫+SequelizeORM+redis數據流緩存的項目經驗

最近用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 配置
  config.sequelize = {
    dialect: 'mysql',
    host: 'localhost',
    port: '3306',
    user: 'root', // 用戶名
    password: '123456', // 用戶密碼
    database: 'db1', // 數據庫名
    pool: {
      max: 20,
      min: 0,
      idle: 10000,
    },
  };

  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文件裏

  config.sequelize = {
    dialect: 'mysql',
    host: 'localhost',
    port: '3306',
    user: 'root', // 用戶名
    password: '123456', // 用戶密碼
    database: 'hrt_tag', // 數據庫名
    pool: {
      max: 20,
      min: 0,
      idle: 10000,
    },
  };
  config.redis = {
    client: {
      port: 6379,          // Redis port
      host: '127.0.0.1',   // Redis host
      password: '123456',
      db: 0
    }
  }
 

      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 = {
         status: 200,
         ok: true,
         msg: '讀取成功',
         data: dataInfo
  };
 
  

以上就是用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 清空當前數據庫

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章