zoukankan      html  css  js  c++  java
  • 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里加配置:

    reidis安装:npm i egg-redis --save


    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
        }
      }
     //redis也可以搞成集群或配置多个:https://github.com/eggjs/egg-redis

          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 清空当前数据库
  • 相关阅读:
    android 近百个源码项目【转】
    503 Service Temporarily Unavailable
    linux 复制文件夹内所有文件到另一个文件夹
    国甲魔方(1)
    大雁展翅,轮回,国甲,国丙,速龙,傲龙,御龙这些魔方有什么区别
    77教师一定要看的15部电影【附下载地址】
    教师一定要看的15部电影
    孩子
    为什么我的 app:actionViewClass="android.widget.SearchView"和app:showAsAction="ifRoom|collapseActionView"才有
    大数据征信 是伪命题?还是金融行业的救世主?
  • 原文地址:https://www.cnblogs.com/zzwlong/p/14237500.html
Copyright © 2011-2022 走看看