redis简单使用一

redis安装
1.现在地址 https://redis.io/download/,可以根据自己需求下载对应的版本,我目前使用的是 redis-5.0.14.tar.gz

2. 下载后上传到服务器的指定目录 (目录可以自定义)

3.解压安装

tar -zxvf redis-5.0.14.tar.gz

注意:安装前 需要安装gcc等环境

yum install -y gcc

进入 redis-5.0.14 目录下 执行 make install 进行安装

也可以指定安装目录 通过 make PREFIX = /usr/local/redis install 指定安装目录

4.安装成功后 ,后又提示输出,或者在你的目录下生成很多新的文件

5.修改配置文件进行启动

# 修改配置
        daemonize yes #设置为后台启动
        protected‐mode no #关闭保护模式,开启的话,只有本机才可以访问redis
        # 需要注释掉bind
        #bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户 端通过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可)

        # 启动服务
        src/redis‐server redis.conf

        # 验证启动是否成功
        ps ‐ef | grep redis

        # 进入redis客户端
        src/redis‐cli

        # 退出客户端
        quit

        # 退出redis服务:
        (1)pkill redis‐server
        (2)kill 进程号
        (3)src/redis‐cli shutdown

其他的使用参考 redis学习redis简单命令

redis在项目中的使用(Java客户端api使用)

由于目前我们项目使用的是springboot构建,所以api这里都是采用redisTemplate去使用的

依赖引入

        <!--缓存依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

序列化设置:


 ## 客户端的key ,value 序列化方式
@Configuration
public class RedisTemplateConfig {

    @Bean("redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(keySerializer());
        redisTemplate.setHashKeySerializer(keySerializer());
        redisTemplate.setValueSerializer(valueSerializer());
        redisTemplate.setHashValueSerializer(valueSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }


    private RedisSerializer<String> keySerializer() {
        return new StringRedisSerializer();
    }

    private RedisSerializer<Object> valueSerializer() {
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        //序列化所有类包括jdk提供的
        ObjectMapper objectMapper = new ObjectMapper();
        //设置序列化的域(属性,方法etc)以及修饰范围,Any包括private,public 默认是public的
        //ALL所有方位,ANY所有修饰符
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //enableDefaultTyping 原来的方法存在漏洞,2.0后改用如下配置
        //指定输入的类型
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL);
        //如果java.time包下Json报错,添加如下两行代码
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        serializer.setObjectMapper(objectMapper);
        return serializer;
    }
}
  1. String类型操作常用的api

@Slf4j(topic = "RdisTemplateTest")
@SpringBootTest(classes = {SpringbootCacheDemoApplication.class})
public class RdisTemplateTest{

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Test
    public void redisCommandStringTest(){
        // 设置 无过期时间的
        redisTemplate.opsForValue().set("test","abc");
        // 设置带过期时间的
        redisTemplate.opsForValue().set("name","yulang",10, TimeUnit.MINUTES);

        // 用value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量
        //offset 开始。不存在的 key 当作空白字符串处理。

        redisTemplate.opsForValue().set("name","abc",1);

        // 获取key的值
        Object name = redisTemplate.opsForValue().get("name");


        ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();

        valueOperations.set("name1","yulang1", Duration.ofMinutes(1));

        // bitmap 操作 可以用来统计某个用户是 那天是否签到了
        valueOperations.setBit("java",1,true);
        valueOperations.setBit("java",2,true);
        valueOperations.setBit("java",3,true);
        Boolean operationsBit = valueOperations.getBit("java", 6);
        log.info("{} - {} - {} -{}",valueOperations.getBit("java", 1),valueOperations.getBit("java", 2),valueOperations.getBit("java", 3),operationsBit);


        valueOperations.setBit("zhangsan",20230301,true);
        valueOperations.setBit("zhangsan",20230302,true);
        valueOperations.setBit("zhangsan",20230303,true);
        Boolean aBoolean = valueOperations.getBit("zhangsan", 20230304);
        // true 表示已经存在的记录
        log.info("aBoolean: {} ,20230302 -{} " ,aBoolean,valueOperations.getBit("zhangsan", 20230303) );


        // 使用的是 setNX 命令 存在的key 不会再次插入
        Boolean setIfAbsent = valueOperations.setIfAbsent("test", "new name");

        Boolean setIfAbsent2 = valueOperations.setIfAbsent("test1", "new name");

        log.info("setIfAbsent - setIfAbsent2 : {} - {}",setIfAbsent,setIfAbsent2);

        // set 存在key就重新更新 ,不存在的key不插入
        Boolean test1 = valueOperations.setIfPresent("test1", "333");
        Boolean test2 = valueOperations.setIfPresent("test2", "444");
        log.info("setIfAbsent - setIfAbsent2 : {} - {}",test1,test2);

        // 自增id操作
        Long increment = valueOperations.increment("LONG-ID");
        log.info("increment : {} - {}",increment,valueOperations.increment("LONG-ID"));

        // set批量设置(批量操纵无法设置每个key的过期时间), 批量操作也可使用 Pipelined 操作 ,命令跟灵活可以设置key过期时间
        Map<String,Object> map =new HashMap<>();
        map.put("demo","1");
        map.put("demo2","1");
        map.put("demo3","1");
        valueOperations.multiSet(map);
    }

