十行代碼將Redis緩存數據進行分頁提取與展示

預覽

在這裏插入圖片描述

準備數據

從以前的項目中提取一些數據直接導入MySQL,原先數據庫爲sqlite3,先將數據轉爲xls文件格式。
在這裏插入圖片描述
然後使用MySQL可視化工具Navicat for MySQL新建一個數據庫,新建一張表,表數據格式與xls格式一致,然後選擇導入嚮導。
在這裏插入圖片描述
在這裏插入圖片描述
至此數據導入完成,開始嘗試將MySQL數據加入Redis緩存。

Redis操作

先開啓Redis服務
在這裏插入圖片描述
Redis包含五大數據格式,基本能完成大部分所需,本地配置也不需要怎麼配置,直接下載安裝就可運行。

import redis,time
#redis連接
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)

# String 字符串
# data=find_data()[::-1]
# for i in range(len(data)): 
#     r.set("dict:chushou:%s"%str(i), str(data[i]))    # key是"food" value是"mutton" 將鍵值對存入redis緩存
#     print(str(i)+"ok")

# import ast
# 將字符串轉爲字典
# 將數據長度放入緩存
# r.set("dict:length",len(data))
# print(r.get("dict:length"))
# for i in range(int(r.get("dict:length"))):
#     a=r.get("dict:chushou:%s"%str(i))
#     a=ast.literal_eval(a)
#     print(a['fruitname'])
#     break

# r.set("visit:12306:totals", 1)
# print(r.get("visit:12306:totals"))
# for i in range(0,10):
# #     自增
#     r.incr("visit:12306:totals")
# print(r.get("visit:12306:totals"))

# time.sleep(2)
# print(r.get('food'))
# '''
# 參數:
# set(name, value, ex=None, px=None, nx=False, xx=False)
# ex,過期時間(秒)
# px,過期時間(毫秒)
# nx,如果設置爲True,則只有name不存在時,當前set操作才執行,同setnx(name, value)
# xx,如果設置爲True,則只有name存在時,當前set操作才執行
# '''

#hash 哈希
# r.hset("hash1", "k1", "v1")
# r.hset("hash1", "k2", "v2")
# print(r.hkeys("hash1")) # 取hash中所有的key
# print(r.hget("hash1", "k1"))    # 單個取hash的key對應的值
# print(r.hmget("hash1", "k1", "k2")) # 多個取hash的key對應的值
# r.hsetnx("hash1", "k2", "v3") # 只能新建
# print(r.hget("hash1", "k2"))

# list  列表
# def fenye(start,end):
#     print(r.lrange('list:chushou',start,end))
# # data=find_data()[::-1]
# # for i in range(len(data)): 
# #     r.lpush("list:chushou",str(data[i]))
# # r.expire("list:chushou", 2);#設置過期時間爲2秒 
# # fenye(0,3)
# # time.sleep(3)
# # fenye(0,3)
# print(r.llen("list:chushou"))  # 列表長度

# fenye(0,1)
# fenye(6,11)
# r.rpush("list2", 11, 22, 33)  # 表示從右向左操作
# print(r.llen("list2"))  # 列表長度
# print(r.lrange("list2", 0, -1))  # 切片取出值,範圍是索引號0-3

# Blpop 命令移出並獲取列表的第一個元素 左移除   右移除 brpop
# print(r.blpop("list2"))


# set  集合
# r.sadd("set1", 33, 44, 55, 66)  # 往集合中添加元素
# print(r.scard("set1"))  # 集合的長度是4
# print(list(r.smembers("set1")))   # 獲取集合中所有的成員


#sortset
# Set操作,Set集合就是不允許重複的列表,本身是無序的。
# 有序集合,在集合的基礎上,爲每元素排序;元素的排序需要根據另外一個值來進行比較,
# 所以,對於有序集合,每一個元素有兩個值,即:值和分數,分數專門用來做排序。
# r.zadd("zset1", n1=11, n2=22)
# r.zadd("zset2", 'm1', 22, 'm2', 44)
# print(r.zcard("zset1")) # 集合長度
# print(r.zcard("zset2")) # 集合長度
# print(r.zrange("zset1", 0, -1))   # 獲取有序集合中所有元素
# print(r.zrange("zset2", 0, -1, withscores=True))   # 獲取有序集合中所有元素和分數

因爲Redis自帶的list有個很好的分頁函數,lrange(‘list:chushou’,start,end),第一個參數是數據的key,第二個是數據開始,第三個參數是數據結尾。比如我們就可以定義以下格式進行分頁提取:

#page是第幾頁
#page_num是每頁幾個數據
#然後這裏end我減去一個元素,因爲Redis默認是右包括的,意思是(0,10)就是十一個數據,那麼下一頁數據(10,20),也包含了10的數據,返回的數據就重複了第10的數據,所以我們把最後一個數據去掉,變成(0,9),(10,19)。
start=page*page_num-page_num
end=page*page_num-1

然後我們這邊定義數據緩存時間爲120秒,也就是2分鐘,2分鐘後數據清除,如果不設置的話,長期下來數據緩存將會是一個很大的數量,當然Redis好像可以配置自動清除數據,當緩存達到上限時。

r.expire("list:chushou", 120);#設置過期時間爲120秒 

MySQL提取數據

這裏沒什麼好說的,pymysql連接數據庫執行sql查找全部數據並返回。

import pymysql
#數據庫配置
DB_CONFIG = {
        'host': '127.0.0.1',
        'port': 3306,
        'user': 'root',
        'password': '123cxk...',
        'db': 'poem',
        'charset': 'utf8',
        'cursorclass': pymysql.cursors.DictCursor
}
#查詢
def find_data():
    #連接數據庫
    db = pymysql.connect(**DB_CONFIG)
    #使用cursor()方法創建一個遊標對象
    cursor = db.cursor()
    sql = "SELECT * FROM tang_poem_info"
    #使用execute()方法執行SQL語句
    cursor.execute(sql)
    #使用fetall()獲取全部數據
    res = cursor.fetchall()
    cursor.close()
    db.close()
    return res

總體代碼

連接數據庫提取數據加入Redis緩存

import pymysql
#數據庫配置
DB_CONFIG = {
        'host': '127.0.0.1',
        'port': 3306,
        'user': 'root',
        'password': '123cxk...',
        'db': 'poem',
        'charset': 'utf8',
        'cursorclass': pymysql.cursors.DictCursor
}
#查詢
def find_data():
    #連接數據庫
    db = pymysql.connect(**DB_CONFIG)
    #使用cursor()方法創建一個遊標對象
    cursor = db.cursor()
    sql = "SELECT * FROM tang_poem_info"
    #使用execute()方法執行SQL語句
    cursor.execute(sql)
    #使用fetall()獲取全部數據
    res = cursor.fetchall()
    cursor.close()
    db.close()
    return res

import redis,ast
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
r = redis.Redis(connection_pool=pool)
# list  列表
def fenye(page,page_num):
    poems=[]
    #包含,後面結尾我們少一條數據
    start=page*page_num-page_num
    end=page*page_num-1
    for i in r.lrange('list:tang_poem',start,end):
    	#因爲Redis加入list默認是字符串格式,我們對提取的數據進行轉字典處理
        a=ast.literal_eval(i)
        poems.append(a)
    #返回數據列表,緩存數據大小
    return poems,r.llen("list:tang_poem")
def write_Redis():
    data=find_data()[::-1]
    # print(len(data)) #23909
    for i in range(0,len(data)):
        r.lpush("list:tang_poem",str(data[i]))
    r.expire("list:tang_poem", 120);#設置過期時間爲120秒

查看數據

在這裏插入圖片描述

flask

from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
    page=1
    page_num=10
    poems=fenye(page,page_num)[0]
    #檢查緩存是否爲空,如果爲空,從數據庫寫入Redis
    if poems==[]:
        write_Redis()
    poems = fenye(page, page_num)[0]
    poems_len=int(fenye(page,page_num)[1]/10)
    context={
        'poems':poems
    }
    return render_template('fenye.html',**context,poems_len=poems_len,page=page)

@app.route('/<int:page>/')
def page(page):
    page=page
    page_num=10
    poems=fenye(page,page_num)[0]
    poems_len=int(fenye(page,page_num)[1]/10)
    context={
        'poems':poems
    }
    return render_template('fenye.html',**context,poems_len=poems_len,page=page)

if __name__ == '__main__':
    app.run(debug=True)

HTML

fenye.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>唐詩大全</title>
</head>
<body>
<table align="center" border="1" cellspacing="0">
    <thead align="center">
    <tr>
        <th>序號</th>
        <th>詩名</th>
        <th>作者</th>
        <th>聲調</th>
        <th>詩句</th>
    </tr>
    </thead>
    <tbody align="center">
    {% for poem in poems %}
    <tr>
        <td>{{ poem.id }}</td>
        <td>{{ poem.poemname }}</td>
        <td>{{ poem.author }}</td>
        <td>{{ poem.strains }}</td>
        <td>{{ poem.paragraphs }}</td>
    </tr>
    {% endfor %}
    </tbody>
</table>
<p align="center">
    <input type="button" value="上一頁" onclick='location.href=("/{{page-1}}/")'/>
    {{page}}/{{poems_len}}頁
    <input type="button" value="下一頁" onclick='location.href=("/{{page+1}}/")'/>
</p>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章