Redis基本数据类型命令和事务操作


Reids存储的是key-value结构的数据类型,value有5中常用的数据类型:

1.字符串string,常用
2.哈希hash,hash适合存储对象
3.列表list,按照插入顺序排序,可以有重复元素
4.集合set,无序集合,没有重复元素
5.有序集合sorted set,有序集合,没有重复元素

字符串string类型操作命令

SET key value                设置指定key的值
GET key                      获取指定key的值
SETEX key seconds value      设置指定key的值,并将key的过期时间设为seconds秒
SETNX key value              只有在key不存在时设置key的值

哈希hash操作命令

Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象,常用命令:

HASH key field value        将哈希表key中的字段field的值设为value
HASH key field              获取存储在哈希表中指定字段的值
HDEL key field              删除存储在哈希表中的指定字段
HKEYS key                   获取哈希表中所有字段
HVALS key                   获取哈希表中所有值
HGETALL key                 获取在hash表中指定key的所有字段和值

在这里插入图片描述

列表list操作命令

Redis列表是简单的字符串列表,按照插入顺序排序,常用命令:

LPUSH key value1 [value2]      将一个或多个值插入到列表头部(LPUSH可以看成从左边插入)
LRANGE key start stop          获取列表指定范围内的元素(LRANGE可以看成从左边开始数)
RPOP key                       移除并获取列表最后一个元素(RPOP可以看成删除并获取最右边的value)
LLEN key                       获取列表长度
BRPOP key1 [key2] timeout      移除并获取列表最后一个元素,如果列表没有元素会阻塞列表直接直到等待超时
                               或发现可弹出元素位置

在这里插入图片描述

集合set操作命令

Redis set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,常用命令:

SADD key member1 [member2]        向集合中添加一个或多个成员
SMEMBERS key                      获取集合中的所有成员
SCARD key                         获取集合中的成员数
SINTER key1 [key2]                返回给定所有集合中的交集
SUNION key1 [key2]                返回给定所有集合中的并集
SDIFF key1 [key2]                 返回给定所有集合中的差集
SREM key member1 [member2]        移除集合中一个或多个成员

在这里插入图片描述

有序集合zset操作命令

Redis zxet有序集合是string类型元素的集合,且不允许重复的成员。每个元素都会关联一个double类型的分数(score)。Redis正是通过分数来为集合中的成员进行从小到大排序。有序集合的成员是唯一的,但分数却可以重复。

ZADD key score1 member1 [score2 member2]    向有序集合中添加一个或多个成员,或者更新已存在成员的分数
ZRANGE key start stop [WITHSCORES]          通过索引区间返回有序集合中指定区间内的成员
ZINCRBY key increment member                有序集合中对指定成员的分数加上增量increment
ZREM key member [member]                    移除有序集合中的一个或多个成员

在这里插入图片描述

新数据类型

BitMaps

本身是一个字符串,不是数据类型,数组的每个单元只能存放0和1,数组的下标在Bitmaps叫做偏移量。
节省空间,一般存储活跃用户比较多
第一次初始化bitmaps,如果偏移量比较大,那么整个初始化过程执行会比较慢,还可能会造成redis的堵塞。

setbit key offset value        设置Bitmaps中某个偏移量的值(01) 偏移量从0开始
getbit key offset              获取Bitmaps中某个偏移量的值
bitcount key (start end)       统计字符串从start到end字节比特值为1的数量
                              (一个字节是8位,例如bitcount user 1 2,就是从第一个字节到第二个字节,
                              换成偏移量是第8位到22位中1的个数)
                              
bitop and(or/not/xor) destkey key[key...]    复合操作,交并非异或,结果保存到destkey

HyperLogLog

基数:例如{1,3,5,7,9,1,3},基数集是:{1,3,5,7,9},基数是5。
1.统计网页中页面访问量
2.只会根据输入元素来计算基数,而不会储存输入元素本身,不能像集合那样,返回输入的各个元素。
3.基数估计是在误差可接受的范围内,快速计算(不重复元素的结算)。

pfadd key element [element...]            添加指定元素到hyperloglog中
pfcount key                            计算key的近似基数
pfmerge destkey sourcekey sourcekey    一个或多个key合并后的结果存在另一个key

Geographic

提供经纬度设置,查询范围,距离查询等。

geoadd key longitude latitude member [longitude latitude member...]    添加地理位置(经纬度名称)
geopos key member                       获取指定地区的坐标值
geodist key member1 member2 (m km ft mi)获取两个位置的直线距离(m米,km千米,mi英里,ft英尺,默认m)
georadius key longitude latitude radius (m km ft mi)以给定的经纬度为中心,找出某一半径内的元素

通用命令