    /**
     *  RedisPipelined 插入 不保证原子性
     * @author 余浪
     */
    private void testRedisPipelined() {
        RedisSerializer<Object> valueSerializer = (RedisSerializer<Object>) redisTemplate.getValueSerializer();

        List<Object> objectList = redisTemplate.executePipelined(new RedisCallback<String>() {

            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {

                RedisStringCommands redisStringCommands = connection.stringCommands();

                RedisSerializer<Object> valueSerializer = (RedisSerializer<Object>) redisTemplate.getValueSerializer();

                for (int  i=0 ;i < 100; i++){
                    byte[] serializeValue = valueSerializer.serialize("Pipelined——"+ i);
                    redisStringCommands.set((i+ "_key").getBytes(), serializeValue, Expiration.seconds(1000), RedisStringCommands.SetOption.UPSERT);
                }

                return null;
            }
        });

        log.info("objectList: 返回操作的数据");
    }
}
  1. hash类型操作

@Test
    public void redisCommandHashTest(){

        // hash 类型相关操作
        HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();


        String product_id = "123";
        // 存储一个商品的分类和品牌  无法单独设置设置过期时间
        hashOperations.put(product_id,"brand","华为");
        hashOperations.put(product_id,"category","5G手机");
        hashOperations.put(product_id,"specification","大内存");

        // 获取品牌的信息
        Object brand = hashOperations.get(product_id, "brand");

        // 获取这个产品下的所有的字段信息
        Map<Object, Object> objectMap = hashOperations.entries(product_id);

        log.info("brand : {}--- objectMap:{}",brand , objectMap );


        // 只能通过顶级key 设置一个统一的过期时间
        redisTemplate.expire(product_id,1000,TimeUnit.MINUTES);


        //批量操作 也可以通过Pipelined 进行操作
        Map<String,Object> map =new HashMap<>();
        map.put("price",120);
        map.put("name","ceshh");
        hashOperations.putAll(product_id,map);


        //判断 价格的属性 是否在 product_id 这个KEY中
        hashOperations.hasKey(product_id,"price");

        hashOperations.delete(product_id,"price");

        // 异步删除key
        redisTemplate.unlink(Arrays.asList(product_id));
    }

3.list常用操作

 @Test
    public void redisCommandListTest(){
        // list 集合操作
        ListOperations<String, Object> listOperations = redisTemplate.opsForList();

        String key = "productId";
        // 从右开始插入
        listOperations.rightPush(key,1);
        listOperations.rightPush(key,2);
        // lInsert 在key 该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插 入到该元素的前面还是后面
        //    Long rightPush(K key, V pivot, V value); api 默认是 AFTER (后面插入)
        // 在 1 后面插入 12 ,如果没有1这个value 则不插入
        listOperations.rightPush(key,1,12);

        // 批量插入
        listOperations.rightPushAll(key,2,3,4);

        // 获取指定索引的元素
        listOperations.index(key,1);

        // 从做开始插入
        listOperations.leftPush(key,99);

        // key 存在就插入 不存在不插入
        listOperations.leftPushIfPresent(key,88);
        
        
        // 从右边移出一个元素 原子操作 ,可以使用 这个做一些简单的队列
        Object rightPop = listOperations.rightPop(key);
    }

