1. 程式人生 > >Redis從基礎命令到實戰之集合型別(Set)

Redis從基礎命令到實戰之集合型別(Set)

Redis集合型別的基礎功能也是儲存字串列表,和列表型別的區別是字串不能重複且沒有順序。當然,儲存元素唯一性也可以通過應用程式保證,單從這一點上並沒有體現出對比列表型別的特點。

其實,集合型別的一個鮮明特性是可以對多個集合求交集、並集和差集。例如在一個社交應用中,A使用者有C、D兩個好友,B使用者有D、E兩個好友,可用通過sinter A B的命令很方便的查出A和B的共同好友。

本節中將利用這個特性給實踐練習中的商品管理模組新增一個按分類查詢商品的功能。

一、常用命令

import java.util.Set;

import redis.clients.jedis.Jedis;

public class SetExample {

	public static void main(String[] args) {
		Jedis jedis = JedisProvider.getJedis();
		jedis.flushDB();

		// 向sets集合中加入元素, 成功返回1, 失敗返回0
		Long sadd = jedis.sadd("fruit", "apple");
		print("sadd fruit apple=" + sadd);
		
		//不能新增重複元素
		sadd = jedis.sadd("fruit", "apple");
		print("sadd fruit apple again=" + sadd);
		jedis.sadd("fruit", "banana", "orange", "grape");
		
		// 返回所有元素
		print("smembers fruit=" + jedis.smembers("fruit"));

		// 刪除元素
		long srem = jedis.srem("fruit", "apple");
		print("srem fruit apple=" + srem);
		
		// 判斷是否存在元素
		boolean exists = jedis.sismember("fruit", "apple");
		print("sismember fruit apple=" + exists);
		exists = jedis.sismember("fruit", "banana");
		print("sismember fruit banana=" + exists);
		
		// 統計元素個數
		print("scard fruit=" + jedis.scard("fruit"));
		
		// 隨機獲取一個元素
		print("srandmember fruit=" + jedis.srandmember("fruit"));
		
		// 隨機彈出一個元素
		print("spop fruit=" + jedis.spop("fruit"));

		jedis.sadd("fruit", "apple", "banana", "orange", "grape");
		jedis.sadd("food", "orange", "grape", "peach", "lemon");
		
		// 求交集
		Set<String> set = jedis.sinter("fruit", "food");
		print("sinter fruit food=" + set);
		
		// 求交集並存儲到指定集合
		jedis.sinterstore("sinter", "fruit", "food");
		print("sinterstore sinter=" + jedis.smembers("sinter"));
		
		// 求並集
		set = jedis.sunion("fruit", "food");
		print("sunion fruit food=" + set);
		
		// 求差集(fruit中有, food中沒有的元素)
		set = jedis.sdiff("fruit", "food");
		print("sdiff fruit food=" + set);

		jedis.close();
	}

	private static void print(String info) {
		System.out.println(info);
		System.out.println("------------------------------------------------------");
		System.out.println();
	}
}
二、實踐練習

首先修改商品類,新增一個設定分類的屬性 Goods.java

	private Set<String> tags;
	public Set<String> getTags() {
		return tags;
	}
	public void setTags(Set<String> tags) {
		this.tags = tags;
	}
然後給商品管理類新增兩個字串陣列用於隨機獲得分類
	private final String[] SIZE = { "small", "middle", "big" };
	private final String[] COLOR = { "red", "yellow", "green" };
修改新增商品的方法,同時儲存分類資訊
	/**
	 * 新增一個商品
	 * @param goods
	 * @return
	 */
	public boolean addGoods(Goods goods) {
		long id = getIncrementId();
		Map<String, String> map = new HashMap<>();
		map.put("id", String.valueOf(id));
		map.put("title", goods.getTitle());
		map.put("price", String.valueOf(goods.getPrice()));
		
		//隨機獲得三個分類
		String size = SIZE[new Random().nextInt(SIZE.length)];
		String color = COLOR[new Random().nextInt(COLOR.length)];
		
		String key = "goods:" + id;
		boolean added = jedis.hmset(key, map).equals("OK");
		if(added) {
			jedis.rpush("goods:list", String.valueOf(id));
			//記錄商品所屬分類
			jedis.sadd("goods:" + id + ":tags", size, color);
			//記錄每個分類下包含的商品ID
			jedis.sadd("tag:" + size + ":goods", String.valueOf(id));
			jedis.sadd("tag:" + color + ":goods", String.valueOf(id));
		}
		return added;
	}
按分類查詢商品
	/**
	 * 查詢指定尺寸和顏色的商品
	 * @param size
	 * @param color
	 * @return
	 */
	public List<Goods> findGoodsByTag(String size, String color) {
		Set<String> ids = jedis.sinter("tag:" + size + ":goods", "tag:" + color + ":goods");
		List<Goods> goodsList = new ArrayList<>();
		for(String id : ids) {
			String key = "goods:" + id;
			Map<String, String> maps = jedis.hgetAll(key);
			Goods goods = new Goods();
			goods.setId(NumberUtils.toLong(maps.get("id")));
			goods.setTitle(maps.get("title"));
			goods.setPrice(NumberUtils.toFloat(maps.get("price")));
			//讀取分類
			goods.setTags(jedis.smembers("goods:" + id + ":tags"));
			goodsList.add(goods);
		}
		return goodsList;
	}
測試程式碼
	public static void main(String[] args) {
		SetLession sl = new SetLession();
		sl.clear();
		
		//新增一批商品
		for(int i = 0; i< 42; i++) {
			Goods goods = new Goods(0, "goods" + String.format("%05d", (i + 1)), i);
			sl.addGoods(goods);
		}
		//讀取商品總數
		System.out.println("商品總數: " + sl.getTotalCount());
		//刪除第29件商品
		sl.delGoods(29);
		System.out.println("刪除後商品總數: " + sl.getTotalCount());
		//分頁顯示
		List<Goods> list = sl.getGoodsList(2, 20);
		System.out.println("第二頁商品:");
		for(Goods goods : list) {
			System.out.println(goods);
		}
		//按分類查詢
		List<Goods> listByTag = sl.findGoodsByTag("big", "green");
		System.out.println("所有尺寸為big,顏色為green的商品:");
		for(Goods goods : listByTag) {
			System.out.println(goods);
		}
	}

原始碼下載