測試聯通
創建Maven工程,引入依賴
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.1.0</version>
</dependency>
package com.lun.shang;
import redis.clients.jedis.Jedis;
public class TestPing {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1",6379);
//輸出PONG,redis連通成功
System.out.println(jedis.ping());
}
}
Jedis_常用API
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import redis.clients.jedis.Jedis;
public class TestAPI {
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
// key
Set<String> keys = jedis.keys("*");
for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
System.out.println(key);
}
System.out.println("jedis.exists====>" + jedis.exists("k2"));
System.out.println(jedis.ttl("k1"));
// String
// jedis.append("k1","myreids");
System.out.println(jedis.get("k1"));
jedis.set("k4", "k4_redis");
System.out.println("----------------------------------------");
jedis.mset("str1", "v1", "str2", "v2", "str3", "v3");
System.out.println(jedis.mget("str1", "str2", "str3"));
// list
System.out.println("----------------------------------------");
// jedis.lpush("mylist","v1","v2","v3","v4","v5");
List<String> list = jedis.lrange("mylist", 0, -1);
for (String element : list) {
System.out.println(element);
}
// set
jedis.sadd("orders", "jd001");
jedis.sadd("orders", "jd002");
jedis.sadd("orders", "jd003");
Set<String> set1 = jedis.smembers("orders");
for (Iterator iterator = set1.iterator(); iterator.hasNext();) {
String string = (String) iterator.next();
System.out.println(string);
}
jedis.srem("orders", "jd002");
System.out.println(jedis.smembers("orders").size());
// hash
jedis.hset("hash1", "userName", "lisi");
System.out.println(jedis.hget("hash1", "userName"));
Map<String, String> map = new HashMap<String, String>();
map.put("telphone", "13811814763");
map.put("address", "atguigu");
map.put("email", "abc@163.com");
jedis.hmset("hash2", map);
List<String> result = jedis.hmget("hash2", "telphone", "email");
for (String element : result) {
System.out.println(element);
}
// zset
jedis.zadd("zset01", 60d, "v1");
jedis.zadd("zset01", 70d, "v2");
jedis.zadd("zset01", 80d, "v3");
jedis.zadd("zset01", 90d, "v4");
Set<String> s1 = jedis.zrange("zset01", 0, -1);
for (Iterator iterator = s1.iterator(); iterator.hasNext();) {
String string = (String) iterator.next();
System.out.println(string);
}
}
}
事務
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class TestTX {
public boolean transMethod() throws InterruptedException {
Jedis jedis = new Jedis("127.0.0.1", 6379);
int balance;// 可用余額
int debt;// 欠額
int amtToSubtract = 10;// 實刷額度
jedis.watch("balance");
// jedis.set("balance","5");//此句不該出現,講課方便。模擬其他程序已經修改了該條目
Thread.sleep(7000);
balance = Integer.parseInt(jedis.get("balance"));
if (balance < amtToSubtract) {
jedis.unwatch();
System.out.println("modify");
return false;
} else {
System.out.println("***********transaction");
Transaction transaction = jedis.multi();
transaction.decrBy("balance", amtToSubtract);
transaction.incrBy("debt", amtToSubtract);
transaction.exec();
balance = Integer.parseInt(jedis.get("balance"));
debt = Integer.parseInt(jedis.get("debt"));
System.out.println("*******" + balance);
System.out.println("*******" + debt);
return true;
}
}
/**
* 通俗點講,watch命令就是標記一個鍵,如果標記了一個鍵, 在提交事務前如果該鍵被別人修改過,那事務就會失敗,這種情況通常可以在程序中 重新再嘗試一次。
* 首先標記了鍵balance,然后檢查余額是否足夠,不足就取消標記,並不做扣減; 足夠的話,就啟動事務進行更新操作,
* 如果在此期間鍵balance被其它人修改, 那在提交事務(執行exec)時就會報錯, 程序中通常可以捕獲這類錯誤再重新執行一次,直到成功。
*
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
TestTX test = new TestTX();
boolean retValue = test.transMethod();
System.out.println("main retValue-------: " + retValue);
}
}
主從復制
import redis.clients.jedis.Jedis;
public class TestMS {
public static void main(String[] args) {
Jedis jedis_M = new Jedis("127.0.0.1", 6379);
Jedis jedis_S = new Jedis("127.0.0.1", 6380);
jedis_S.slaveof("127.0.0.1", 6379);
jedis_M.set("class", "1122V2");
String result = jedis_S.get("class");//可能有延遲,需再次啟動才能使用
System.out.println(result);
}
}
JedisPool
- 獲取Jedis實例需要從JedisPool中獲取
- 用完Jedis實例需要返還給JedisPool
- 如果Jedis在使用過程中出錯,則也需要還給JedisPool
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisPoolUtil {
private static volatile JedisPool jedisPool = null;
private JedisPoolUtil() {
}
public static JedisPool getJedisPoolInstance() {
if (null == jedisPool) {
synchronized (JedisPoolUtil.class) {
if (null == jedisPool) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxActive(1000);
poolConfig.setMaxIdle(32);
poolConfig.setMaxWait(100 * 1000);
poolConfig.setTestOnBorrow(true);
jedisPool = new JedisPool(poolConfig, "127.0.0.1", 6379);
}
}
}
return jedisPool;
}
public static void release(JedisPool jedisPool, Jedis jedis) {
if (null != jedis) {
jedisPool.returnResourceObject(jedis);
}
}
}
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class TestPool {
public static void main(String[] args) {
JedisPool jedisPool = JedisPoolUtil.getJedisPoolInstance();
JedisPool jedisPool2 = JedisPoolUtil.getJedisPoolInstance();
System.out.println(jedisPool == jedisPool2);
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.set("aa", "bb");
} catch (Exception e) {
e.printStackTrace();
} finally {
JedisPoolUtil.release(jedisPool, jedis);
}
}
}
配置總結
JedisPool的配置參數大部分是由JedisPoolConfig的對應項來賦值的。
- maxActive:控制一個pool可分配多少個jedis實例,通過pool.getResource()來獲取;如果賦值為-1,則表示不限制;如果pool已經分配了maxActive個jedis實例,則此時pool的狀態為exhausted。
- maxIdle:控制一個pool最多有多少個狀態為idle(空閑)的jedis實例;
- whenExhaustedAction:表示當pool中的jedis實例都被allocated完時,pool要采取的操作;默認有三種。
- WHEN_EXHAUSTED_FAIL --> 表示無jedis實例時,直接拋出NoSuchElementException;
- WHEN_EXHAUSTED_BLOCK --> 則表示阻塞住,或者達到maxWait時拋出JedisConnectionException;
- WHEN_EXHAUSTED_GROW --> 則表示新建一個jedis實例,也就說設置的maxActive無用;
- maxWait:表示當borrow一個jedis實例時,最大的等待時間,如果超過等待時間,則直接拋JedisConnectionException;
- testOnBorrow:獲得一個jedis實例的時候是否檢查連接可用性(ping());如果為true,則得到的jedis實例均是可用的;
- testOnReturn:return 一個jedis實例給pool時,是否檢查連接可用性(ping());
- testWhileIdle:如果為true,表示有一個idle object evitor線程對idle object進行掃描,如果validate失敗,此object會被從pool中drop掉;這一項只有在timeBetweenEvictionRunsMillis大於0時才有意義;
- timeBetweenEvictionRunsMillis:表示idle object evitor兩次掃描之間要sleep的毫秒數;
- numTestsPerEvictionRun:表示idle object evitor每次掃描的最多的對象數;minEvictableIdleTimeMillis
- minEvictableIdleTimeMillis:表示一個對象至少停留在idle狀態的最短時間,然后才能被idle object evitor掃描
- 並驅逐;這一項只有在timeBetweenEvictionRunsMillis大於0時才有意義;
- softMinEvictableIdleTimeMillis:在minEvictableIdleTimeMillis基礎上,加入了至少minIdle個對象已經在pool里面了。如果為-1,evicted不會根據idle time驅逐任何對象。如果minEvictableIdleTimeMillis>0,則此項設置無意義,且只有在timeBetweenEvictionRunsMillis大於0時才有意義;
- lifo:borrowObject返回對象時,是采用DEFAULT_LIFO(last in first out,即類似cache的最頻繁使用隊列),如果為False,則表示FIFO隊列;
RedisTemplate
Jedis是Redis官方推薦的面向Java的操作Redis的客戶端,而RedisTemplate是SpringDataRedis中對JedisApi的高度封裝。
SpringDataRedis相對於Jedis來說可以方便地更換Redis的Java客戶端,比Jedis多了自動管理連接池的特性,方便與其他Spring框架搭配使用
@Autowired
private RedisTemplate<String,String> template;
redis的基本操作
操作 | Jedis | StringRedisTemplate |
---|---|---|
String | ||
設置 | set("k","v") | template.opsForValue().set("k","v") |
獲取 | get("k") | template.opsForValue().get("k") |
增1 | incr("k") | template.boundValueOps("k").increment(1) |
減1 | decr("k") | template.boundValueOps("k").increment(-1) |
設置時間 | setex("k",seconds,"v") | template.opsForValue().set("k","v",20, TimeUnit.SECONDS) |
不存在 就設置 | setnx("k","v") | template.opsForValue().setIfAbsent("k", "v") |
獲取過期時間 | ttl("k") | template.getExpire("k") |
刪除 | del("k") | template.delete("k") |
Hash | ||
設置 | jedis.hset("pig","name","peiqi"; | template.opsForHash().put("pig","name","peiqi") |
獲取 | jedis.hget("pig","name") | template.opsForHash().get("pig", "name") 獲取所有template.opsForHash().values("pig") |
刪除 | jedis.hdel("pig","name") | template.opsForHash().delete("pig","name") |
判斷是否存在 | jedis.hexists("pig","name") | template.opsForHash().hasKey("pig","name") |
List | 左/右不做區分 | |
添加 | rpush("k","v") | template.opsForList().rightPush("k","v") |
移出 | rpop("list") | template.opsForList().rightPop("k") |
長度 | llen("k") | template.opsForList().size("k") |
獲取 | lrange("list",0,-1) //-1全部 | template.opsForList().range("list", 0, -1) |
Set | ||
添加 | sadd("k","v") | template.opsForSet().add("k","v") |
值移除 | srem("k","v") | template.opsForSet().remove("k","v") |
直接移 | spop("k") | template.opsForSet().pop("k") |
長度 | scard("k") | template.opsForSet().size("k") |
交集 | sinter("k1","k2" ) | template.opsForSet().intersect("k", "k2") |
並集 | sunion("k1","k2" ) | template.opsForSet().union("k", "k2") |
差集 | sdiff("k1","k2" ) | template.opsForSet().difference("k", "k2") |
Zset | ||
增加 | zadd("k",1,"a") | template.opsForZSet().add("k","aa",12) |
排名結果 | zrevrange("k", 0, -1) | template.opsForZSet().reverseRange("k", 0, -1) |
排名分數 | zrevrangeByScoreWithScores("k", 12, 10); | template.opsForZSet().reverseRangeByScore("k", 1, 100) |
修改分數 | zincrby("k",20,"a") | template.opsForZSet().incrementScore("k","aa",19) |
數量 | zcard("k") | template.opsForZSet().zCard("k") |
獲取排名 | zrank("k","a") | template.opsForZSet().rank("k","aa") |