Redis入门与Spring整合Redis

1 Redis入门

1.1 关系型数据库与非关系型数据库

本部分内容参考:https://www.jianshu.com/p/fd7b422d5f93,非常详细。

关系型数据库:采用了关系模型来组织数据的数据库,通俗来讲就是二维表格样式的数据库。
非关系型数据库:指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。

1.2 Redis介绍

在这里插入图片描述
NoSQL:not only SQL,不只是数据库,有的按照键值对存储数据,有的按照文档,形式各异
Redis是按照键值对方式存储数据的。键都是String,值支持多种数据结构。

1.3 Redis持久化策略

https://www.redis.com.cn/redis-persistence.html
RDB(快照):把当前内存中的数据原原本本存到硬盘上
优点:恢复数据快
缺点:耗时
不适合实时做,适合每隔一段时间存一次

AOF(日志):将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍
优点:可以实时存储
缺点:要恢复数据,需要把指令都跑一遍,慢

1.4 Redis应用

缓存:有些数据访问非常频繁,放在内存里加快访问速度,可以用Redis实现
排行榜:热门帖子访问频繁,利用Redis放在内存里
计数器:如:帖子的浏览量
社交网络:点赞、点踩、关注

1.5 命令手册与下载安装

官网:https://redis.io/
在这里插入图片描述
中文官网:https://www.redis.com.cn/
Redis命令手册:https://www.redis.com.cn/commands.html

下载win版:https://github.com/microsoftarchive/redis
路径配置到环境变量
cmd

redis-cli
select 1#内置16个库,没有名字,用索引区分,0-15,默认选择第0个,可以自己选择一个库
flushdb#不想要数据了,刷新库,把内容刷没
#Redis里两个相连的单词用:隔开(代码里两个相连的单词用_隔开)
set test:count 1#存String类型数据
get test:count#取数据
incr test:count#+1
decr test:count#-1
hset test:user id 1#存Hash类型数据
hget test:user id#取Hash类型数据

#list数据:横向容器,左进右出,有序
#l表示left
lpush test:ids 101 102 103 #存数据
llen test:ids #看长度
lindex test:ids 0 #看某一个索引所对应的值
lrange test:ids 0 2 #查看一个范围内的值
#r表示right
rpop test:ids #从右侧取出一个值

#集合:无序,无重复数据
sadd test:teachers aaa bbb ccc ddd eee
scard test:teachers#统计
spop test:teachers#随机弹出一个数据
smembers test:teachers# 查看集合中的元素

#有序集合:给每个存的值附加一个分数,用分数排序
zadd test:students 10 aaa 20 bbb 30 ccc
zscore test:students ccc#查分数
zrank test:students ccc
zrange test:students 0 2

keys * #查看所有kry
keys test* #test开头的key
type test:user #查看key对应的值的类型
exists test:user #查看key是否存在
del test:user #删掉key
expire test:students 10#有效期10秒

2 Spring整合Redis

官网:https://spring.io/projects/spring-data-redis
在这里插入图片描述

2.1 引入依赖

https://mvnrepository.com/
在这里插入图片描述
在这里插入图片描述

Spring Boot整合的包,或者说是Spring整合的包,可以不用写version,因为当前pom是继承自某个父pom,父pom声明过这些版本,并做过兼容测试,不会出错
查看父pom:按住CTRL点击箭头所指
在这里插入图片描述
在这里插入图片描述
CTRL+F页面查找
在这里插入图片描述

2.2 配置Redis

2.2.1 application.properties

#Redis
spring.redis.database=11
spring.redis.port=6379
spring.redis.host=localhost

2.2.2 编写配置类

注意方法前要带@Configuration

@Configuration
public class RedisConfig {
    @Bean
    //要把哪个对象装回到容器中,就返回哪个对象
    //方法名就是Bean的名字
    //template要想访问数据库,需要建立连接。连接是由连接工厂创建的,所以要把工厂注入到template里
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        //序列化方式,或者说是数据转换的方式

        //设置key的序列化方式
        template.setKeySerializer(RedisSerializer.string());
        //设置value的序列化方式
        template.setValueSerializer(RedisSerializer.json());
        //设置hash的key的序列化方式
        template.setHashKeySerializer(RedisSerializer.string());
        //设置hash的value的序列化方式
        template.setHashValueSerializer(RedisSerializer.json());

        template.afterPropertiesSet();//设置完之后触发生效
        
        return template;
    }

}

2.3 访问Redis

写个测试类

1.测试类的头几行

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)

2.注入RedisTemplate
3.测试方法上面 @Test

在这里插入图片描述
application.properties里选的是第11个库,一开始啥都没有哈(有就flushdb一下)

2.3.1 访问各类数据类型

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class RedisTests {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testStrings(){
        String redisKey = "test:count";

        //存数据
        redisTemplate.opsForValue().set(redisKey, 1);
        //取数据
        System.out.println(redisTemplate.opsForValue().get(redisKey));
        System.out.println(redisTemplate.opsForValue().increment(redisKey));
        System.out.println(redisTemplate.opsForValue().decrement(redisKey));
    }
}

在这里插入图片描述
在这里插入图片描述
其他数据类型都大同小异,完整测试代码:

	@Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testStrings(){
        String redisKey = "test:count";

        //存数据
        redisTemplate.opsForValue().set(redisKey, 1);
        //取数据
        System.out.println(redisTemplate.opsForValue().get(redisKey));
        System.out.println(redisTemplate.opsForValue().increment(redisKey));
        System.out.println(redisTemplate.opsForValue().decrement(redisKey));
    }

    @Test
    public void tsetHashs(){
        String redisKey = "test:user";
        redisTemplate.opsForHash().put(redisKey, "id", 1);
        redisTemplate.opsForHash().put(redisKey, "username", "zhangsan");

        System.out.println(redisTemplate.opsForHash().get(redisKey, "id"));
        System.out.println(redisTemplate.opsForHash().get(redisKey,"username"));

    }

    @Test
    public void testLists(){
        String redisKey = "test:ids";

        redisTemplate.opsForList().leftPush(redisKey, 101);
        redisTemplate.opsForList().leftPush(redisKey, 102);
        redisTemplate.opsForList().rightPush(redisKey, 103);

        System.out.println(redisTemplate.opsForList().size(redisKey));
        System.out.println(redisTemplate.opsForList().range(redisKey, 0, 2));
        System.out.println(redisTemplate.opsForList().index(redisKey, 0));

        System.out.println(redisTemplate.opsForList().leftPop(redisKey));
        System.out.println(redisTemplate.opsForList().rightPop(redisKey));
        System.out.println(redisTemplate.opsForList().rightPop(redisKey));
    }

    @Test
    public void testSets(){
        String redisKey = "test:teachers";
        redisTemplate.opsForSet().add(redisKey, "张三", "李四", "王五");

        System.out.println(redisTemplate.opsForSet().size(redisKey));
        System.out.println(redisTemplate.opsForSet().members(redisKey));
        System.out.println(redisTemplate.opsForSet().pop(redisKey));
    }

    @Test
    public void testSortedSets(){
        String redisKey = "test:students";
        redisTemplate.opsForZSet().add(redisKey, "张三", 80);
        redisTemplate.opsForZSet().add(redisKey, "李四", 70);
        redisTemplate.opsForZSet().add(redisKey, "王五", 60);

        System.out.println(redisTemplate.opsForZSet().zCard(redisKey));
        System.out.println(redisTemplate.opsForZSet().score(redisKey,"张三"));
        System.out.println(redisTemplate.opsForZSet().rank(redisKey, "张三"));
        System.out.println(redisTemplate.opsForZSet().reverseRank(redisKey,"张三"));
    }

    @Test
    public void testKeys(){
        redisTemplate.delete("test:user");
        System.out.println(redisTemplate.hasKey("test:user"));

        redisTemplate.expire("test:students", 10, TimeUnit.SECONDS);
    }

2.3.2 多次访问同一个Key

在一段代码里,可能要访问Redis多次,可能每次访问都是同一个Redis Key,会有大量重复代码。这种情况下可以简化操作:

    //多次访问同一个Key
    @Test
    public void testBoundOperations(){
        String redisKey = "test:count";
        //对value操作就是BoundValueOperations,对Hash操作就是BoundHashOperations,以此类推
        BoundValueOperations operations = redisTemplate.boundValueOps(redisKey);
        operations.increment();
        System.out.println(operations.get());

    }

2.3.3 Redis事务管理

	//事务管理
    //Redis事务不满足ACID,因为不是关系型数据库
    //启动事务后,命令不会立刻执行,都存在队列里,直到提交事务,再从队列里取出命令一步步执行
    //所以,事务中间不要查询,要么在事务前面查,要么在事务后面查
    //编程式事务
    @Test
    public void testTransactional(){
        Object obj = redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                String redisKey = "test:tx";
                operations.multi();//启动事务
                operations.opsForSet().add(redisKey, "zhangsan ");
                System.out.println(operations.opsForSet().members(redisKey));
                operations.opsForSet().add(redisKey, "lisi");

                return operations.exec();//提交事务
            }
        });
        System.out.println(obj);

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值