zoukankan      html  css  js  c++  java
  • 第二百九十六节,python操作redis缓存-Hash哈希类型,可以理解为字典类型

    第二百九十六节,python操作redis缓存-Hash哈希类型,可以理解为字典类型

    Hash操作,redis中Hash在内存中的存储格式如下图:

    hset(name, key, value)name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
      name,redis的name
      key,name对应的hash中的key
      value,name对应的hash中的value
      hsetnx(name, key, value),当name对应的hash中不存在当前key时则创建(相当于添加)

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hset('foo', 'k1','v1')                                    #hset(name, key, value)name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
    
    f = r.hgetall('foo')                                        #获取名称对应的键和值
    print(f)
    #返回:{b'k1': b'v1'}

    hmset(name, mapping)在name对应的hash中批量设置键值对
      name,redis的name
      mapping,字典,如:{'k1':'v1', 'k2': 'v2'}

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'v1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    f = r.hgetall('foo')                                        #获取名称对应的键和值
    print(f)
    #返回:{b'k2': b'v2', b'k1': b'v1'}

    hget(name,key)在name对应的hash中获取根据key获取value

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'v1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    # f = r.hgetall('foo')                                        #获取名称对应的键和值
    
    f =  r.hget('foo','k1')                                       #hget(name,key)在name对应的hash中获取根据key获取value
    print(f)
    #返回:b'v1'

    hmget(name, keys, *args)在name对应的hash中获取多个key的值
      name,reids对应的name
      keys,要获取key集合,如:['k1', 'k2', 'k3']
      *args,要获取的key,如:k1,k2,k3
      如:r.mget('xx', ['k1', 'k2'])
      或:r.hmget('xx', 'k1', 'k2')

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'v1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    # f = r.hgetall('foo')                                        #获取名称对应的键和值
    
    f =  r.hmget('foo',['k1', 'k2'])                                      #hmget(name, keys, *args)在name对应的hash中获取多个key的值
    #或者
    f2 =  r.hmget('foo','k1', 'k2')
    print(f)
    print(f2)
    
    #返回:
    # [b'v1', b'v2']
    # [b'v1', b'v2']

    hgetall(name)获取name对应hash的所有键值

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'v1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    f = r.hgetall('foo')                                        #获取name对应hash的所有键值
    print(f)
    
    #返回:
    # {b'k1': b'v1', b'k2': b'v2'}

    hlen(name)获取name对应的hash中键值对的个数

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'v1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    # f = r.hgetall('foo')                                        #获取name对应hash的所有键值
    
    f = r.hlen('foo')                                             #hlen(name)获取name对应的hash中键值对的个数
    print(f)
    
    #返回:
    # 2

    hkeys(name)获取name对应的hash中所有的key的值

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'v1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    # f = r.hgetall('foo')                                        #获取name对应hash的所有键值
    
    f = r.hkeys('foo')                                            #hkeys(name)获取name对应的hash中所有的key
    print(f)
    
    #返回:
    # [b'k2', b'k1']

    hvals(name)获取name对应的hash中所有的value的值

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'v1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    # f = r.hgetall('foo')                                        #获取name对应hash的所有键值
    
    f = r.hvals('foo')                                            #hvals(name)获取name对应的hash中所有的value的值
    print(f)
    
    #返回:
    # [b'v2', b'v1']

    hexists(name, key)检查name对应的hash是否存在当前传入的key

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'v1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    # f = r.hgetall('foo')                                        #获取name对应hash的所有键值
    
    f = r.hexists('foo','k1')                                          #hexists(name, key)检查name对应的hash是否存在当前传入的key
    print(f)
    
    #返回:
    #True

    hdel(name,*keys)将name对应的hash中指定key的键值对删除

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'v1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    r.hdel('foo','k1')                                          #hdel(name,*keys)将name对应的hash中指定key的键值对删除
    
    f = r.hgetall('foo')                                        #获取name对应hash的所有键值
    print(f)
    
    #返回:
    #{b'k2': b'v2'}

    hincrby(name, key, amount=1)自增整数,name对应的hash中的指定key的值,不存在则创建key=amount
      name,redis中的name
      key, hash对应的key
      amount,自增数(整数)

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    r.hincrby('foo','k1',amount=1)                              #hincrby(name, key, amount=1)自增整数,name对应的hash中的指定key的值,不存在则创建key=amount
    
    f = r.hgetall('foo')                                        #获取name对应hash的所有键值
    print(f)
    
    #返回:
    #{b'k1': b'2', b'k2': b'v2'}

    hincrbyfloat(name, key, amount=1.0)自增浮点数 name对应的hash中的指定key的值,不存在则创建key=amount
      name,redis中的name
      key, hash对应的key
      amount,自增数(浮点数)

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    r.hmset('foo',{'k1':'1', 'k2': 'v2'})                      #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    r.hincrbyfloat('foo','k1',amount=1.2)                       #hincrbyfloat(name, key, amount=1.0)自增浮点数 name对应的hash中的指定key的值,不存在则创建key=amount
    
    f = r.hgetall('foo')                                        #获取name对应hash的所有键值
    print(f)
    
    #返回:
    #{b'k1': b'2.2', b'k2': b'v2'}

    hscan(name, cursor=0, match=None, count=None)增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而防止内存被撑爆
      name,redis的name
      cursor,游标(基于游标分批取获取数据)
      match,匹配指定key,默认None 表示所有的key
      count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数
      如:
      第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)
      第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)
      ...
      直到返回值cursor的值为0时,表示数据已经通过分片获取完毕

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                            #连接连接池
    r.hmset('foo',{'k1':'1', 'k2': 'v2','m2':'mm'})                  #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    cursor1, data1 = r.hscan('foo',cursor=0,match='*2',count=None)        #获取name对应的键,以2结尾的键
    print(cursor1, data1)                                                 #返回两个值,第一个是获取的游标位置,第二个是获取到的数据
    
    cursor2, data2 = r.hscan('foo',cursor=cursor1,match='*2',count=None)    #第二次获取,游标使用第一次返回的游标位置
    print(cursor2, data2)
    
    #返回:
    # 0 {b'm2': b'mm', b'k2': b'v2'}
    # 0 {b'm2': b'mm', b'k2': b'v2'}

    hscan_iter(name, match=None, count=None)利用yield封装hscan创建生成器,实现分批去redis中获取数据
      match,匹配指定key,默认None 表示所有的key
      count,每次分片最少获取个数,默认None表示采用Redis的默认分片个数

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                            #连接连接池
    r.hmset('foo',{'k1':'1', 'k2': 'v2','m2':'mm'})                  #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    for item in r.hscan_iter('foo'):
        print(item)
    
    #返回:
    # (b'm2', b'mm')
    # (b'k2', b'v2')
    # (b'k1', b'1')

    哈希类型设置过期时间

    哈希类型只能将整个哈希表设置过期时间,过期后name对应里面的所有键值对就过期了

    expire(name,过期时间秒)设置哈希表过期时间

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                            #连接连接池
    r.hmset('foo',{'k1':'1', 'k2': 'v2','m2':'mm'})                  #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    r.expire('foo',10)                                               #expire(name,过期时间秒)设置哈希表过期时间

    exists(name)判断一个哈希名称是否存在

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    import redis                #导入操作redis模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)  #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                            #连接连接池
    r.hmset('foo',{'k1':'1', 'k2': 'v2','m2':'mm'})                  #hmset(name, mapping)在name对应的hash中批量设置键值对
    
    ret = r.exists('foo')                                            #exists(name)判断一个哈希名称是否存在
    print(ret)
    #返回
    #True

    Hash哈希类型结合cookie,实现session

    session封装模块

    #!/usr/bin/env python
    #coding:utf-8
    
    import hashlib                                          #导入md5加密模块
    import time                                             #导入时间模块
    import redis                                            #导入操作redis缓存模块
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379)    #配置连接池连接信息
    
    r = redis.Redis(connection_pool=pool)                       #连接连接池
    
    
    class Session:
        def __init__(self,_self):
            """
            self._self = _self 接收创建Session时传进来的对象,也就是继承对象
            self.cookie 设置self.cookie名称
            self.guo_qi 设置cookie和Redis过期时间
            self.sui_ji 接收随机密串
            """
            self._self = _self
            self.cookie = "_session_"
            self.guo_qi = 60
            self.redis_guo_qi = self.guo_qi
            self.cookie_guo_qi = time.time() + self.guo_qi
            self.sui_ji = self.suiji_str
    
    
        @property  # 声明特性方法,执行方法是不用写括号
        def suiji_str(self):
            """
            返回值:随机密串
            uiji_str 生成随机密串方法
            """
            obj = hashlib.md5()
            obj.update(bytes(str(time.time()), encoding='utf-8'))
            random_str = obj.hexdigest()
            return random_str
    
    
        def chuang_jian(self):
            """
            返回值:无
            chuang_jian() 创建浏览器cookie和生成Redis缓冲哈希表
            """
            self._self.set_cookie(self.cookie, self.sui_ji, expires=self.cookie_guo_qi)
            r.hset(self.sui_ji, 'deng_lu_zhuang_tai', None)
            r.expire(self.sui_ji, self.redis_guo_qi)
    
    
        def __setitem__(self, key, value):
            """
            返回值:无
            接收键和值设置cookie值对应在Redis缓存的哈希表名称里的键值对
            使用方式:
            session对象[键]=值,如:session['deng_lu_zhuang_tai'] = True
            """
            if not r.exists(self._self.get_cookie(self.cookie)):
                self.chuang_jian()
                r.hset(self.sui_ji, key, value)
            if r.exists(self._self.get_cookie(self.cookie)):
                r.hset(self._self.get_cookie(self.cookie), key, value)
    
    
        def __getitem__(self,key):
            """
            使用方法:Session对象[xxx]
            功能:获取cookie对应Redis缓存里哈希表名称里的指定键的值,键为接收到参数的值,存在返回值,不存在返回None
            """
            if not r.exists(self._self.get_cookie(self.cookie)):
                return None
            else:
                fanui = r.hget(self._self.get_cookie(self.cookie), key)
                if not fanui:
                    return None
                else:
                    return fanui.decode("utf-8")

    Tornado框架逻辑处理

    #!/usr/bin/env python
    #coding:utf-8
    
    import tornado.ioloop
    import tornado.web                              #导入tornado模块下的web文件
    import session as se                            #导入Session模块
    
    
    
    
    class indexHandler(tornado.web.RequestHandler):  #定义一个类,继承tornado.web下的RequestHandler类
        def get(self):                                              #get()方法,接收get方式请求
            session = se.Session(self)
            if session['deng_lu_zhuang_tai']:                       #判断当前用户session里的登录状态
                self.render("index.html")                           # 显示index.html文件  #显示查看页面
            else:
                self.redirect("/dlu")
    
    
    class dluHandler(tornado.web.RequestHandler):
        def get(self):
            session = se.Session(self)
            if session['deng_lu_zhuang_tai']:                       #判断当前用户session里的登录状态
                self.redirect("/index")                             #跳转查看页面
            else:
                self.render("dlu.html")
    
        def post(self):
            session = se.Session(self)
            if session['deng_lu_zhuang_tai']:
                self.redirect("/index")
            else:
                yong_hu_ming = self.get_argument('yhm')                 #接收用户输入的登录账号
                mi_ma = self.get_argument('mim')                        #接收用户输入的登录密码
                session['yong_hu_ming'] = yong_hu_ming
                session['mi_ma'] = mi_ma
                session['deng_lu_zhuang_tai'] = True
                self.redirect("/index")
    
    
    
    settings = {                                        #html文件归类配置,设置一个字典
        "template_path":"views",                     #键为template_path固定的,值为要存放HTML的文件夹名称
        "static_path":"statics",                         #键为static_path固定的,值为要存放js和css的文件夹名称
        "cookie_secret":"61oETzKXQAGaYdkL5gEmGeJJY",
    }
    
    #路由映射
    application = tornado.web.Application([         #创建一个变量等于tornado.web下的Application方法
        (r"/index", indexHandler),                   #判断用户请求路径后缀是否匹配字符串index,如果匹配执行MainHandler方法
        (r"/dlu", dluHandler),
    
    ],**settings)                                   #将html文件归类配置字典,写在路由映射的第二个参数里
    
    if __name__ == "__main__":
        #内部socket运行起来
        application.listen(8888)                    #设置端口
        tornado.ioloop.IOLoop.instance().start()

    实现用户登录后,每次访问一个页面让Hash哈希表和合cookie过期时间累加

    Tornado框架逻辑处理,配置好html模板可以调用的py模块

    py模块定义一个执行函数,函数里获取到客户cookie值,根据cookie值找到Redis里对应的哈希表

    cookie时间累加,在将Redis里对应的哈希表时间累加

    最后在网站的html模板通用区域执行这个函数实现过期时间累加

  • 相关阅读:
    洛谷春季多校第四场
    HZNU Training 8 for Zhejiang Provincial Competition 2020
    HZNU Training 6 for Zhejiang Provincial Competition 2020
    二分图
    HZNU Training 5 for Zhejiang Provincial Competition 2020
    洛谷春季 ACM 多校训练第二周
    HZNU Training 2 for Zhejiang Provincial Competition 2020
    TestNG入门教程-12-Java代码执行testng.xml和失败后重跑
    eclipse导出可执行jar包步骤
    创建可执行的JAR包并运行
  • 原文地址:https://www.cnblogs.com/adc8868/p/7110623.html
Copyright © 2011-2022 走看看