KEYS pattern        查看所有符合给定模式(pattern)的key
EXISTS key          检查给定key是否存在
TYPE key            返回key所存储值的类型
TTL key             返回给定key的剩余生存时间(TTL,time to live,以秒为单位
DEL key             该命令用在key存在时删除key

使用Spring Data Redis操作Redis

导入maven坐标

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Spring Data Redis中提供了一个高度封装的类:RedisTemplate,针对jedis客户端中大量API进行了归类封装,将统一类型操作封装为operation接口,具体分类如下:
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型数据操作
ListOperations:针对list类型的数据操作

配置:

redis:
  host: localhost
  port: 6379
  database: 0 #操作的是0号数据库,不写的话默认是0号数据库
  jedis:
    #Redis连接池配置
    pool:
      max-active: 16 #最大连接数
      max-wait: 1ms #连接池最大连接阻塞时间
      max-idle: 5 #连接池中最大空闲连接
      min-idle: 0 #连接池中最小空闲连接

配置Redis配置类RedisConfig:

@Configuration
@EnableCaching //启用缓存
public class RedisCacheConfig extends CachingConfigurerSupport{

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory){
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(factory);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

例子:

@Autowired
private RedisTemplate redisTemplate;

/**
 * 操作String类型数据
 */
@Test
public void testString() {
    redisTemplate.opsForValue().set("city123","beijing");

    String value = (String) redisTemplate.opsForValue().get("city123");
    System.out.println(value);
    //设置key-value,10s后过期
    redisTemplate.opsForValue().set("key1","value1",10l, TimeUnit.MICROSECONDS);

    //只有在key不存在时设置key的值 判断key是否存在,存在则返回false;不存在返回true并设置key的值
    Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("city123", "nanjing");
    System.out.println(aBoolean);
}

/**
 * 操作Hash类型数据
 */
@Test
public void testHash(){
    HashOperations hashOperations = redisTemplate.opsForHash();
    //存值
    hashOperations.put("002","name","xiaoming");
    hashOperations.put("002","age","18");
    hashOperations.put("002","address","wuhan");
    //取值
    String name = (String) hashOperations.get("002", "name");
    System.out.println(name);
    //获得hash结构中的所有字段
    Set keys = hashOperations.keys("002");
    for (Object key:keys){
        System.out.println(key);
    }
    //获取hash结构中的所有值
    List values = hashOperations.values("002");
    for (Object value:values){
        System.out.println(value);
    }
}

/**
 * 操作list类型的数据
 */
@Test
void testList() {
    ListOperations listOperations = redisTemplate.opsForList();
    //存值
    listOperations.leftPush("mylist","a");
    listOperations.leftPushAll("mylist","b","c","d");
    //取值
    List<String> mylist = listOperations.range("mylist", 0, -1);
    for (String value:mylist){
        System.out.println(value);
    }
    //获得队列长度llen
    Long size = listOperations.size("mylist");
    int intValue = size.intValue();
    for (int i = 0; i < intValue; i++) {
        //出队列
        String rightPop = (String) listOperations.rightPop("mylist");
        System.out.println(rightPop);
    }
}

/**
 * 操作set类型的数据
 */
@Test
public void testSet() {
    SetOperations setOperations = redisTemplate.opsForSet();
    //存值
    setOperations.add("myset","a","b","c","d");
    //取值
    Set<String> myset = setOperations.members("myset");
    for (String o : myset) {
        System.out.println(o);
    }
    //删除成员
    setOperations.remove("myset","a","b");
}

/**
 * 操作ZSet类型的数据
 */
@Test
public void testZSet() {
    ZSetOperations zSetOperations = redisTemplate.opsForZSet();
    //存值
    zSetOperations.add("myZset","a",10.0);
    zSetOperations.add("myZset","b",11.0);
    zSetOperations.add("myZset","c",12.0);
    zSetOperations.add("myZset","a",13.0);
    //取值
    Set<String> myzset = zSetOperations.range("myZset", 0, -1);
    for (String s : myzset) {
        System.out.println(s);
    }
    //修改分数
    zSetOperations.incrementScore("myZset","a",20.0);
    //删除成员
    zSetOperations.remove("myZset","a");
    zSetOperations.remove("myZset","b");
}

/**
 * 通用操作
 */
@Test
public void testCommon(){
    //获取Redis中所有的key
    Set keys = redisTemplate.keys("*");
    for (Object key : keys) {
        System.out.println(key);
    }
    //判断某个key是否存在
    Boolean hasKey = redisTemplate.hasKey("myset");
    System.out.println(hasKey);
    //删除指定key
    redisTemplate.delete("myset");
    //获取指定key对应的value的数据类型
    DataType dataType = redisTemplate.type("myZset");
    System.out.println(dataType.name());
}

事务操作

  • 单独的隔离操作
  • 事务中的所有命令都会序列化
  • 按顺序执行
  • 执行的过程中,不会被其他命令请求所打断

Redis事务三大特性

单独的隔离操作:事务中的所有命令都会序列化、按顺序执行。事务在执行过程中,不会被其他客户端发送来的命令请求所打断。
没有隔离级别:队列中的命令没有提交之前都不会实际被执行,因为事务事务提交前任何指令都不会别实际执行。
不保证原子性:事务中如果有一条命令执行失败,其后的命令仍然会被执行,不会回滚。

sql的事务特性,为acid,一致性,隔离性,原子性,持久性
Redis事务的主要作用是串联多个命令防止别的命令插队
三个主要命令:

multi                组队阶段,还未执行
exec                 执行阶段,将multi的队列放到exec中
discard              放弃multi在队列中的值

从输入multi命令开始,输入的命令都会进入命令队列中,但不会执行,直到输入exec后,Redis会将之前的命令队列中的命令一次执行。
组队的过程中可以通过discard来放弃组队。
在这里插入图片描述

事务的错误处理:组队的时候失败,则执行的时候也会失败,所有命令都不会成功;
组队的时候成功,执行时出错,那么出错指令执行失败,其他命令会成功;

悲观锁和乐观锁

悲观锁:不能同时进行操作,对数据执行操作前会上锁,防止其他人操作。
乐观锁:给数据加上版本,同步更新数据及版本号,可以多人操作。每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

命令:

watch key1 [key2...]      乐观锁,在执行multi之前,先执行watch可以监视一个或多个key,
                          如果在事务执行之前key被其他命令所改动,那么事务将被打断。
                          
flushdb                   清空数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值