Java游戏服务器开发之二十二–使用Jedis访问redis数据库
介绍
Redis是一个远程数据结构服务器。它肯定比将数据存储在本地内存中要慢(因为它涉及套接字往返存取数据)。但是,它也带来了一些有趣的属性:
- Redis可以被应用程序的所有进程访问,可能运行在多个节点上(本地内存无法实现)。
- Redis内存存储非常高效,并在单独的过程中完成。如果应用程序在内存被垃圾收集的平台上运行(node.js,java等),它允许处理更大的内存缓存/存储。在实践中,非常大的堆用垃圾收集语言表现不佳。
如果需要,Redis可以将数据保存在磁盘上。 - Redis不仅仅是一个简单的缓存:它提供了各种数据结构,各种项目驱逐策略,阻塞队列,pub / sub,原子性,Lua脚本等等。
- Redis可以使用主/从机制来复制其活动,以实现高可用性。
基本上,如果需要你的应用程序在共享相同数据的多个节点上进行扩展,则需要类似Redis(或任何其他远程键/值存储)。
简单使用
redis快速上手使用 https://blog.csdn.net/cmqwan/article/details/81481522
Jedis
- Jedis是对redis的一层封装,把一些常用方法封装好了。
- JedisPool是jedis的连接池。
- 看下JedisPool的构造方法的参数
- @param poolConfig 连接池设置
- @param host 主机
- @param port 端口
- @param timeout 超时
- @param password 密码
- @param databaseIndex 数据库
– Jedis有哪些方法
- 看下JedisPool的构造方法的参数
需要引入的包
<!-- redis start -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.3</version>
</dependency>
<!--上面已经添加了-->
<!--<dependency>-->
<!--<groupId>org.springframework.data</groupId>-->
<!--<artifactId>spring-data-redis</artifactId>-->
<!--<version>1.7.1.RELEASE</version>-->
<!--</dependency>-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
<!-- redis end -->
关键代码
我们使用就是在JedisPool上进行操作,主要是这么几个方法
构造线程池
/**
* 创建一个redis连接池
*
* @param poolConfig 连接池设置
* @param host 主机
* @param port 端口
* @param timeout 超时
* @param password 密码
* @param databaseIndex 数据库
*/
public void createJedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port, int timeout,
final String password, final int databaseIndex) {
pool = new JedisPool(poolConfig, host, port, timeout, password, databaseIndex);
}
从线程池中获取Jedis
/**
* 获取Jedis对象
*
* @return Jedis
*/
public synchronized Jedis getJedis() {
Jedis jedis = null;
if (pool != null) {
if (jedis == null) {
try {
jedis = pool.getResource();
} catch (Exception e) {
logger.debug("Jedis getJedis find error", e);
}
}
}
return jedis;
}
使用jedis进行读写
/**
* 从高到低排名,返回前 num 个
*
* @param key 键
* @param num 数量
* @return Set
*/
public Set<String> ztop(String key, int num) {
if (num <= 0) {
return Collections.emptySet();
}
Jedis jedis = getJedis();
Set<String> ret = jedis.zrevrange(key, 0, num - 1);
jedis.close();
return ret;
}
测试方法
/*
* Copyright (C), 2015-2018
* FileName: RedisTest
* Author: zhao
* Date: 2018/8/6 16:00
* Description: Redis的测试类
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
package com.lizhaoblog.base.redis;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
import java.util.Set;
import redis.clients.jedis.JedisPoolConfig;
/**
* 〈一句话功能简述〉<br>
* 〈Redis的测试类〉
* 〈Redis工具,从<<Java游戏服务器开发>>一书中获取〉
*
* @author zhao
* @date 2018/8/6 16:00
* @see Redis
* @since 1.0.1
*/
public class RedisTest {
private static final Logger logger = LoggerFactory.getLogger(RedisTest.class);
@Test
public void test() {
String host = "127.0.0.1";
int port = 6379;
int timeout = 2000;
String password = "admin123";
int databaseIndex = 16;
logger.info("Redis at {}:{}", host, port);
JedisPoolConfig poolConfig = new JedisPoolConfig();
//设置最大连接数(100个足够用了,没必要设置太大)
poolConfig.setMaxTotal(100);
//最大空闲连接数
poolConfig.setMaxIdle(10);
//获取Jedis连接的最大等待时间(50秒)
poolConfig.setMaxWaitMillis(50 * 1000);
//在获取Jedis连接时,自动检验连接是否可用
poolConfig.setTestOnBorrow(false);
//在将连接放回池中前,自动检验连接是否有效
poolConfig.setTestOnReturn(true);
//自动测试池中的空闲连接是否都是可用连接
poolConfig.setTestWhileIdle(true);
Redis redis = Redis.getInstance();
redis.createJedisPool(poolConfig, host, port, timeout, password, databaseIndex);
/** redis save **/
logger.info("=============redis save==============");
// string save
logger.info("string save:调用set时,若key不存在则添加key,否则为修改key对应的值");
redis.set("testKey1", "test string val1");
// set save
logger.info("set save:set中的元素不允许出现重复且无序");
redis.sadd("testKey2", "test set val1");
redis.sadd("testKey2", "test set val2");
redis.sadd("testKey2", "test set val3");
// hash save
logger.info("hash save:调用hset时,若key不存在则创建key,若hash中存在这个hashkey,则修改其值,不存在则添加一条hash数据");
redis.hset("testKey3", "hashKey1", "hashVal1");
redis.hset("testKey3", "hashKey2", "hashVal2");
redis.hset("testKey3", "hashKey3", "hashVal3");
redis.hset("testKey3", "hashKey4", "hashVal4");
// list save
logger.info("list save:数据在链表中是有序的,并可以重复添加数据");
redis.lpush("testKey4", "test list val1");
redis.lpush("testKey4", "test list val2");
redis.lpush("testKey4", "test list val3");
// sorted set save
logger.info("sorted set save:有序set中的元素是有序的");
redis.zadd("testKey5", 1, "test zset val1");
redis.zadd("testKey5", 2, "test zset val2");
redis.zadd("testKey5", 3, "test zset val3");
redis.zadd("testKey5", 4, "test zset val4");
/** redis get **/
logger.info("=============redis get==============");
// string get
String stringRet = redis.get("testKey1");
logger.info("string get:" + stringRet);
// set get
Set<String> setRet = redis.sget("testKey2");
logger.info("set get:");
for (String string : setRet) {
logger.info(string + ",");
}
// hash get
String hashKeyRet = redis.hget("testKey3", "hashKey2");
logger.info("hash key get:" + hashKeyRet);
Map<String, String> hashRet = redis.hgetAll("testKey3");
logger.info("hash get:");
for (String string : hashRet.keySet()) {
logger.info("key[" + string + "]" + "value[" + hashRet.get(string) + "],");
}
// list get
List<String> listRet = redis.lgetList("testKey4");
logger.info("list get:");
for (String string : listRet) {
logger.info(string + ",");
}
// zset get
long val2Rank = redis.zrank("testKey5", "test zset val2");
logger.info("zset get val2 rank:" + val2Rank);
Set<String> zsetRet = redis.zrange("testKey5", 0, 3);
logger.info("zset get range:");
for (String string : zsetRet) {
logger.info(string + ",");
}
/** redis delete **/
logger.info("=============redis delete==============");
// string delete
logger.info("string delete:调用Redis的del方法,可直接删除key,对于所有的数据类型来说,都可以通过这种方式直接删除整个key");
redis.del("testKey1");
// set delete
logger.info("set delete:删除set中的val3");
redis.sremove("testKey2", "test set val3");
// hash delete
logger.info("hash delete:删除hash中key为hashKey4的元素");
redis.hdel("testKey3", "hashKey4");
// list delete
logger.info("list delete:删除list中值为test list val3的元素,其中count参数,0代表删除全部,正数代表正向删除count个此元素,负数代表负向删除count个此元素");
redis.lrem("testKey4", 0, "test list val3");
// zset delete
logger.info("zset delete:同set删除元素的方式相同");
redis.zrem("testKey5", "test zset val4");
logger.info("除了以上常用api之外,还有更多api,在Redis类中都有列出,请参考Redis类,或直接参照Jedis的官方文档");
}
}
工具类完整代码
/*
* Copyright (C), 2015-2018
* FileName: Redis
* Author: zhao
* Date: 2018/8/4 10:30
* Description: Redis工具
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
package com.lizhaoblog.base.redis;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Tuple;
/**
* 〈一句话功能简述〉<br>
* 〈Redis工具,从<<Java游戏服务器开发>>一书中获取〉
* <具体简单入门可以查看:https://blog.csdn.net/cmqwan/article/details/81481522>
*
* @author zhao
* @date 2018/8/4 10:30
* @since 1.0.1
*/
public class Redis {
private static Redis instance;
private static final Logger logger = LoggerFactory.getLogger(Redis.class);
private JedisPool pool = null;
public static Redis getInstance() {
if (instance == null) {
instance = new Redis();
}
return instance;
}
/**
* 创建一个redis连接池
*
* @param poolConfig 连接池设置
* @param host 主机
* @param port 端口
* @param timeout 超时
* @param password 密码
* @param databaseIndex 数据库
*/
public void createJedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port, int timeout,
final String password, final int databaseIndex) {
pool = new JedisPool(poolConfig, host, port, timeout, password, databaseIndex);
}
/**
* 获取Jedis对象
*
* @return Jedis
*/
public synchronized Jedis getJedis() {
Jedis jedis = null;
if (pool != null) {
if (jedis == null) {
try {
jedis = pool.getResource();
} catch (Exception e) {
logger.debug("Jedis getJedis find error", e);
}
}
}
return jedis;
}
public Map<String, String> hgetAll(String key) {
if (key == null) {
return null;
}
Jedis jedis = getJedis();
//
Map<String, String> ret = jedis.hgetAll(key);
jedis.close();
return ret;
}
public static Map<String, String> objectToHash(Object obj)
throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Map<String, String> map = new HashMap<String, String>();
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
if (!"class".equals(property.getName())) {
map.put(property.getName(), "" + property.getReadMethod().invoke(obj));
}
}
return map;
}
public static void hashToObject(Map<?, ?> map, Object obj) throws IllegalAccessException, InvocationTargetException {
for (Map.Entry<?, ?> entry : map.entrySet()) {
if ("null".equals(entry.getValue())) {
entry.setValue(null);
}
}
BeanUtils.populate(obj, (Map) map);
}
@SuppressWarnings("unchecked")
public static <T> T hashToObject(Map<?, ?> map, Class c)
throws IllegalAccessException, InvocationTargetException, InstantiationException {
Object obj = c.newInstance();
hashToObject(map, obj);
return (T) obj;
}
public List<String> hmget(String key, String... fields) {
Jedis jedis = getJedis();
List<String> ret = jedis.hmget(key, fields);
jedis.close();
return ret;
}
public String hmset(String key, Object object)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
Jedis jedis = getJedis();
String ret = jedis.hmset(key, objectToHash(object));
jedis.close();
return ret;
}
public String hmset(String key, Map<String, String> fields)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
Jedis jedis = getJedis();
String ret = jedis.hmset(key, fields);
jedis.close();
return ret;
}
public boolean hexist(String key, String field) {
if (key == null) {
return false;
}
Jedis jedis = getJedis();
boolean ret = jedis.hexists(key, field);
jedis.close();
return ret;
}
public Long hdel(String key, String... fields) {
Jedis jedis = getJedis();
Long cnt = jedis.hdel(key, fields);
jedis.close();
return cnt;
}
public String hget(String key, String field) {
if (key == null) {
return null;
}
Jedis jedis = getJedis();
String ret = jedis.hget(key, field);
jedis.close();
return ret;
}
public void hset(String key, String field, String value) {
if (field == null || field.length() == 0) {
return;
}
if (value == null || value.length() == 0) {
return;
}
Jedis jedis = getJedis();
jedis.hset(key, field, value);
jedis.close();
}
/**
* Map 的存放和获取
*/
public void add(String group, Map<String, String> values) {
if (values == null || values.size() == 0) {
return;
}
Jedis jedis = getJedis();
jedis.hmset(group, values);
jedis.close();
}
public void add(String group, String key, String value) {
if (value == null || key == null) {
return;
}
Jedis jedis = getJedis();
jedis.hset(group, key, value);
jedis.close();
}
public void set(String key, String value) {
if (value == null || key == null) {
return;
}
Jedis jedis = getJedis();
jedis.set(key, value);
jedis.close();
}
public Long hDelBuilder(String group, String... keys) {
Jedis jedis = getJedis();
byte[][] fields = new byte[keys.length][];
for (int i = 0; i < keys.length; i++) {
fields[i] = keys[i].getBytes();
}
Long cnt = jedis.hdel(group.getBytes(), fields);
jedis.close();
return cnt;
}
public Map<String, String> getMap(String group) {
Jedis jedis = getJedis();
Map<String, String> ret = jedis.hgetAll(group);
jedis.close();
return ret;
}
public String get(String key) {
Jedis jedis = getJedis();
String ret = jedis.get(key);
jedis.close();
return ret;
}
/**
* 添加元素到集合中
*
* @param key
* @param element
*/
public boolean sadd(String key, String... element) {
if (element == null || element.length == 0) {
return false;
}
Jedis jedis = getJedis();
boolean success = jedis.sadd(key, element) == 1;
jedis.close();
return success;
}
public boolean smove(String oldKey, String newKey, String element) {
if (element == null) {
return false;
}
Jedis jedis = getJedis();
boolean success = (jedis.smove(oldKey, newKey, element) == 1);
jedis.close();
return success;
}
/**
* 删除指定set内的元素
*/
public boolean sremove(String key, String... element) {
if (element == null) {
return false;
}
Jedis jedis = getJedis();
boolean success = (jedis.srem(key, element) == 1);
jedis.close();
return success;
}
public Set<String> sget(String key) {
Jedis jedis = getJedis();
Set<String> m = jedis.smembers(key);
jedis.close();
return m;
}
/**
* 返回set的的元素个数
*
* @param key
* @return
* @Title: zcard
*/
public long scard(String key) {
Jedis jedis = getJedis();
long size = jedis.scard(key);
jedis.close();
return size;
}
public void laddList(String key, String... elements) {
if (elements == null || elements.length == 0) {
return;
}
Jedis jedis = getJedis();
jedis.lpush(key, elements);
jedis.close();
}
/**
* @param key
* @param id
* @Title: lpush
*/
public void lpush(String key, String id) {
Jedis jedis = getJedis();
jedis.lpush(key, id);
jedis.close();
}
public void rpush(String key, String id) {
Jedis jedis = getJedis();
jedis.rpush(key, id);
jedis.close();
}
/**
* add by wangzhuan
*
* @param key
* @param start
* @param end
* @return
* @Title: lrange
*/
public List<String> lrange(String key, int start, int end) {
Jedis jedis = getJedis();
List<String> list = jedis.lrange(key, start, end);
jedis.close();
return list;
}
public List<String> lgetList(String key) {
Jedis jedis = getJedis();
long len = jedis.llen(key);
List<String> ret = jedis.lrange(key, 0, len - 1);
jedis.close();
return ret;
}
/**
* 列表list中是否包含value
*
* @param key
* @param value
* @return
*/
public boolean lexist(String key, String value) {
List<String> list = lgetList(key);
return list.contains(value);
}
public List<String> lgetList(String key, long len) {
Jedis jedis = getJedis();
long max = jedis.llen(key);
long l = max > len ? len : max;
List<String> ret = jedis.lrange(key, 0, l - 1);
jedis.close();
return ret;
}
public Long del(String key) {
Jedis jedis = getJedis();
Long cnt = jedis.del(key);
jedis.close();
return cnt;
}
/**
* 模糊删除
*
* @param key
* @return
*/
public Long delKeyLikes(String key) {
Jedis jedis = getJedis();
Set<String> keys = jedis.keys(key);
Long cnt = jedis.del(keys.toArray(new String[keys.size()]));
jedis.close();
return cnt;
}
/**
* 测试元素是否存在
*
* @param key
* @param element
* @return
*/
public boolean sexist(String key, String element) {
Jedis jedis = getJedis();
boolean ret = jedis.sismember(key, element);
jedis.close();
return ret;
}
/**
* 判断某一个key值得存储结构是否存在
*
* @param key
* @return
* @Title: exist
*/
public boolean exist(String key) {
Jedis jedis = getJedis();
boolean yes = jedis.exists(key);
jedis.close();
return yes;
}
/**********************************************************************
* 排行用到的SortedSet
**********************************************************************/
public long zadd(String key, int score, String member) {
Jedis jedis = getJedis();
long ret = 0;
try {
ret = jedis.zadd(key, score, member);
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
jedis.close();
}
return ret;
}
/**
* 添加 分数,并返回修改后的值
*
* @param key
* @param update
* @param member
* @return
*/
public double zincrby(String key, int update, String member) {
Jedis jedis = getJedis();
double ret = jedis.zincrby(key, update, member);
jedis.close();
return ret;
}
/**
* 返回有序集 key 中,成员 member 的 score 值,存在返回score,不存在返回-1
*
* @param key
* @param member
* @return
*/
public double zscore(String key, String member) {
Jedis jedis = getJedis();
Double ret = jedis.zscore(key, member);
jedis.close();
if (ret == null) {
return -1;
}
return ret;
}
/**
* 按 从大到小的排名,获取 member的 排名
*
* @param key
* @param member
* @return
*/
public long zrevrank(String key, String member) {
Jedis jedis = getJedis();
long ret = jedis.zrevrank(key, member);
jedis.close();
return ret;
}
/**
* 按照score的值从小到大排序,返回member的排名 排序是从0开始
*
* @param key
* @param member
* @return 设置为名次从1开始。返回为-1,表示member无记录
* @Title: zrank
*/
public long zrank(String key, String member) {
Jedis jedis = getJedis();
long ret = -1;
Long vv = jedis.zrank(key, member);
if (vv != null) {
ret = vv.longValue();
}
jedis.close();
if (ret != -1) {
ret += 1;
}
return ret;
}
/**
* 返回的是score的值
*
* @param key
* @param member
* @return 返回有序集 key 中,成员 member 的 score 值 如果 member 元素不是有序集 key 的成员,或 key
* 不存在,返回 null 。
* @Title: zscore
*/
public int zscoreDouble(String key, String member) {
Jedis jedis = getJedis();
int ret = -1;
Double vv = jedis.zscore(key, member);
if (vv != null) {
ret = (int) vv.doubleValue();
}
jedis.close();
if (ret != -1) {
ret += 1;
}
return ret;
}
/**
* min 和max 都是score的值
*
* @param key
* @param min
* @param max
* @return
* @Title: zrangebyscore
*/
// add 20141216
public Set<String> zrangebyscore(String key, long min, long max) {
Jedis jedis = getJedis();
Set<String> ss = jedis.zrangeByScore(key, min, max);
jedis.close();
return ss;
}
public Set<String> zrange(String key, long min, long max) {
Jedis jedis = getJedis();
Set<String> ss = jedis.zrange(key, min, max);
jedis.close();
return ss;
}
/**
* min 和max 都是score的值 获得一个包含了score的元组集合. 元组(Tuple)
* 笛卡尔积中每一个元素(d1,d2,…,dn)叫作一个n元组(n-tuple)或简称元组
*
* @param key
* @param min
* @param max
* @return
* @Title: zrangebyscorewithscores
*/
public Set<Tuple> zrangebyscorewithscores(String key, long min, long max) {
Jedis jedis = getJedis();
Set<Tuple> result = null;
try {
result = jedis.zrangeByScoreWithScores(key, min, max);
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
jedis.close();
}
return result;
}
/**
* zrevrangeWithScores : 从大到小排序 zrangeWithScores : 从小到大排序
*
* @param key
* @param start : (排名)0表示第一个元素,-x:表示倒数第x个元素
* @param end : (排名)-1表示最后一个元素(最大值)
* @return 返回 排名在start 、end之间带score元素
*/
public Map<String, Double> zrevrangeWithScores(String key, long start, long end) {
Jedis jedis = getJedis();
Set<Tuple> result = null;
try {
result = jedis.zrevrangeWithScores(key, start, end);
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
jedis.close();
}
return tupleToMap(result);
}
/**
* @param tupleSet 一个set
* @return Map<String<element, score>
*/
public Map<String, Double> tupleToMap(Set<Tuple> tupleSet) {
if (tupleSet == null) {
return null;
}
Map<String, Double> map = new LinkedHashMap<String, Double>();
for (Tuple tup : tupleSet) {
map.put(tup.getElement(), tup.getScore());
}
return map;
}
/**
* 删除key中的member
*
* @param key 键
* @param member 值
* @return 结果
*/
public long zrem(String key, String member) {
Jedis jedis = getJedis();
long result = -1;
try {
result = jedis.zrem(key, member);
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
jedis.close();
}
return result;
}
/**
* 从高到低排名,返回前 num 个score和member
*
* @param key 根据某个key
* @param num 前面第n个
* @return 返回一个set
*/
public Set<Tuple> ztopWithScore(String key, int num) {
if (num <= 0) {
return Collections.emptySet();
}
Jedis jedis = getJedis();
Set<Tuple> ret = jedis.zrevrangeWithScores(key, 0, num - 1);
jedis.close();
return ret;
}
/**
* 返回score区间的member
*
* @param key 键
* @param max 最大值
* @param min 最小值
* @return 一个区间set
*/
public Set<String> zrankByScore(String key, int max, int min) {
Jedis jedis = getJedis();
Set<String> ret = jedis.zrevrangeByScore(key, max, min);
jedis.close();
return ret;
}
/**
* 从高到低排名,返回前 num 个
*
* @param key 键
* @param num 数量
* @return Set
*/
public Set<String> ztop(String key, int num) {
if (num <= 0) {
return Collections.emptySet();
}
Jedis jedis = getJedis();
Set<String> ret = jedis.zrevrange(key, 0, num - 1);
jedis.close();
return ret;
}
/**
* 从高到低排名,返回start到end的前 num 个
*
* @param key 排序方式
* @return set
*/
public Set<String> ztop(String key, int start, int end) {
if (end <= start) {
return Collections.emptySet();
}
Jedis jedis = getJedis();
Set<String> ret = jedis.zrevrange(key, start, end - 1);
jedis.close();
return ret;
}
public long zcard(String key) {
Jedis jedis = getJedis();
long size = jedis.zcard(key);
jedis.close();
return size;
}
public static void destroy() {
getInstance().pool.destroy();
}
public void publish(String channel, String message) {
if (channel == null || message == null) {
return;
}
Jedis jedis = getJedis();
jedis.publish(channel, message);
jedis.close();
}
public String lpop(String key) {
Jedis jedis = getJedis();
String value = jedis.lpop(key);
jedis.close();
return value;
}
public void lrem(String key, int count, String value) {
Jedis jedis = getJedis();
jedis.lrem(key, count, value);
jedis.close();
}
}
上面的代码在码云上 https://gitee.com/lizhaoandroid/JgServer
可以加qq群一起探讨Java游戏服务器开发的相关知识 676231564