分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow
Redis介绍 && Java客户端操作Redis
本文内容
- redis介绍
- redis的 shell 客户端简介
- redis的 java 客户端简介
环境配置
- redis 2.8.17 64bit
- JDK1.6
redis介绍
大多数时候,我们都将 redis 称作是内存数据库,它在运行过程中,将键值对信息存储在内存中,同时在后台以异步的形式写入本地数据库中(默认是:dump.rdb,在 redis.conf 中配置,如果需要考虑安全的持久化需求需要开启 AOF 功能,详细介绍可以查看这篇文章 : redis持久化),redis中存储的 key 可以是任意类型,最后都会存储为 byte[] 类型;value 有多种类型 : string、list、set、sortedset、hash,基本上能够满足在开发中的键值存储需求;此外,redis还支持事务、消息系统等功能,而且提供了各种客户端的 API,如 Java、Python、Shell 等等。
redis的 shell 客户端简介
启动 shell 客户端之前,我们需要打开 redis 服务,redis 默认端口是6379,这个配置也是位于 redis.conf 中。登陆 redis 客户端的方法是 : redis-cli -h 127.0.0.1 -p 6379 (-h 是主机地址, -p 是 redis 服务端口号,由于本文介绍单机环境的 redis,我们可以直接采用默认的配置,那么登陆的方式可以简化为 : redis-cli),当我们打开了 shell 客户端之后,我们可以去 “Ping” 一下,如果返回 “PONG”,那么代表 redis 服务是处于健康状态的。
Redis中每个数据库对外都是一个从0开始的递增数字命名,Redis默认支持16个数据库,可以通过配置参数databases来修改这一数字。客户端与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT命令更换数据库。
之前说过,redis 的 value 支持许多种类型,redis 对于每一种存储类型都有不同的 shell 客户端 api,这里,我们对各种 value 的类型 api 进行介绍:
- String类型
String api | 功能描述 |
---|---|
set(key, value) | 给数据库中名称为key的string赋予值value |
get(key) | 返回数据库中名称为key的string的value |
getset(key, value) | 给名称为key的string赋予上一次的value |
mget(key1, key2,…, key N) | 返回库中多个string的value |
setnx(key, value) | 添加string,名称为key,值为value |
setex(key, time, value) | 向库中添加string,设定过期时间time |
mset(key N, value N) | 批量设置多个string的值 |
msetnx(key N, value N) | 如果所有名称为key i的string都不存在 |
incr(key) | 名称为key的string增1操作 |
incrby(key, integer) | 名称为key的string增加integer |
decr(key) | 名称为key的string减1操作 |
decrby(key, integer) | 名称为key的string减少integer |
append(key, value) | 名称为key的string的值附加value |
substr(key, start, end) | 返回名称为key的string的value的子串 |
- List类型
List api | 功能描述 |
---|---|
rpush(key, value) | 在名称为key的list尾添加一个值为value的元素 |
lpush(key, value) | 在名称为key的list头添加一个值为value的 元素 |
llen(key) | 返回名称为key的list的长度 |
lrange(key, start, end) | 返回名称为key的list中start至end之间的元素 |
ltrim(key, start, end) | 截取名称为key的list |
lindex(key, index) | 返回名称为key的list中index位置的元素 |
lset(key, index, value) | 给名称为key的list中index位置的元素赋值 |
lrem(key, count, value) | 删除count个key的list中值为value的元素 |
lpop(key) | 返回并删除名称为key的list中的首元素 |
rpop(key) | 返回并删除名称为key的list中的尾元素 |
blpop(key1, key2,… key N, timeout) | lpop命令的block版本 |
brpop(key1, key2,… key N, timeout) | rpop的block版本 |
- Set类型
List api | 功能描述 |
---|---|
sadd(key, member) | 向名称为key的set中添加元素member |
srem(key, member) | 删除名称为key的set中的元素member |
spop(key) | 随机返回并删除名称为key的set中一个元素 |
smove(srckey, dstkey, member) | 移到集合元素 |
scard(key) | 返回名称为key的set的基数 |
sismember(key, member) | member是否是名称为key的set的元素 |
sinter(key1, key2,…key N) | 求交集 |
sunion(key1, (keys)) | 求并集 |
sdiff(key1, (keys)) | 求差集 |
sinterstore(dstkey, (keys)) | 求交集并将交集保存到dstkey的集合 |
sunionstore(dstkey, (keys)) | 求并集并将并集保存到dstkey的集合 |
sdiffstore(dstkey, (keys)) | 求差集并将差集保存到dstkey的集合 |
smembers(key) | 返回名称为key的set的所有元素 |
srandmember(key) | 随机返回名称为key的set的一个元素 |
- Hash类型
Hash api | 功能描述 |
---|---|
hset(key, field, value) | 向名称为key的hash中添加元素field |
hget(key, field) | 返回名称为key的hash中field对应的value |
hmget(key, (fields)) | 返回名称为key的hash中field i对应的value |
hmset(key, (fields)) | 向名称为key的hash中添加元素field |
hincrby(key, field, integer) | 将名称为key的hash中field的value增加integer |
hexists(key, field) | 名称为key的hash中是否存在键为field的域 |
hdel(key, field) | 删除名称为key的hash中键为field的域 |
hlen(key) | 返回名称为key的hash中元素个数 |
hkeys(key) | 返回名称为key的hash中所有键 |
hvals(key) | 返回名称为key的hash中所有键对应的value |
hgetall(key) | 返回名称为key的hash中所有的键(field)及其对应的value |
除了针对 value 类型的 api 之外,还有一些常用的公共 api,如下:
常用 api | 功能描述 |
---|---|
quit | 关闭连接(connection) |
type(key) | 返回值的类型 |
del(key) | 删除一个key |
exists(key) | 确认一个key是否存在 |
keys(pattern) | 返回满足给定pattern的所有key |
dbsize | 返回当前数据库中key的数目 |
flushdb | 删除当前选择数据库中的所有key |
flushall | 删除所有数据库中的所有key |
redis的 Java 客户端简介
与 Shell 客户端支持单机与集群同一接口不同,Java 客户端针对单机环境与集群环境有不一样的接口(单机环境使用 Jedis对象,集群环境使用 JedisCluster 对象),本文针对单机环境进行介绍,集群环境的话,除了配置下主机地址与端口号,其他的接口操作同 Jedis 是一样的。
下面对 redis 提供的 Java 客户端接口进行介绍,由于代码中都有相应的注释,所以,不做详细描述:
- 公共接口
private static Jedis jedis; private static final String PREFIX = "qinyi-"; private static final String HOST_IP = "127.0.0.1"; private static final int HOST_PORT = 6379; private static final Logger logger = LoggerFactory.getLogger(RedisClient.class); public synchronized static Jedis getJedis(String host_ip, int host_port) { jedis = new Jedis(host_ip, host_port); //jedis.auth("root"); //开启密码验证(配置文件中为 requirepass root)的时候需要执行该方法 return jedis; } public synchronized static Jedis getDefaultJedis() { return getJedis(HOST_IP, HOST_PORT); } /** * 清空 redis 中的所有数据 * */ public String flushRedis() { logger.debug("flush redis data"); return getDefaultJedis().flushDB(); } /** * 根据 pattern 获取 redis 中的键 * */ public Set<String> getKeysByPattern(String pattern) { return getDefaultJedis().keys(pattern); } /** * 获取 redis 中所有的键 * */ public Set<String> getAllKeys() { return getKeysByPattern("*"); } /** * 判断key是否存在redis中 * */ public boolean exists(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().exists(PREFIX + key); } /** * 从Redis中移除一个key * */ public void removeKey(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } getDefaultJedis().del(PREFIX + key); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- String类型接口
/** * 存储字符串 * */ public void setString(String key, String value, int expireTime) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } String finalKey = PREFIX + key; getDefaultJedis().set(finalKey, value); if (expireTime > 0) { /** * 如果设置了 expireTime, 那么这个 finalKey会在expireTime秒后过期,那么该键会被自动删除 * 这一功能配合出色的性能让Redis可以作为缓存系统来使用,成为了缓存系统Memcached的有力竞争者 * */ getDefaultJedis().expire(finalKey, expireTime); } } /** * 获取字符串 * */ public String getString(String key) throws Exception{ if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().get(PREFIX + key); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- List类型接口
/** * 存储 List * */ public void pushList(String key, String value, String flag) throws Exception { if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(flag)) { logger.error("key or flag is null"); throw new Exception("key or flag is null"); } /** * key代表的是链表的名字 * List是一个双端链表,lpush是往链表的头部插入一条数据,rpush是往尾部插入一条数据 * */ if (flag.equalsIgnoreCase("L")) { getDefaultJedis().lpush(PREFIX + key, value); } else if (flag.equalsIgnoreCase("R")) { getDefaultJedis().rpush(PREFIX + key, value); } else { logger.error("unknown flag"); throw new Exception("unknown flag"); } } /** * 获取 List 中的单个元素 * */ public String popList(String key, String flag) throws Exception { if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(flag)) { logger.error("key or flag is null"); throw new Exception("key or flag is null"); } if (flag.equalsIgnoreCase("L")) { return getDefaultJedis().lpop(PREFIX + key); } else if (flag.equalsIgnoreCase("R")) { return getDefaultJedis().rpop(PREFIX + key); } else { logger.error("unknown flag"); throw new Exception("unknown flag"); } } /** * 获取 List 中指定区间上的元素 * */ public List<String> getAppointedList(String key, long start, long end) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().lrange(PREFIX + key, start, end); } /** * 获取 List 上所有的元素 * */ public List<String> getList(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().lrange(PREFIX + key, 0, -1); } /** * 获取 List 的长度 * */ public long getListLength(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().llen(PREFIX + key); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- Set类型接口
/** * 存储 Set : 单值存储 * */ public void addValueToSet(String key, String value) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } getDefaultJedis().sadd(PREFIX + key, value); } /** * 存储 Set : 多值存储 * */ public void addListToSet(String key, List<String> values) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } for (String value : values) { getDefaultJedis().sadd(PREFIX + key, value); } } /** * 删除 Set 中的某个元素 * */ public void deleteElementInSet(String key, String value) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } getDefaultJedis().srem(PREFIX + key, value); } /** * 获取 Set 中所有的成员 * */ public Set<String> getSet(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().smembers(PREFIX + key); } /** * 判断 value 是否属于 set * */ public boolean isExistInSet(String key, String value) throws Exception { if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(value)) { logger.error("key or value is null"); throw new Exception("key or value is null"); } return getDefaultJedis().sismember(PREFIX + key, value); } /** * 获取 Set 中元素个数 * */ public long getLengthOfSet(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().scard(PREFIX + key); } /** * 取两个 Set 的交集 * */ public Set<String> getSetInter(String key1, String key2) throws Exception { if (StringUtil.IsEmpty(key1) || StringUtil.IsEmpty(key2)) { logger.error("key1 or key2 is null"); throw new Exception("key1 or key2 is null"); } return getDefaultJedis().sinter(PREFIX + key1, PREFIX + key2); } /** * 取两个 Set 的并集 * */ public Set<String> getSetUnion(String key1, String key2) throws Exception { if (StringUtil.IsEmpty(key1) || StringUtil.IsEmpty(key2)) { logger.error("key1 or key2 is null"); throw new Exception("key1 or key2 is null"); } return getDefaultJedis().sunion(PREFIX + key1, PREFIX + key2); } /** * 取两个 Set 的差集 * */ public Set<String> getSetDiff(String key1, String key2) throws Exception { if (StringUtil.IsEmpty(key1) || StringUtil.IsEmpty(key2)) { logger.error("key1 or key2 is null"); throw new Exception("key1 or key2 is null"); } return getDefaultJedis().sdiff(PREFIX + key1, PREFIX + key2); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- SortedSet类型接口
/** * 存储有序集合 SortedSet * */ public void setSortedSet(String key, double weight, String value) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } getDefaultJedis().zadd(PREFIX + key, weight, value); } /** * 获取有序集合指定区间上的元素 * */ public Set<String> getAppointedSortedSet(String key, long start, long end) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().zrange(PREFIX + key, start, end); } /** * 获取有序集合上的所有元素 * */ public Set<String> getSortedSet(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().zrange(PREFIX + key, 0, -1); } /** * 获取有序集合上某个权重区间上的元素 * */ public long getLengthOfSortedSetByWeight(String key, double min, double max) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().zcount(PREFIX + key, min, max); } /** * 删除有序集合上的元素 * */ public void deleteElementInSortedSet(String key, String value) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } getDefaultJedis().zrem(PREFIX + key, value); } /** * 获取有序集合中元素的个数 * */ public long getLengthOfSortedSet(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().zcard(PREFIX + key); } /** * 查看有序集合中元素的权重 * */ public double getWeight(String key, String value) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().zscore(PREFIX + key, value); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- Hash类型接口
/** * 存储 HashMap * */ public void setHashMapByFieldAndValue(String key, String field, String value) throws Exception { if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(field)) { logger.error("key or field is null"); throw new Exception("key or field is null"); } getDefaultJedis().hset(PREFIX + key, field, value); } /** * 存储 HashMap * */ public void setHashMapByMap(String key, Map<String, String> map) throws Exception { if (StringUtil.IsEmpty(key) || map == null) { logger.error("key or map is null"); throw new Exception("key or map is null"); } getDefaultJedis().hmset(PREFIX + key, map); } /** * 删除 HashMap 中的键值对 * */ public void deleteHashMapValueByField(String key, String field) throws Exception { if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(field)) { logger.error("key or field is null"); throw new Exception("key or field is null"); } getDefaultJedis().hdel(PREFIX + key, field); } /** * 获取 HashMap 中键对应的值 * */ public String getHashMapValueByField(String key, String field) throws Exception { if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(field)) { logger.error("key or field is null"); throw new Exception("key or field is null"); } return getDefaultJedis().hget(PREFIX + key, field); } /** * 获取 HashMap 中所有的 key * */ public Set<String> getHashMapKeys(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().hkeys(PREFIX + key); } /** * 获取 HashMap 中所有的值 * */ public List<String> getHashMapValues(String key) throws Exception { if (StringUtil.IsEmpty(key)) { logger.error("key is null"); throw new Exception("key is null"); } return getDefaultJedis().hvals(PREFIX + key); } /** * 判断 HashMap 中是否存在某一个键 * */ public boolean isFieldExistsInHashMap(String key, String field) throws Exception { if (StringUtil.IsEmpty(key) || StringUtil.IsEmpty(field)) { logger.error("key or field is null"); throw new Exception("key or field is null"); } return getDefaultJedis().hexists(PREFIX + key, field); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
相对关系型数据库而言,redis 以一种非常简单的思想来存储数据,由于它将数据存储在内存中,所以,读写非常高效,同时,它将内存中的数据写入数据库中,保证数据不会丢失,每次关闭并重新打开时,再将存储在本地数据库中的键值对信息载入内存。
redis 同时提供 Windows 和 Linux 系统的不同版本,针对不同的流行语言都有相应的 API 接口(目前来看, Java 最为活跃),方便了开发过程中的使用。
一些经典的数据库操作,redis 中都有很好的支持,比如保证一致性的事务,减小构建数据库开销的连接池接口(JedisPool)等等。
总的来说,使用 redis,你会感受到它的简洁与高效!
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow