1.登录和缓存功能实现
- package com.redis;
- import redis.clients.jedis.Jedis;
- /**
- * FileName: 登录和缓存
- * Author: sujinran
- * Date: 2018/6/17 15:12
- */
- public class LoginAndCookie {
- /**
- * 检查用户是否登录
- * @param conn redis连接
- * @param token 令牌
- * @return
- */
- public String checkToken(Jedis conn, String token) {
- //hget散列
- return conn.hget("login:", token);
- }
- /**
- * 更新令牌
- * @param conn redis连接
- * @param token 令牌
- * @param user 用户
- * @param item 商品
- */
- public void updateToken(Jedis conn, String token, String user, String item) {
- //获取当前时间戳
- long timestamp = System.currentTimeMillis() / 1000;
- //令牌和已经登录的用户映射
- conn.hset("login:", token, user);
- //记录令牌最后一次出现的时间
- conn.zadd("recent:", timestamp, token);
- if (item != null) {//传入的商品不是空的
- //记录浏览过的商品
- conn.zadd("viewed:" + token, timestamp, item);
- //移除旧的记录,保留最近浏览过的25个商品
- conn.zremrangeByRank("viewed:" + token, 0, -26);
- //Zincrby 命令对有序集合中指定成员的分数加上增量
- conn.zincrby("viewed:", -1, item);
- }
- }
- }
更新会话:
- package com.util;
- import redis.clients.jedis.Jedis;
- import java.util.ArrayList;
- import java.util.Set;
- /**
- * FileName: 更新登录会话
- * Author: sujinran
- * Date: 2018/6/17 19:40
- */
- public class CleanSessionsThread extends Thread {
- private Jedis conn;
- private int limit;
- private boolean quit;
- public CleanSessionsThread(int limit) {
- this.conn = new Jedis("localhost");
- this.conn.auth("123456");
- this.conn.select(15);
- this.limit = limit;
- }
- public void quit() {
- quit = true;
- }
- public void run() {
- while (!quit) {
- //依据登录时间确定在线人数
- long size = conn.zcard("recent:");
- if (size <= limit) {
- try {
- sleep(1000);
- } catch (InterruptedException ie) {
- Thread.currentThread().interrupt();
- }
- continue;
- }
- long endIndex = Math.min(size - limit, 100);
- Set<String> tokenSet = conn.zrange("recent:", 0, endIndex - 1);
- String[] tokens = tokenSet.toArray(new String[tokenSet.size()]);
- ArrayList<String> sessionKeys = new ArrayList<String>();
- for (String token : tokens) {
- sessionKeys.add("viewed:" + token);
- }
- conn.del(sessionKeys.toArray(new String[sessionKeys.size()]));
- conn.hdel("login:", tokens);
- conn.zrem("recent:", tokens);
- }
- }
- }
登录和缓存功能测试:
- import com.util.CleanSessionsThread;
- import com.redis.LoginAndCookie;
- import org.junit.Test;
- import redis.clients.jedis.Jedis;
- import java.util.UUID;
- /**
- * FileName: 登录和缓存测试
- * Author: sujinran
- * Date: 2018/6/17 19:15
- */
- public class LoginAndCookieTest {
- public static void main(String[] args) throws InterruptedException {
- Jedis conn =new Jedis("127.0.0.1");
- conn.auth("123456");
- LoginAndCookieTest loginAndCookieTest =new LoginAndCookieTest();
- loginAndCookieTest.testLoginCookies(conn);
- }
- /**
- * 登录测试
- *
- * @throws InterruptedException
- */
- public void testLoginCookies(Jedis conn) throws InterruptedException {
- /*
- 这里令牌自动生成
- UUID.randomUUID().toString():javaJDK提供的一个自动生成主键的方法
- */
- String token = UUID.randomUUID().toString();
- //创建登录和缓存类的对象
- LoginAndCookie loginAndCookie = new LoginAndCookie();
- /*
- 使用 LoginAndCookie 中的updateToken()的方法更新令牌
- conn:Redis连接,user1:用户,item1:商品
- */
- loginAndCookie.updateToken(conn, token, "user1", "item1");
- System.out.println("我们刚刚登录/更新了令牌:" + token);
- System.out.println("用户使用: 'user1'");
- System.out.println();
- System.out.println("当我们查找令牌时会得到什么用户名");
- String r = loginAndCookie.checkToken(conn, token);
- //r是令牌
- System.out.println(r);
- System.out.println();
- assert r != null;
- System.out.println("让我们把cookies的最大数量降到0来清理它们");
- System.out.println("我们开始用线程来清理,一会儿再停止");
- CleanSessionsThread thread = new CleanSessionsThread(0);
- thread.start();
- Thread.sleep(1000);
- thread.quit();
- Thread.sleep(2000);
- if (thread.isAlive()) {
- throw new RuntimeException("线程还存活?!?");
- }
- //Hlen命令用于获取哈希表中字段的数量
- long s = conn.hlen("login:");
- System.out.println("目前仍可提供的sessions次数如下: " + s);
- assert s == 0;
- }
- }
2.购物车功能实现
- package com.redis;
- import redis.clients.jedis.Jedis;
- /**
- * FileName: 购物车实现
- * Author: sujinran
- * Date: 2018/6/17 20:27
- */
- public class AddToCart {
- /**
- * 购物车实现
- * @param conn 连接
- * @param session 会话
- * @param item 商品
- * @param count 总数
- */
- public void addToCart(Jedis conn, String session, String item, int count) {
- //总数<=0
- if (count <= 0) {
- // 购物车移除指定的商品,HDEL 每次只能删除单个域
- conn.hdel("cart:" + session, item);
- } else {
- //将指定的商品添加到购物车,Hset 命令用于为哈希表中的字段赋值
- conn.hset("cart:" + session, item, String.valueOf(count));
- }
- }
- }
更新会话:
- package com.util;
- import redis.clients.jedis.Jedis;
- import java.util.ArrayList;
- import java.util.Set;
- /**
- * FileName: 更新购物车会话
- * Author: sujinran
- * Date: 2018/6/17 20:35
- */
- public class CleanFullSessionsThread extends Thread {
- private Jedis conn;
- private int limit;
- private boolean quit;
- public CleanFullSessionsThread(int limit) {
- this.conn = new Jedis("localhost");
- this.conn.auth("123456");
- this.conn.select(15);
- this.limit = limit;
- }
- public void quit() {
- quit = true;
- }
- public void run() {
- while (!quit) {
- long size = conn.zcard("recent:");
- if (size <= limit) {
- try {
- sleep(1000);
- } catch (InterruptedException ie) {
- Thread.currentThread().interrupt();
- }
- continue;
- }
- long endIndex = Math.min(size - limit, 100);
- Set<String> sessionSet = conn.zrange("recent:", 0, endIndex - 1);
- String[] sessions = sessionSet.toArray(new String[sessionSet.size()]);
- ArrayList<String> sessionKeys = new ArrayList<String>();
- for (String sess : sessions) {
- sessionKeys.add("viewed:" + sess);
- sessionKeys.add("cart:" + sess);
- }
- conn.del(sessionKeys.toArray(new String[sessionKeys.size()]));
- conn.hdel("login:", sessions);
- conn.zrem("recent:", sessions);
- }
- }
- }
购物车功能测试:
- import com.redis.AddToCart;
- import com.redis.LoginAndCookie;
- import com.util.CleanFullSessionsThread;
- import redis.clients.jedis.Jedis;
- import java.util.Map;
- import java.util.UUID;
- /**
- * FileName: 添加商品到购物车测试
- * Author: sujinran
- * Date: 2018/6/17 20:39
- */
- public class AddToCartTest {
- AddToCart addToCart =new AddToCart();
- LoginAndCookie loginAndCookie =new LoginAndCookie();
- public static void main(String[] args) throws InterruptedException {
- Jedis conn = new Jedis("127.0.0.1");
- conn.auth("123456");
- AddToCartTest addToCartTest =new AddToCartTest();
- addToCartTest.testShopppingCartCookies(conn);
- }
- /**
- * 添加商品到购物车测试
- * @param conn
- * @throws InterruptedException
- */
- public void testShopppingCartCookies(Jedis conn) throws InterruptedException {
- /*
- 这里令牌自动生成
- UUID.randomUUID().toString():javaJDK提供的一个自动生成主键的方法
- */
- String token = UUID.randomUUID().toString();
- System.out.println("我们将刷新我们的会话.");
- loginAndCookie.updateToken(conn, token, "user2", "item2");
- System.out.println("并在购物车中添加一个商品");
- addToCart.addToCart(conn, token, "item2", 3);
- Map<String, String> r = conn.hgetAll("cart:" + token);
- System.out.println("我们的购物车目前有:");
- for (Map.Entry<String, String> entry : r.entrySet()) {
- System.out.println(" " + entry.getKey() + ": " + entry.getValue());
- }
- System.out.println();
- assert r.size() >= 1;
- System.out.println("让我们清理我们的会话和购物车");
- CleanFullSessionsThread thread = new CleanFullSessionsThread(0);
- thread.start();
- Thread.sleep(1000);
- thread.quit();
- Thread.sleep(2000);
- if (thread.isAlive()) {
- throw new RuntimeException("清理会话线程还存在");
- }
- r = conn.hgetAll("cart:" + token);
- System.out.println("我们的购物车现在装有:");
- for (Map.Entry<String, String> entry : r.entrySet()) {
- System.out.println(" " + entry.getKey() + ": " + entry.getValue());
- }
- assert r.size() == 0;
- }
- }