4.set操作

 @Test
    public void redisCommandSetTest(){

        //set 相关操作 不重复无序的元素
        SetOperations<String, Object> opsForSet = redisTemplate.opsForSet();

        String setKey ="SET-KEY";
        // 添加元素
        opsForSet.add(setKey,1,2,3,4);

        // 移出元素为 1 的元素
        opsForSet.remove(setKey,1);

        // 输出 2,3,4
        Set<Object> members = opsForSet.members(setKey);

        log.info("members1 : {}" ,members);

        // 判断元素是否存在
        Boolean member = opsForSet.isMember(setKey, 3);
        log.info("member : {}" ,member);

        String setKey2 ="SET-KEY2";
        Long add = opsForSet.add(setKey2, 2, 3, 4, 5, 6);
        log.info("members2 : {}" ,opsForSet.members(setKey2));


        List<String> list = Arrays.asList(setKey2,setKey);

        // 集合差集 第一个集合是大集合 - 第二个小集合 = 差集
        Set<Object> difference = opsForSet.difference(list);
        log.info("difference: {}",difference);

        // 集合的交集
        Set<Object> intersect = opsForSet.intersect(list);
        log.info("intersect: {}",intersect);

        // 属于a 或者属于 b 集合的数据 并集
        Set<Object> objects = opsForSet.union(list);
        log.info("objects: {}",objects);

        // 获取集合中元素个数
        Long size = opsForSet.size(setKey);
        log.info("size: {}",size);

        // 从集合中移出一个元素  可以使用这个 做抽奖的功能 
        Object pop = opsForSet.pop(setKey);
        log.info("pop: {} - {}",pop,opsForSet.members(setKey));
        
        // 批量移出 多个元素
        List<Object> objectList = opsForSet.pop(setKey, 2);
    }

5.zset使用

@Test
    public void redisCommandZsetTest(){
        // zset 有序的集合 不重复
        ZSetOperations<String, Object> opsForZSet = redisTemplate.opsForZSet();

        String zkey = "sort-key";
        opsForZSet.add(zkey,"java",99);
        opsForZSet.add(zkey,"php",80);
        opsForZSet.add(zkey,"golang",85);

        // 按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)
        // ZREVRANGE:按照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素
        Set<Object> objects = opsForZSet.range(zkey, 0, -1);
        log.info("objects: {} - {}",objects,objects.size());

        // 查询排名前三的书
        Set<Object> reverseRange = opsForZSet.reverseRange(zkey, 0, 2);

        // 给某个元素加上多少分
        Double java = opsForZSet.incrementScore(zkey, "java", 100);
        log.info("java: {} - {}",java,objects.size());


        // 获取某个元素的分数
        Double score = opsForZSet.score(zkey, "java");
        log.info("score: {} - {}",score,objects.size());

        // 删除某个元素
        opsForZSet.remove(zkey,"php");

        //[php, golang, java] - 3  unbounded
        Set<ZSetOperations.TypedTuple<Object>> tupleSet = opsForZSet.rangeByScoreWithScores(zkey, 0, 200);
        log.info("objectSet: {} - {}",tupleSet,tupleSet.size());

        Set<Object> rangeByScore = opsForZSet.rangeByScore(zkey, 80, 100);
        log.info("rangeByScore: {} - {}",rangeByScore,rangeByScore.size());

        // 获取元素的排名 从小到大
        Long rank = opsForZSet.rank(zkey, "java");
        log.info("rank: {} - {}",rank);


        String zkey2 = "sort-key2";
        opsForZSet.add(zkey2,"张三",99);
        opsForZSet.add(zkey2,"李四",80);

        //将 key1 和 key2 的合并的结果放到 新的key中
        opsForZSet.unionAndStore(zkey,zkey2,"new-key");
    }

