java Collections 排序--多條件排序例項
阿新 • • 發佈:2020-09-16
目錄
Redis使用
安裝
Python操作Redis普通連線
1 pip install redis #簡單使用 from redis import Redis #獲取redis連線 conn = Redis(host='127.0.0.1',port=6379) #key取值 ret = conn.get('name') print(ret)#b'alex'
Python操作Redis連線池
#redis_pool\redis_pool.py import redis #連線池物件,最大連線數100 POOL = redis.ConnectionPool(host='127.0.0.1',port=6379,max_connections=100) #redis_pool\redis_pool.py import redis from redis_pool import POOL #執行這句話就是從連線池拿出一個連線 r = redis.Redis(connection_pool=POOL) ret = r.get('name') print(ret)#b'alex'
Redis資料型別
string(字串)
list(列表)
set(集合)
zset(有序集合)
hash(雜湊)
String(字串)操作
string在記憶體中按照一個name一個value來儲存,看圖1 #加*表示重點 set(name, value, ex=None, px=None, nx=False, xx=False)* #設定值,不存在則建立,存在則修改, 引數: ex過期時間秒 px過期時間毫秒 nx為True時,key不存在時,才會執行,key存在則不執行操作 xx為True時,key不存在時,不會執行操作,key存在才會執行 setnx(name, value) #設定值,key不存在,才會執行,存在不會執行操作 setex(name, value, time) #設定值,引數time過期時間數字秒,或timedelta物件 psetex(name, time_ms, value) #設定值,引數time_ms過期時間數字毫秒,或timedelta物件 mset(*args,**kwargs)* #批量設定值,如 mset(k1='v1',k2='v2') mset({'k1':'v1','k2':'v2'}) get(key)* #獲取值 mget(keys,*args)* #批量獲取,如 mget('k1','k2') mget(['k1','k2']) getset(name, value)* #設定值並獲取原來的值 getrange(key, start, end) #獲取子序列,根據位元組獲取,非字元,引數: start開始位置的索引(前閉後閉)#漢字佔3個位元組 end結束位置的的索引(前閉後閉) setrange(name, offset, value) #修改字串內容,從指定索引向後修改,新值比原值長則向後新增,引數: 0ffset開始修改字串的索引,漢字佔3個位元組 value指要設定的指 setbit(name, offset, value) #對key對應的值的二進位制(010101001)進行操作,引數: offset開始位的索引,需要將值轉成二進位制(1位元組等於8位二進位制)索引 value值只能是0或1 getbit(name, offset) # 獲取key對應值開始索引的二進位制的值0或1 bitcount(key, start=None, end=None) #獲取key對應值的二進位制的值中的1的個數,引數: strat二進位制起始位置 end二進位制結束位置 bitop(operation, dest, *keys) #獲取多個值,並將值做位運算,將最後的值儲存至新的key對應的值,引數: operation可以是AND(並)、OR(或)、NOT(非)、XOR(異或) dest新的key名 *keys要查詢的key 如: conn.bitop('AND','name_1','name1','name2','name3') #獲取key,'name1','name2','name3'對應的值,做位運算(並集),然後將結果儲存到name_1對應的值中 strlen(name) #返回key對應值的位元組長度(漢字三個位元組) incr(self, name, amount=1)#incrby(self, name, amount=1)* #自增key對應的值,當key不存在時,則建立key對應值是amount的值,否則則自增,引數: amount自增數,必須是整數 incrbyfloat(self, name, amount=1.0) #自增key對應的值,key不存在時,則建立key=amount,否則自增,引數: amount自增數,必須是浮點型 decr(self, name, amount=1)* #自減key對應的值,key不存在時,則建立key=amount,否則則自減,引數: amount自減數,必須是整數 append(key, value)* #在key對應的值後面追加內容,引數: value要追加的字串
圖1
Hash(雜湊)操作
#Hash在記憶體中的儲存格式,value值必須是字串型別,看圖1
#加*表示重點
hset(name, key, value)*
#name對應的hash中設定一個鍵值對,不存在建立,存在則修改,引數:
name指redis儲存hash的name
key指name對應的hash的key
value指name對應的hash的value
hmset(name, mapping)*
#在name對應的hash中批量設定鍵值對,引數:
mapping是字典,比如{'k1':'v1','k2','v2'}
hget(name,key)*
#在name對應的hash中獲取根據key獲取value值
hmget(name, keys, *args)*
#在name對應的hash中獲取多個key對應的值。引數:
keys要獲取key的集合,如['k1','k2','k3']
*args要獲取的key,如k1,k2,k3
例項:
hmget('name',['k1','k2','k3'])
hmget('name',k1,k2,k3)
hgetall(name)
#獲取name對應的hash的所有鍵值
hlen(name)
#獲取name對應的hash的鍵值對的個數
hkeys(name)
#獲取name對應的hash的所有的key的值
hvals(name)
#獲取name對應的hash的所有的value的值
hexists(name, key)
#檢查name對應的hash是否存在key
hdel(name,*keys)
#將name對應的hash指定的key的鍵值對刪除
hincrby(name, key, amount=1)*
#自增name對應的hash中指定的key的值,不存在則建立key=amount,引數:
amount自增數,必須是整數
hincrbyfloat(name, key, amount=1.0)
#自增name對應的hash中指定key的值,不存在則建立key=amount,引數:
amount自增數,必須是浮點數
hscan(name, cursor=0, match=None, count=None)
#增量式迭代獲取,對於資料大的非常有用,hscan可以實現分片式獲取資料,並非一次性將資料全部獲取,導致記憶體被撐爆,引數:
cursor遊標,基於遊標分批獲取資料
match匹配指定key,預設None,表示所有的key
count每次分片最少獲取個數,預設None表示採用redis預設分片個數
hscan_iter(name, match=None, count=None)
#利用yield封裝hscan建立生成器,實現分批去redis中獲取資料,引數:
match匹配指定key,預設Nnoe,表示所有的key
count每次分片最少獲取個數,預設None表示採用redis的預設分片個數
例項:for item in r.hscan_iter('xx'):
print item
# 區分hgetall和hscan_iter
List(列表)操作
#List在記憶體中按照一個name對應一個List來儲存,看圖1
#加*表示重點
lpush(name,values)*
#在name對應的list中新增元素,每個新的元素都新增到列表的最左邊,如:
r.lpush('oo', 11,22,33)
結果為: 33,22,11
# 擴充套件:
rpush(name, values) 表示從右向左操作
lpushx(name,value)
#在name對應的list中新增元素,只有name存在時,值新增到list最左邊
擴充套件:rpushx(name, value) 表示從右向左操作
llen(name)*
#name對應的list元素的個數
linsert(name, where, refvalue, value))
#在name對應的list的某一個值前面或後面插入一個值,引數:
where可以式BEFORE或AFTER(小寫也可以)
refvalue標杆值,在它前後插入資料,如果存在多個標杆值,以找到的第一個為準
value要插入的值
r.lset(name, index, value)
#對name對應的list的某一個索引位置重新賦值,引數:
index指需要重新賦值的索引位置
value要設定的值
r.lrem(name, value, num)
#在name對應的list中刪除指定的值,引數:
value要刪除的值
num:
num=0表示刪除該list中所有指定值
num=2表示從前到後刪除兩個
num=-2表示從後到前刪除兩個
lpop(name)*
#在name對應的list左側獲取第一個元素並在list中移除,返回值則是該元素
擴充套件:rpop(name) 表示從右向左操作
lindex(name, index)
#在name對應的list中根據索引獲取list元素
lrange(name, start, end)*
#在name對應的list分片獲取資料,引數:
start開始的索引位置
end結束的索引位置
ltrim(name, start, end)
#在name對應的list中移除沒有在start-end索引之間的值,引數:
start開始的索引位置
end結束的索引位置
rpoplpush(src, dst)
#從一個列表取出最右邊的元素,提示新增到另一個list的最左邊,引數:
src要獲取資料的list的name
dst要新增資料的list的name
blpop(keys, timeout)*
#將多個list排列,按照從左到右去pop對應list的元素,引數:
keys是個集合,要pop元素的集合
timeout超時時間,當元素所有list的元素獲取玩之後,阻塞等待list內資料局的時間秒,0表示醫院阻塞,
擴充套件:r.brpop(keys, timeout),從右向左獲取資料,應用場景:爬蟲實現簡單分散式:多個url放到列表裡,往裡不停放URL,程式迴圈取值,但是隻能一臺機器執行取值,可以把url放到redis中,多臺機器從redis中取值,爬取資料,實現簡單分散式
brpoplpush(src, dst, timeout=0)
#從一個列表的右側移除一個元素,並將其新增到另一個list的左側,引數:
src取出並要移除元素的list的name
dst要插入元素的list的name
timeout當src對應的list中沒有資料時,阻塞等待其有資料的超時時間秒,0表示醫院阻塞
自定義增量迭代
# 由於redis類庫中沒有提供對列表元素的增量迭代,如果想要迴圈name對應的列表的所有元素,那麼就需要:
# 1、獲取name對應的所有列表
# 2、迴圈列表
# 但是,如果列表非常大,那麼就有可能在第一步時就將程式的內容撐爆,所有有必要自定義一個增量迭代的功能:
import redis
conn=redis.Redis(host='127.0.0.1',port=6379)
# conn.lpush('test',*[1,2,3,4,45,5,6,7,7,8,43,5,6,768,89,9,65,4,23,54,6757,8,68])
# conn.flushall()
def scan_list(name,count=2):
index=0
while True:
data_list=conn.lrange(name,index,count+index-1)
if not data_list:
return
index+=count
for item in data_list:
yield item
print(conn.lrange('test',0,100))
for item in scan_list('test',5):
print('---')
print(item)
Set(集合)操作
其他操作
delete(*names)
#刪除redis中任意資料型別
exists(name)
#檢查redis的name是否存在
keys(pattern='*')
#根據模型獲取redis的name,其他引數:
KEYS * 匹配資料庫中所有 key 。
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
KEYS h*llo 匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo 匹配 hello 和 hallo ,不匹配 hillo
expire(name ,time)
#為某個redis的某個name設定超時時間
rename(src, dst)
#對redis的name重新命名
move(name, db)
#將redis的某個值移動到指定的db下
randomkey()
#隨機獲取一個redis的name,不刪除
type(name)
#獲取nmae對應值的型別
scan(cursor=0, match=None, count=None)
scan_iter(match=None, count=None)
#同字串操作,用於增量迭代獲取key
管道
如果想要在一次請求中指定多個命令,則可以使用pipline實現一次請求指定多個命令,並且預設情況下一次pipline 是原子性操作。#redis預設在執行每次請求都會建立(連線申請連線池)和斷開(歸還連線池)一次性操作,如果想要在一次請求中指定多個命令,則可以使用pipline實現一次請求指定多個命令,並且預設情況下一次pipline 是原子性操作(要麼全部成功,要麼全部失敗)。
#test.py
import redis
pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
r = redis.Redis(connection_pool=pool)
# pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True)
pipe.multi()
pipe.set('name', 'alex')
pipe.set('role', 'sb')
pipe.execute()
Django使用Redis
#方式一,通用方式
#utils\redis_pool.py
import redis
#POOL連線池,max_connections=100指最大連線數是100
POOL = redis.ConnectionPool(host='127.0.0.1',port=6379,max_connections=100)
#app01\views.py
import redis
from utils.redis_pool import POOL
from django.shortcuts import render, HttpResponse
def index(request):
conn = redis.Redis(connection_pool=POOL)
conn.set('hobby','sleep')
return HttpResponse('設定成功')
def order(request):
conn = redis.Redis(connection_pool=POOL)
ret = conn.get('hobby')
print(ret)
return HttpResponse('獲取成功')
#方式二,安裝django-redis模組
pip install django-redis
#settings.py配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
# "PASSWORD": "123",
}
}
}
#views.py
from django_redis import get_redis_connection
conn = get_redis_connection('default')
print(conn.hgetall('xxx'))
介面快取
#luffyapi\apps\home\views.py,BannerView類內
def banner_list(self,request,*args,**kwargs):
banner_list = cache.get('banner_list')
if not banner_list:
#快取沒有去資料拿
response = super().list(request,*args,**kwargs)
#加到快取
cache.set('banner_list',response.data,60*60*24)#banner_list一天過期
return Response(data=banner_list)