# getset # 先get然后set
127.0.0.1:6379> getset db redis # 如果不存在值,则返回nil
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongo # 如果存在值,则返回原来的值,并设置新的值
"redis"
127.0.0.1:6379> get db
"mongo"
5.2. List类型
所有的List命令都是以l开头的,在redis里面我们可以把List玩成,栈、队列、阻塞队列!
List当中插入一个元素LPUSH/RPUSH
List当中获取指定元素LRANGE
移出List集合中的一个元素LPOP/RPOP
移出List集合中指定的元素LREM
根据索引(下标)获取集合中元素值LINDEX
获取List的长度LLEN
ltrim裁剪List为原来的一部分(直接修改原有List集合)
移出列表的最后一个元素,并移动到新的列表中RPOPLPUSH
将列表中指定的下标值替换为另一个值,更新操作,如果下标不存在就会报错
在list集合中的指定元素前面插入值linsert lst before world xiaofan
127.0.0.1:6379> lpush list one # 将一个值或者多个值,插入到列表头部(左)
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1 # 获取list中的值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> lrange list 0 1 # 通过区间获取具体的值
1) "three"
2) "two"
127.0.0.1:6379> rpush list four # 将一个值或者多个值,插入到列表尾部(右)
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "four"
127.0.0.1:6379> lpop list # 移出list的第一个元素(左)
"three"
127.0.0.1:6379> rpop list # 移出list的最后一个元素(右)
"four"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
######################################################################
# lindex 根据下标获取元素
127.0.0.1:6379> lindex list 0
"two"
127.0.0.1:6379> lindex list 1
"one"
127.0.0.1:6379> llen list # 获取长度
######################################################################
# 移出指定的值!
127.0.0.1:6379> lpush list one two three
(integer) 3
127.0.0.1:6379> lpush list three
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lrem list 1 one # 移除list集合中指定个数的value,精确匹配
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> lrem list 2 three
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "two"
######################################################################
# 截断
127.0.0.1:6379> lrange list 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> ltrim list 1 2 # 通过下标截取指定的长度,这个list已经改变了,截断了,只剩下截取的元素
OK
127.0.0.1:6379> lrange list 0 -1
1) "b"
2) "c"
######################################################################
# rpoplpush 移除列表的最后一个元素,将他移动到新的列表当中
127.0.0.1:6379> rpush list1 a b c d
(integer) 4
127.0.0.1:6379> lrange list1 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> rpoplpush list1 list2 # 移除列表的最后一个元素,将他移动到新的列表中!
"d"
127.0.0.1:6379> rpoplpush list1 list2
"c"
127.0.0.1:6379> lrange list1 0 -1
1) "a"
2) "b"
127.0.0.1:6379> lrange list2 0 -1
1) "c"
2) "d"
######################################################################
# lset 更新list当中存在的元素
127.0.0.1:6379> exists list
(integer) 0
127.0.0.1:6379> lset list 0 item
(error) ERR no such key
127.0.0.1:6379> lpush list a
(integer) 1
127.0.0.1:6379> lset list 0 item # 如果存在当前下标值,则更新
OK
127.0.0.1:6379> lrange list 0 -1
1) "item"
127.0.0.1:6379> lset list 1 value # 如果不存在当前下标值,则报错
(error) ERR index out of range
######################################################################
127.0.0.1:6379> linsert list before b xxx
(integer) 6
127.0.0.1:6379> lrange list 0 -1
1) "a"
2) "xxx"
3) "b"
4) "c"
5) "d"
6) "b"
127.0.0.1:6379> linsert list after b yyy
(integer) 7
127.0.0.1:6379> lrange list 0 -1
1) "a"
2) "xxx"
3) "b"
4) "yyy"
5) "c"
6) "d"
7) "b"
m 为米。
km 为千米。
mi 为英里。
ft 为英尺。
127.0.0.1:6379> geodist china:city beijing taiyuan km
"404.1120"
127.0.0.1:6379> geodist china:city beijing shanghai
"1067597.9668"
127.0.0.1:6379> geodist china:city beijing shanghai km
"1067.5980"
127.0.0.1:6379> PFADD mykey a b c d e f g h i j # 创建第一组元素 mykey
(integer) 1
127.0.0.1:6379> PFCOUNT mykey # 统计第一组元素的个数
(integer) 10
127.0.0.1:6379> PFADD mykey2 i j z x c v b n m # 创建第二组元素 mykey2
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2 # 统计第二组元素的个数
(integer) 9
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2 # 合并第一组元素和第二组元素
OK
127.0.0.1:6379> PFCOUNT mykey3
(integer) 15
127.0.0.1:6379> multi # 开启事务
OK
# 入队
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> exec # 执行事务
1) OK
2) OK
3) "v2"
4) OK
取消事务
127.0.0.1:6379> multi # 开启事务
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> DISCARD # 取消事务
OK
127.0.0.1:6379> keys * # 事务队列中命令都不会被执行
(empty array)
编译性异常(代码有问题! 命令有错!),事务中所有的命令都不会被执行!
127.0.0.1:6379> multi # 开启事务
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> setget k3 # 命令报错
(error) ERR unknown command `setget`, with args beginning with: `k3`,
127.0.0.1:6379> set k4 v4
QUEUED
127.0.0.1:6379> set k5 v5
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k5 # 队列中的其他命令都没有被执行
(nil)
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> INCR k1 # 会执行的时候失败
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> get k3
QUEUED
127.0.0.1:6379> EXEC
1) (error) ERR value is not an integer or out of range # 虽然其中一条命令执行失败了,但是不影响其他命令执行
2) OK
3) OK
4) "v3"
127.0.0.1:6379> get k3
"v3"
127.0.0.1:6379> get k2
"v2"
8. Redis实现乐观锁
# 正常执行
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money # 监视money对象
OK
127.0.0.1:6379> multi # 事务正常结束,数据期间没有发生变化,这个时候就正常执行成功!
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> INCRBY out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20
测试多线程(另起一个客户端)修改值,使用watch可以当做redis的乐观锁操作!
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> INCRBY out 20
QUEUED
127.0.0.1:6379> exec # 执行之前,另一个线程修改了我们的值, 这个时候,就会导致事务执行失败!
(nil)
127.0.0.1:6379> set salary 100
OK
127.0.0.1:6379> watch salary
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY salary 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> exec # 执行事务的时候报错
(nil)
127.0.0.1:6379> unwatch # 取消监听
OK
127.0.0.1:6379> watch salary # 重新监听
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY salary 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
127.0.0.1:6379> exec
1) (integer) 990
2) (integer) 10
9. Jedis
导入依赖
redis.clientsjedis3.3.0com.alibabafastjson1.2.73
测试
Jedis jedis = new Jedis("47.94.235.187", 6379);
System.out.println(jedis.ping());
10. springboot
源码分析:
@Bean
@ConditionalOnMissingBean(name = {"redisTemplate"}) // 我们可以自己定一个redisTemplate来替换这个默认的!
public RedisTemplate
public class HttpClientUtils
{
public static CloseableHttpClient createSSLClientDefault(CookieStore cookies){
SSLContext sslContext=null;
try
{
sslContext=new SSLContextBuilder().l
对于JAVA的join,JDK 是这样说的:join public final void join (long millis )throws InterruptedException Waits at most millis milliseconds for this thread to die. A timeout of 0 means t
在网站项目中,没必要把公用的函数写成一个工具类,有时候面向过程其实更方便。 在入口文件index.php里添加 require_once('protected/function.php'); 即可对其引用,成为公用的函数集合。 function.php如下:
<?php /** * This is the shortcut to D
这篇日志是我写的第三次了 前两次都发布失败!郁闷极了!
由于在web开发中常常用到这一部分所以在此记录一下,呵呵,就到备忘录了!
我对于登录信息时使用session存储的,所以我这里是通过实现HttpSessionAttributeListener这个接口完成的。
1、实现接口类,在web.xml文件中配置监听类,从而可以使该类完成其工作。
public class Ses
Spring Boot 1.3.0.M1于6.12日发布,现在可以从Spring milestone repository下载。这个版本是基于Spring Framework 4.2.0.RC1,并在Spring Boot 1.2之上提供了大量的新特性improvements and new features。主要包含以下:
1.提供一个新的sprin