6.geo 相关操作

 @Test
    public void redisCommandGEOTest(){
        GeoOperations<String, Object> geoOperations = redisTemplate.opsForGeo();

        String key = "cn";

        //  geoadd:添加地理位置的坐标。
        Map<Object,Point> stringPointMap = new HashMap<>();

        stringPointMap.put("wuhan",new Point(114.02919,30.58203));
        stringPointMap.put("beijing",new Point(116.23128,40.22077));
        stringPointMap.put("shanghai",new Point(121.48941,31.40527));
        stringPointMap.put("changsha",new Point(112.98626,28.25591));
        geoOperations.add(key,stringPointMap);


        //  geopos:获取地理位置的坐标。
        List<Point> wuchang = geoOperations.position(key, "wuhan");
        log.info("wuchang : {}" ,wuchang);

       // geodist:计算两个位置之间的距离。
        Distance distance = geoOperations.distance(key, "wuhan", "changsha");
        log.info("distance: {}" ,distance.getValue() + " - " + distance.getUnit());
        Distance distance1 = geoOperations.distance(key, "wuhan", "changsha", RedisGeoCommands.DistanceUnit.KILOMETERS);
        log.info("distance1: {}" ,distance1.getValue() + " - " + distance1.getUnit());

        //georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。


        // 定义返回结果参数,如果不指定默认只返回content即保存的member信息
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs
                .newGeoRadiusArgs().includeDistance().includeCoordinates()
                .sortAscending()
                .limit(100);
        
        GeoResults<RedisGeoCommands.GeoLocation<Object>> geoResults = geoOperations.radius(key, "wuhan",
                new Distance(3000, RedisGeoCommands.DistanceUnit.KILOMETERS),args);
        log.info("geoResults : {}", geoResults.getContent() + "-- " + geoResults.getAverageDistance().getValue());

       //georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
        GeoResults<RedisGeoCommands.GeoLocation<Object>> geoResults1 = geoOperations.radius(key, new Circle(new Point(114.02919,30.58203),
                new Distance(1000,Metrics.KILOMETERS)),args);
        log.info("geoResults1 : {}", geoResults1.getContent() + "-- " + geoResults1.getAverageDistance().getValue());

        //geohash:返回一个或多个位置对象的 geohash 值
        List<String> jiangxia = geoOperations.hash(key, "shanghai");

    }

7.lua的简单操作

@Test
    public void redisLuaScript(){

        // 确保操作的原子性
        String script = "local isExists = redis.call('exists',KEYS[1]) \n"+
                "if isExists == 1 then \n" +
                " redis.call('DEL',KEYS[1]) \n" +
                " redis.call('INCR', KEYS[2]) \n" +
                " redis.call('EXPIRE', KEYS[2], ARGV[1]) \n" +
                " return 1 \n" +
                " else \n"+
                " redis.call('INCR', KEYS[2]) \n" +
                " redis.call('EXPIRE', KEYS[2], ARGV[1]) \n" +
                " return 0 end";

        // 对应的key参数 按照 key[1],key[2] 顺序添加
        List<String> listKeys = Arrays.asList("user","user:lock");

        // 加载lua脚本
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<Long>(script,Long.class);
        // 执行lua脚本  参数1: script脚本, key的集合, 参数集合
        Long resultLong = redisTemplate.execute(redisScript, listKeys, 1000);

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个用于创建独立的、基于Spring的应用程序的框架,而Redis是一个开源的内存数据存储系统。结合使用Spring Boot和Redis可以实现高效的数据缓存和持久化。 在Spring Boot中使用Redis,首先需要在项目的pom.xml文件中添加Redis的依赖。然后,在application.properties或application.yml文件中配置Redis的连接信息,包括主机名、端口号、密码等。 接下来,可以通过使用Spring Data Redis来简化对Redis的操作。Spring Data Redis提供了一系列的注解和模板类,可以方便地进行数据的读取、写入和删除等操作。 以下是一个简单的示例,演示了如何在Spring Boot中使用Redis: 1. 添加依赖: 在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 配置Redis连接信息: 在application.properties或application.yml文件中添加以下配置: ```properties spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= ``` 3. 创建Redis操作类: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; @Component public class RedisUtil { @Autowired private RedisTemplate<String, Object> redisTemplate; public void set(String key, Object value) { redisTemplate.opsForValue().set(key, value); } public Object get(String key) { return redisTemplate.opsForValue().get(key); } public void delete(String key) { redisTemplate.delete(key); } } ``` 4. 使用Redis操作类: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @Autowired private RedisUtil redisUtil; @GetMapping("/user/{id}") public User getUser(@PathVariable String id) { // 先从缓存中获取数据 User user = (User) redisUtil.get("user:" + id); if (user == null) { // 如果缓存中不存在,则从数据库中获取数据 user = userService.getUserById(id); // 将数据存入缓存 redisUtil.set("user:" + id, user); } return user; } } ``` 以上示例中,我们创建了一个RedisUtil类来封装对Redis的操作,然后在UserController中使用RedisUtil来实现对用户数据的缓存。当请求用户数据时,先从缓存中获取,如果缓存中不存在,则从数据库中获取,并将数据存入缓存。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值