今日內(nèi)容
redis
1. 概念
2. 下載安裝
3. 命令操作
1. 數(shù)據(jù)結(jié)構(gòu)
4. 持久化操作
5. 使用Java客戶端操作redis
6. 在ssm項(xiàng)目中使用緩沖進(jìn)行CRUD操作
Redis
1. 概念
redis是一款高性能的NOSQL系列的非關(guān)系型數(shù)據(jù)庫(kù)
1.1.什么是NOSQL
? NoSQL(NoSQL = Not Only SQL),意即“不僅僅是SQL”,是一項(xiàng)全新的數(shù)據(jù)庫(kù)理念,泛指非關(guān)系型的數(shù)據(jù)庫(kù)。
? 隨著互聯(lián)網(wǎng)web2.0網(wǎng)站的興起,傳統(tǒng)的關(guān)系數(shù)據(jù)庫(kù)在應(yīng)付web2.0網(wǎng)站,特別是超大規(guī)模和高并發(fā)的SNS類型的web2.0純動(dòng)態(tài)網(wǎng)站已經(jīng)顯得力不從心,暴露了很多難以克服的問(wèn)題,而非關(guān)系型的數(shù)據(jù)庫(kù)則由于其本身的特點(diǎn)得到了非常迅速的發(fā)展。
NoSQL數(shù)據(jù)庫(kù)的產(chǎn)生就是為了解決大規(guī)模數(shù)據(jù)集合多重?cái)?shù)據(jù)種類帶來(lái)的挑戰(zhàn),尤其是大數(shù)據(jù)應(yīng)用難題。
1.1.1.NOSQL數(shù)據(jù)庫(kù)和關(guān)系型數(shù)據(jù)庫(kù)比較
? 優(yōu)點(diǎn):
? 1)成本:nosql數(shù)據(jù)庫(kù)簡(jiǎn)單易部署,基本都是開源軟件,不需要像使用oracle那樣花費(fèi)大量成本購(gòu)買使用,相比關(guān)系型數(shù)據(jù)庫(kù)價(jià)格便宜。
? 2)查詢速度:nosql數(shù)據(jù)庫(kù)將數(shù)據(jù)存儲(chǔ)于緩存之中,關(guān)系型數(shù)據(jù)庫(kù)將數(shù)據(jù)存儲(chǔ)在硬盤中,自然查詢速度遠(yuǎn)不及nosql數(shù)據(jù)庫(kù)。
? 3)存儲(chǔ)數(shù)據(jù)的格式:nosql的存儲(chǔ)格式是key,value形式、文檔形式、圖片形式等等,所以可以存儲(chǔ)基礎(chǔ)類型以及對(duì)象或者是集合等各種格式,而關(guān)系型數(shù)據(jù)庫(kù)則只支持基礎(chǔ)類型。
? 4)擴(kuò)展性:關(guān)系型數(shù)據(jù)庫(kù)有類似join這樣的多表查詢機(jī)制的限制導(dǎo)致擴(kuò)展很艱難。
? 缺點(diǎn):
? 1)維護(hù)的工具和資料有限,因?yàn)閚osql是屬于新的技術(shù),不能和關(guān)系型數(shù)據(jù)庫(kù)10幾年的技術(shù)同日而語(yǔ)。
? 2)不提供對(duì)sql的支持,如果不支持sql這樣的工業(yè)標(biāo)準(zhǔn),用戶將產(chǎn)生一定的學(xué)習(xí)和使用成本。
? 3)不提供關(guān)系型數(shù)據(jù)庫(kù)對(duì)事務(wù)的處理。
1.1.2.非關(guān)系型數(shù)據(jù)庫(kù)的優(yōu)勢(shì)
? 1)性能 NOSQL是基于鍵值對(duì)的,可以想象成表中的主鍵和值的對(duì)應(yīng)關(guān)系,而且不需要經(jīng)過(guò)SQL層的解析,所以性能非常高。
? 2)可擴(kuò)展性 同樣也是因?yàn)榛阪I值對(duì),數(shù)據(jù)之間沒(méi)有耦合性,所以非常容易水平擴(kuò)展。
1.1.3.關(guān)系型數(shù)據(jù)庫(kù)的優(yōu)勢(shì)
? 1)復(fù)雜查詢 可以用SQL語(yǔ)句方便的在一個(gè)表以及多個(gè)表之間做非常復(fù)雜的數(shù)據(jù)查詢。
? 2)事務(wù)支持 使得對(duì)于安全性能很高的數(shù)據(jù)訪問(wèn)要求得以實(shí)現(xiàn)。對(duì)于這兩類數(shù)據(jù)庫(kù),對(duì)方的優(yōu)勢(shì)就是自己的弱勢(shì),反之亦然。
1.1.4.總結(jié)
? 關(guān)系型數(shù)據(jù)庫(kù)與NoSQL數(shù)據(jù)庫(kù)并非對(duì)立而是互補(bǔ)的關(guān)系,即通常情況下使用關(guān)系型數(shù)據(jù)庫(kù),在適合使用NoSQL的時(shí)候使用NoSQL數(shù)據(jù)庫(kù),
? 讓NoSQL數(shù)據(jù)庫(kù)對(duì)關(guān)系型數(shù)據(jù)庫(kù)的不足進(jìn)行彌補(bǔ)。
? 一般會(huì)將數(shù)據(jù)存儲(chǔ)在關(guān)系型數(shù)據(jù)庫(kù)中,在nosql數(shù)據(jù)庫(kù)中備份存儲(chǔ)關(guān)系型數(shù)據(jù)庫(kù)的數(shù)據(jù)
1.2.主流的NOSQL產(chǎn)品
? ? 鍵值(Key-Value)存儲(chǔ)數(shù)據(jù)庫(kù)
? 相關(guān)產(chǎn)品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
? 典型應(yīng)用: 內(nèi)容緩存,主要用于處理大量數(shù)據(jù)的高訪問(wèn)負(fù)載。
? 數(shù)據(jù)模型: 一系列鍵值對(duì)
? 優(yōu)勢(shì): 快速查詢
? 劣勢(shì): 存儲(chǔ)的數(shù)據(jù)缺少結(jié)構(gòu)化
? ? 列存儲(chǔ)數(shù)據(jù)庫(kù)
? 相關(guān)產(chǎn)品:Cassandra, HBase, Riak
? 典型應(yīng)用:分布式的文件系統(tǒng)
? 數(shù)據(jù)模型:以列簇式存儲(chǔ),將同一列數(shù)據(jù)存在一起
? 優(yōu)勢(shì):查找速度快,可擴(kuò)展性強(qiáng),更容易進(jìn)行分布式擴(kuò)展
? 劣勢(shì):功能相對(duì)局限
? ? 文檔型數(shù)據(jù)庫(kù)
? 相關(guān)產(chǎn)品:CouchDB、MongoDB
? 典型應(yīng)用:Web應(yīng)用(與Key-Value類似,Value是結(jié)構(gòu)化的)
? 數(shù)據(jù)模型: 一系列鍵值對(duì)
? 優(yōu)勢(shì):數(shù)據(jù)結(jié)構(gòu)要求不嚴(yán)格
? 劣勢(shì): 查詢性能不高,而且缺乏統(tǒng)一的查詢語(yǔ)法
? ? 圖形(Graph)數(shù)據(jù)庫(kù)
? 相關(guān)數(shù)據(jù)庫(kù):Neo4J、InfoGrid、Infinite Graph
? 典型應(yīng)用:社交網(wǎng)絡(luò)
? 數(shù)據(jù)模型:圖結(jié)構(gòu)
? 優(yōu)勢(shì):利用圖結(jié)構(gòu)相關(guān)算法。
? 劣勢(shì):需要對(duì)整個(gè)圖做計(jì)算才能得出結(jié)果,不容易做分布式的集群方案。
1.3 什么是Redis
? Redis是用C語(yǔ)言開發(fā)的一個(gè)開源的高性能鍵值對(duì)(key-value)數(shù)據(jù)庫(kù),官方提供測(cè)試數(shù)據(jù),50個(gè)并發(fā)執(zhí)行100000個(gè)請(qǐng)求,讀的速度是110000次/s,寫的速度是81000次/s ,且Redis通過(guò)提供多種鍵值數(shù)據(jù)類型來(lái)適應(yīng)不同場(chǎng)景下的存儲(chǔ)需求,目前為止Redis支持的鍵值數(shù)據(jù)類型如下:
- 字符串類型 string
- 哈希類型 hash
- 列表類型 list
- 集合類型 set
- 有序集合類型 sortedset
1.3.1 redis的應(yīng)用場(chǎng)景
緩存(數(shù)據(jù)查詢、短連接、新聞內(nèi)容、商品內(nèi)容等等)
聊天室的在線好友列表
任務(wù)隊(duì)列。(秒殺、搶購(gòu)、12306等等)
應(yīng)用排行榜
網(wǎng)站訪問(wèn)統(tǒng)計(jì)
數(shù)據(jù)過(guò)期處理(可以精確到毫秒
分布式集群架構(gòu)中的session分離
2. 下載安裝
- 官網(wǎng):https://redis.io
- 中文網(wǎng):http://www.redis.net.cn/
- 解壓直接可以使用:
- redis.windows.conf:配置文件
- redis-cli.exe:redis的客戶端
- redis-server.exe:redis服務(wù)器端
** 設(shè)置Redis服務(wù)
1、由于上面雖然啟動(dòng)了redis,但是只要一關(guān)閉cmd窗口,redis就會(huì)消失。所以要把redis設(shè)置成windows下的服務(wù)。
2、設(shè)置服務(wù)命令
? 在radis軟件目錄下F:\Program Files (x86)\Redis-x64-3.2.100 cmd調(diào)出命令窗口輸入下列代碼,添加服務(wù)
? redis-server --service-install redis.windows.conf --loglevel verbose
? 3、常用的redis服務(wù)命令。
? 卸載服務(wù):redis-server --service-uninstall
? 開啟服務(wù):redis-server --service-start
? 停止服務(wù):redis-server --service-stop
3. 命令操作
-
redis的數(shù)據(jù)結(jié)構(gòu):
-
redis存儲(chǔ)的是:key,value格式的數(shù)據(jù),其中key都是字符串,value有5種不同的數(shù)據(jù)結(jié)構(gòu)
- value的數(shù)據(jù)結(jié)構(gòu):
- 字符串類型 string
- 哈希類型 hash : map格式
- 列表類型 list : linkedlist格式。支持重復(fù)元素
- 集合類型 set : 不允許重復(fù)元素
-
有序集合類型 sortedset:不允許重復(fù)元素,且元素有順序
1.字符串類型String set key value get key del key 2.哈希類型hash 類似于java中的map集合 hset key field value hget key field hdel key field 3.列表類型list 可重復(fù) 有序 lpush key value rpush key value lrange key start end lpop key rpop key 4.集合類型set 不可重復(fù),無(wú)序 sadd key value smembers key srem key value 5.有序集合類型sortedset/zset 不可重復(fù),有序 zadd key score value zrange key start end [withscores] zrem key value 6.通用命令 keys * : 查詢所有的鍵 type key : 獲取鍵對(duì)應(yīng)的value的類型 del key:刪除指定的key value
- value的數(shù)據(jù)結(jié)構(gòu):
-
-
字符串類型 string
-
存儲(chǔ): set key value
127.0.0.1:6379> set username zhangsan
OK -
獲取: get key
127.0.0.1:6379> get username
“zhangsan” -
刪除: del key
127.0.0.1:6379> del age
(integer) 1
-
存儲(chǔ): set key value
-
哈希類型 hash
-
存儲(chǔ): hset key field value
127.0.0.1:6379> hset myhash username lisi
(integer) 1
127.0.0.1:6379> hset myhash password 123
(integer) 1 -
獲取:
- hget key field: 獲取指定的field對(duì)應(yīng)的值
127.0.0.1:6379> hget myhash username
“l(fā)isi” - hgetall key:獲取所有的field和value
127.0.0.1:6379> hgetall myhash- “username”
- “l(fā)isi”
- “password”
- “123”
- hget key field: 獲取指定的field對(duì)應(yīng)的值
-
刪除: hdel key field
127.0.0.1:6379> hdel myhash username
(integer) 1
-
-
列表類型 list:可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊)
-
添加:
-
lpush key value: 將元素加入列表左邊
-
rpush key value:將元素加入列表右邊
127.0.0.1:6379> lpush myList a
(integer) 1
127.0.0.1:6379> lpush myList b
(integer) 2
127.0.0.1:6379> rpush myList c
(integer) 3
-
-
獲取:
- lrange key start end :范圍獲取
127.0.0.1:6379> lrange myList 0 -1- “b”
- “a”
- “c”
- lrange key start end :范圍獲取
-
-
刪除:
- lpop key: 刪除列表最左邊的元素,并將元素返回
- rpop key: 刪除列表最右邊的元素,并將元素返回
-
集合類型 set : 不允許重復(fù)元素
-
存儲(chǔ):sadd key value
127.0.0.1:6379> sadd myset a
(integer) 1
127.0.0.1:6379> sadd myset a
(integer) 0-
獲取:smembers key:獲取set集合中所有元素
127.0.0.1:6379> smembers myset- “a”
-
刪除:srem key value:刪除set集合中的某個(gè)元素
127.0.0.1:6379> srem myset a
(integer) 1
-
獲取:smembers key:獲取set集合中所有元素
-
有序集合類型 sortedset/zset:
不允許重復(fù)元素,且元素有順序.每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù)。redis正是通過(guò)分?jǐn)?shù)來(lái)為集合中的成員進(jìn)行從小到大的排序。
-
存儲(chǔ):zadd key score value
127.0.0.1:6379> zadd mysort 60 zhangsan
(integer) 1
127.0.0.1:6379> zadd mysort 50 lisi
(integer) 1
127.0.0.1:6379> zadd mysort 80 wangwu
(integer) 1
2. **獲取**:zrange key start end [withscores] 127.0.0.1:6379> zrange mysort 0 -1 1) "lisi" 2) "zhangsan" 3) "wangwu" 127.0.0.1:6379> zrange mysort 0 -1 withscores 1) "zhangsan" 2) "60" 3) "wangwu" 4) "80" 5) "lisi" 6) "500" 3. **刪除**:zrem key value 127.0.0.1:6379> zrem mysort lisi (integer) 1
-
通用命令
- keys * : 查詢所有的鍵
- type key : 獲取鍵對(duì)應(yīng)的value的類型
- del key:刪除指定的key value
-
設(shè)置過(guò)期時(shí)間Redis Setex
將值 value 關(guān)聯(lián)到 key ,并將 key 的過(guò)期時(shí)間設(shè)為 seconds (以秒為單位)。
Redis Setex 命令為指定的 key 設(shè)置值及其過(guò)期時(shí)間。如果 key 已經(jīng)存在, SETEX 命令將會(huì)替換舊的值。
語(yǔ)法
redis Setex 命令基本語(yǔ)法如下:
redis 127.0.0.1:6379> SETEX KEY_NAME TIMEOUT VALUE
舉例:
redis 127.0.0.1:6379> SETEX mykey 60 redis
OK
redis 127.0.0.1:6379> TTL mykey
60
redis 127.0.0.1:6379> GET mykey
"redis
4. 持久化
-
redis是一個(gè)內(nèi)存數(shù)據(jù)庫(kù),當(dāng)redis服務(wù)器重啟,獲者電腦重啟,數(shù)據(jù)會(huì)丟失,我們可以將redis內(nèi)存中的數(shù)據(jù)持久化保存到硬盤的文件中。
-
redis持久化機(jī)制:
-
RDB:默認(rèn)方式,不需要進(jìn)行配置,默認(rèn)就使用這種機(jī)制
- 在一定的間隔時(shí)間中,檢測(cè)key的變化情況,然后持久化數(shù)據(jù)
-
編輯redis.windwos.conf文件
# after 900 sec (15 min) if at least 1 key changed
save 900 1
# after 300 sec (5 min) if at least 10 keys changed
save 300 10
# after 60 sec if at least 10000 keys changed
save 60 10000
-
重新啟動(dòng)redis服務(wù)器,并指定配置文件名稱
D:\Java\redis\資料\redis\windows-64\redis-2.8.9>redis-server.exe redis.windows.conf
-
AOF:日志記錄的方式,可以記錄每一條命令的操作??梢悦恳淮蚊畈僮骱?,持久化數(shù)據(jù)
-
編輯redis.windows.conf文件
appendonly no(關(guān)閉aof) --> appendonly yes (開啟aof)# appendfsync always : 每一次操作都進(jìn)行持久化
appendfsync everysec : 每隔一秒進(jìn)行一次持久化
# appendfsync no : 不進(jìn)行持久化
-
-
5. Java客戶端 Jedis
-
Jedis: 一款java操作redis數(shù)據(jù)庫(kù)的工具.
-
使用步驟:
-
下載jedis的jar包
用到j(luò)unit+jedis
https://mvnrepository.com/ ,可以通過(guò)這個(gè)網(wǎng)站找jar包依賴。
-
使用
//1. 獲取連接 Jedis jedis = new Jedis("localhost",6379); //2. 操作 jedis.set("username","zhangsan"); //3. 關(guān)閉連接 jedis.close();
-
Jedis操作各種redis中的數(shù)據(jù)結(jié)構(gòu)
① 字符串類型 string
set get
// 1. 獲取連接 Jedis jedis = new Jedis();//如果使用空參構(gòu)造,默認(rèn)值 "localhost",6379端口 // 2. 操作 // 存儲(chǔ) jedis.set("username","zhangsan"); // 獲取 String username = jedis.get("username"); System.out.println(username); // 可以使用setex()方法存儲(chǔ)可以指定過(guò)期時(shí)間的 key value jedis.setex("activecode",20,"hehe"); // 將activecode:hehe鍵值對(duì)存入redis,并且20秒后自動(dòng)刪除該鍵值對(duì) //3. 關(guān)閉連接 jedis.close();
② 哈希類型 hash : map格式
hset
hget
hgetAll// 1. 獲取連接 Jedis jedis = new Jedis(); // 如果使用空參構(gòu)造,默認(rèn)值 "localhost",6379端口 // 2. 操作 // 存儲(chǔ)hash jedis.hset("user","name","lisi"); jedis.hset("user","age","23"); jedis.hset("user","gender","female"); // 獲取hash String name = jedis.hget("user", "name"); System.out.println(name); // 獲取hash的所有map中的數(shù)據(jù) Map<String, String> user = jedis.hgetAll("user"); // keyset Set<String> keySet = user.keySet(); for (String key : keySet) { //獲取value String value = user.get(key); System.out.println(key + ":" + value); } //3. 關(guān)閉連接 jedis.close();
③ 列表類型 list : linkedlist格式。支持重復(fù)元素
lpush / rpush
lpop / rpop
lrange start end : 范圍獲取// 1. 獲取連接 Jedis jedis = new Jedis();//如果使用空參構(gòu)造,默認(rèn)值 "localhost",6379端口 // 2. 操作 // list 存儲(chǔ) jedis.lpush("mylist","a","b","c");//從左邊存 jedis.rpush("mylist","a","b","c");//從右邊存 // list 范圍獲取 List<String> mylist = jedis.lrange("mylist", 0, -1); System.out.println(mylist); // list 彈出 String element1 = jedis.lpop("mylist");//c System.out.println(element1); String element2 = jedis.rpop("mylist");//c System.out.println(element2); // list 范圍獲取 List<String> mylist2 = jedis.lrange("mylist", 0, -1); System.out.println(mylist2); // 3. 關(guān)閉連接 jedis.close();
④ 集合類型 set : 不允許重復(fù)元素
sadd
smembers: 獲取所有元素// 1. 獲取連接 Jedis jedis = new Jedis();//如果使用空參構(gòu)造,默認(rèn)值 "localhost",6379端口 // 2. 操作 // set 存儲(chǔ) jedis.sadd("myset","java","php","c++"); // set 獲取 Set<String> myset = jedis.smembers("myset"); System.out.println(myset); //3. 關(guān)閉連接 jedis.close();
⑤ 有序集合類型 sortedset:不允許重復(fù)元素,且元素有順序
zadd
zrange// 1. 獲取連接 Jedis jedis = new Jedis();//如果使用空參構(gòu)造,默認(rèn)值 "localhost",6379端口 // 2. 操作 // sortedset 存儲(chǔ) jedis.zadd("mysortedset",3,"亞瑟"); jedis.zadd("mysortedset",30,"后裔"); jedis.zadd("mysortedset",55,"孫悟空"); // sortedset 獲取 Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1); System.out.println(mysortedset); // 3. 關(guān)閉連接 jedis.close();
-
jedis連接池: JedisPool
使用:
- 創(chuàng)建JedisPool連接池對(duì)象
- 調(diào)用方法 getResource()方法獲取Jedis連接
// 0.創(chuàng)建一個(gè)配置對(duì)象 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(50); config.setMaxIdle(10); // 1.創(chuàng)建Jedis連接池對(duì)象 JedisPool jedisPool = new JedisPool(config,"localhost",6379); // 2.獲取連接 Jedis jedis = jedisPool.getResource(); // 3. 使用 jedis.set("hehe","heihei"); // 4. 關(guān)閉 歸還到連接池中 jedis.close();
-
連接池工具類
public class JedisPoolUtils { private static JedisPool jedisPool; static{ //讀取配置文件 InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties"); //創(chuàng)建Properties對(duì)象 Properties pro = new Properties(); //關(guān)聯(lián)文件 try { pro.load(is); } catch (IOException e) { e.printStackTrace(); } //獲取數(shù)據(jù),設(shè)置到JedisPoolConfig中 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal"))); config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle"))); //初始化JedisPool jedisPool = new JedisPool(config, pro.getProperty("host"), Integer.parseInt(pro.getProperty("port"))); } /** * 獲取連接方法 */ public static Jedis getJedis(){ return jedisPool.getResource(); } }
-
6. 案例
案例需求:
1. 提供index.html頁(yè)面,頁(yè)面中有一個(gè)省份的下拉列表
2. 當(dāng) 頁(yè)面加載完成后 發(fā)送ajax請(qǐng)求,加載所有省份
* 注意:使用redis緩存一些不經(jīng)常發(fā)生變化的數(shù)據(jù)。
* 數(shù)據(jù)庫(kù)的數(shù)據(jù)一旦發(fā)生改變,則需要更新緩存。
* 數(shù)據(jù)庫(kù)的表執(zhí)行 增刪改的相關(guān)操作,需要將redis緩存數(shù)據(jù)清空,再次存入
* 在service對(duì)應(yīng)的增刪改方法中,將redis數(shù)據(jù)刪除。
?
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="js/jquery-3.3.1.min.js"></script>
<!--頁(yè)面加載完成后 發(fā)送ajax請(qǐng)求,加載所有省份-->
<script>
$(function () {
// 發(fā)送ajax請(qǐng)求
$.get("provinceServlet",function (data) {
// [{"id":1,"name":"北京"},{"id":2,"name":"上海"},{"id":3,"name":"廣東"},{"id":4,"name":"廣西"}]
// 獲取下拉列表
var province = $("#province");
// 遍歷Json數(shù)據(jù)
$(data).each(function () {
// 創(chuàng)建option元素
var option = "<option name='"+ this.id +"'>"+ this.name +"</option>";
// 將option元素追加到select中
province.append(option);
});
});
});
</script>
</head>
<body>
<!--下拉列表-->
<select id="province">
<option>--請(qǐng)選擇省份--</option>
</select>
</body>
</html>
ProvinceServlet.java
package cn.yh.redis.web;
import cn.yh.redis.pojo.Province;
import cn.yh.redis.service.ProvinceService;
import cn.yh.redis.service.impl.ProvinceServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/provinceServlet")
public class ProvinceServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
// 1.調(diào)用service查詢
ProvinceService provinceService = new ProvinceServiceImpl();
List<Province> provinceList = provinceService.findAll();
// 2.將數(shù)據(jù)序列化為json
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(provinceList);
// String json = provinceService.findAllJson();
System.out.println(json);
// 3.響應(yīng)數(shù)據(jù)
response.getWriter().write(json);
}
}
ProvinceService.java
package cn.yh.redis.service;
import cn.yh.redis.pojo.Province;
import java.util.List;
public interface ProvinceService {
List<Province> findAll();
String findAllJson();
}
ProvinceServiceImpl.java
package cn.yh.redis.service.impl;
import cn.yh.redis.dao.ProvinceDao;
import cn.yh.redis.dao.impl.ProvinceDaoImpl;
import cn.yh.redis.pojo.Province;
import cn.yh.redis.service.ProvinceService;
import cn.yh.redis.util.JedisPoolUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import redis.clients.jedis.Jedis;
import java.util.List;
public class ProvinceServiceImpl implements ProvinceService {
private final ProvinceDao provinceDao = new ProvinceDaoImpl();
@Override
public List<Province> findAll() {
return provinceDao.findAll();
}
@Override
public String findAllJson() {
// 1.先從緩存中查
Jedis jedis = JedisPoolUtil.getJedis();
String province_json = jedis.get("province");
// 判斷province_json是否為空
if (province_json == null || province_json.length() == 0) {
// 緩存中沒(méi)有數(shù)據(jù)
System.out.println("redis中沒(méi)有數(shù)據(jù),查詢數(shù)據(jù)庫(kù)...");
// 從數(shù)據(jù)庫(kù)查
List<Province> provinceList = provinceDao.findAll();
// 將查到的數(shù)據(jù)序列化為json放入緩存
ObjectMapper objectMapper = new ObjectMapper();
try {
province_json = objectMapper.writeValueAsString(provinceList);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// 存入Redis
jedis.set("province",province_json);
jedis.close();
} else {
System.out.println("redis有數(shù)據(jù),查詢緩存...");
}
return province_json;
}
}
ProvinceDao.java
package cn.yh.redis.dao;
import cn.yh.redis.pojo.Province;
import java.util.List;
public interface ProvinceDao {
List<Province> findAll();
}
ProvinceDaoImpl.java
package cn.yh.redis.dao.impl;
import cn.yh.redis.dao.ProvinceDao;
import cn.yh.redis.pojo.Province;
import cn.yh.redis.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class ProvinceDaoImpl implements ProvinceDao {
// JdbcTemplate
private final JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public List<Province> findAll() {
// 聲明sql
String sql = "select * from province";
// 執(zhí)行
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Province.class));
}
}
JedisPoolUtil.java
package cn.yh.redis.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* JedisPool工具類
* 加載配置文件,配置連接參數(shù)
* 提供獲取連接的方法
*/
public class JedisPoolUtil {
private static final JedisPool jedisPool;
static{
// 讀取配置文件
InputStream in = JedisPoolUtil.class.getClassLoader()
.getResourceAsStream("jedis.properties");
// 創(chuàng)建Properties對(duì)象
Properties props = new Properties();
try {
props.load(in);
} catch (IOException e) {
e.printStackTrace();
}
// 獲取數(shù)據(jù) 設(shè)置到配置對(duì)象
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(props.getProperty("maxTotal")));
config.setMaxTotal(Integer.parseInt(props.getProperty("maxIdle")));
// 初始化連接池對(duì)象
jedisPool = new JedisPool(config,
props.getProperty("host"),
Integer.parseInt(props.getProperty("port")));
}
/**
* 獲取連接
* @return Jedis
*/
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
作業(yè):將案例改為springboot+springmvc+mybatis項(xiàng)目 或 ssm項(xiàng)目文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-666308.html
ssm項(xiàng)目添加緩存
import com.mapper.BookMapper;
import com.pojo.Book;
import com.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookMapper bookMapper;
@Autowired
private RedisTemplate redisTemplate;
@Override
public void insert(Book book) {
bookMapper.insert(book);
//將book類轉(zhuǎn)成json字符串
ObjectMapper mapper = new ObjectMapper();
String bookJson=null;
try {
bookJson = mapper.writeValueAsString(book);
System.out.println(bookJson);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
//在插入數(shù)據(jù)的同時(shí)更新緩存
redisTemplate.boundHashOps("hash_book").put(book.getId(),bookJson);
}
@Override
public void update(Book book) {
bookMapper.updateByPrimaryKey(book);
//將book類轉(zhuǎn)換為json字符串
ObjectMapper mapper = new ObjectMapper();
String bookJson=null;
try {
bookJson = mapper.writeValueAsString(book);
System.out.println(bookJson);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
redisTemplate.boundHashOps("hash_book").delete(book.getId());
redisTemplate.boundHashOps("hash_book").put(book.getId(),bookJson);
}
@Override
public void delete(Integer id) {
bookMapper.deleteByPrimaryKey(id);
//刪除原有緩存重新設(shè)定
redisTemplate.boundHashOps("hash_book").delete(id);
}
@Override
public List<Book> selectAll() {
//先從緩存中查詢
// List bookList = redisTemplate.boundListOps("book").range(0, -1);
List bookList = redisTemplate.boundHashOps("hash_book").values();
if (null!=bookList&&bookList.size()>0){
System.out.println("在緩存中取出");
return bookList;
}else {
//如果沒(méi)有的話就把緩存刪除掉重新放入
redisTemplate.delete("hash_book");
//另一種緩存中沒(méi)有就從數(shù)據(jù)庫(kù)中查 存入緩存中
List<Book> books = bookMapper.selectAll();
//將集合進(jìn)行遍歷得到單個(gè)book對(duì)象 轉(zhuǎn)換為json
ObjectMapper mapper = new ObjectMapper();
for (Book book:books
) {
//將集合轉(zhuǎn)為json并存入緩存中
String Json=null;
try {
Json = mapper.writeValueAsString(book);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
redisTemplate.boundHashOps("hash_book").put(book.getId(),Json);
}
return books;
}
}
}
RedisTemplate設(shè)置過(guò)期時(shí)間
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-666308.html
到了這里,關(guān)于redis基礎(chǔ)細(xì)心講解,一篇了解常用的緩存技術(shù)!的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!