在Java中操作Redis(详细-->从环境配置到代码实现)

在Java中操作Redis

1、介绍

Redis 的Java客户端很多,官方推荐的有三种:

  • Jedis

  • Lettuce

  • Redisson

Spring对Redis客户端进行了整合,提供了Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即spring-boot-starter-data-redis

2、Jedis

Jedis的maven坐标:

     <!--redis-->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.8.0</version>
    </dependency>

使用Jedis操作Redis的步骤:

  1. 获取连接
  2. 执行操作关闭连接
  3. 关闭连接

编写一个测试类测试redis:

package com.mannor.jedisdemo;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;

@SpringBootTest
class JedisDemoApplicationTests {

    @Test
    void contextLoads() {

        //1. 获取连接
        Jedis jedis = new Jedis("localhost", 6379);
        //2. 执行操作关闭连接
        jedis.set("name", "mannor");

        //3. 关闭连接
        jedis.close();
    }
}

在此之前,需要将Redis服务启动起来redis-server.exe

程序运行前:

image-20230812220121965

测试项目运行后:

image-20230812220213860

测试其他:

package com.mannor.jedisdemo;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;

import java.util.Set;

@SpringBootTest
class JedisDemoApplicationTests {

    /**
     * 使用jedis操作Redis
     */
    @Test
    void contextLoads() {

        //1. 获取连接
        Jedis jedis = new Jedis("localhost", 6379);
        //2. 执行操作关闭连接
        jedis.set("name", "mannor");//设置
        String name = jedis.get("name");//获取
        System.out.println(name);
        jedis.del("name");//删除

        jedis.hset("myhash","addr","beijing");//设置哈希表值
        String hget = jedis.hget("myhash", "addr");//获取哈希表
        System.out.println(hget);

        Set<String> keys = jedis.keys("*");//获取所有Redis的数据
        for(String key:keys){
            System.out.println(key);
        }
        //3. 关闭连接
        jedis.close();
    }

}

测试项目源码:上述测试项目的源码

3、Spring Data Redis

在Spring Boot项目中,可以使用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类型的数据操作

yml配置文件:

spring:
  application:
    name: springdataredis_demo
  #Redis相关配置
  redis:
    host: localhost
    port: 6379
    #password: 123456
    database: 0 #操作的是0号数据库(redis存在0-15号数据库(默认),在命令中使用select来切换)
    jedis:
      #Redis连接池配置
      pool:
        max-active: 8 #最大连接数
        max-wait: 1ms #连接池最大阻塞等待时间 
        max-idle: 4 #连接池中的最大空闲连接
        min-idle: 0 #连接池中的最小空闲连接

在获取到RedisTemplate对象执行下列语句:

redisTemplate.opsForValue().set("city","beijing");

输出:image-20230812225658840

原因:RedisTemplate在操作Redis数据库的时候,将key做了一个序列化,上述结果就是序列化的结果,为了解决这个问题就要配置一个配置类:

package com.itheima.config;

import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * Redis配置类
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {

        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();

        //默认的Key序列化器为:JdkSerializationRedisSerializer
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        redisTemplate.setConnectionFactory(connectionFactory);

        return redisTemplate;
    }
}

对于接下类的在java中对Redis的操作,我们可以参照Redis中的常用命令

3.1、对String的操作

(ValueOperations接口)示例:

@SpringBootTest
class SpringDataRedisApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 操作String类型的数据
     */
    @Test
    void contextLoads() {
		//redisTemplate.opsForValue().set("mannor" ,"rediaz");
        String mannor = (String) redisTemplate.opsForValue().get("mannor");
        System.out.println(mannor);
        redisTemplate.opsForValue().set("k1", "v1", 10L, TimeUnit.SECONDS);
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent("mannor1", "mannor");
        System.out.println(aBoolean);
    }
}

3.2、对哈希类型数据的操作

@SpringBootTest
class SpringDataRedisApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 操作hash类型的数据
     */
    @Test
    public void hashTest() {
        HashOperations hashOperations = redisTemplate.opsForHash();
        //存
        hashOperations.put("002", "name", "zhangsan");
        hashOperations.put("002", "age", "20");
        hashOperations.put("002", "addr", "beijing");

        //取
        Object age = hashOperations.get("002", "age");
//        System.out.println((String) age);

        //获取所有字段
        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);
        }
    }

}

3.3、对list的操作

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 操作list类型的数据
     */
    @Test
    public void listTest() {
        ListOperations listOperations = redisTemplate.opsForList();
        //存
        listOperations.leftPush("list", "00");
        listOperations.leftPushAll("list", "01", "02", "03");

        //取值
        List list = listOperations.range("list", 0, -1);
        for (Object val : list) {
            System.out.println(val);
        }
        System.out.println("------------------------------------------------------------");
        //获取长度来遍历
        Long size = listOperations.size("list");
        for (int i = 0; i < size; i++) {
            //出队列
            String element = (String) listOperations.rightPop("list");
            System.out.println(element);
        }

3.4、对set类型的操作

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 操作Set类型的数据
     */
    @Test
    public void testSet() {
        SetOperations setOperations = redisTemplate.opsForSet();

        //存值
        setOperations.add("myset", "a", "b", "c", "a");

        //取值
        Set<String> myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }

        //删除成员
        setOperations.remove("myset", "a", "b");

        //取值
        myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }

    }

3.5、对 ZSet类型的数据(有序集合)

    @Autowired
    private RedisTemplate redisTemplate;

/** 
 * 操作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", "b", 20.0);

    //取值
    myZset = zSetOperations.range("myZset", 0, -1);
    for (String s : myZset) {
        System.out.println(s);
    }

    //删除成员
    zSetOperations.remove("myZset", "a", "b");

    //取值
    myZset = zSetOperations.range("myZset", 0, -1);
    for (String s : myZset) {
        System.out.println(s);
    }
}

3.6、通用类型的操作

     @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 通用操作,针对不同的数据类型都可以操作
     */
    @Test
    public void testCommon() {
        //获取Redis中所有的key
        Set<String> keys = redisTemplate.keys("*");
        for (String key : keys) {
            System.out.println(key);
        }

        //判断某个key是否存在
        Boolean itcast = redisTemplate.hasKey("itcast");
        System.out.println(itcast);

        //删除指定key
        redisTemplate.delete("myZset");

        //获取指定key对应的value的数据类型
        DataType dataType = redisTemplate.type("myset");
        System.out.println(dataType.name());

    }

测试项目源代码:https://gitee.com/rediaz/note-management/tree/master/Regis/SpringDataRedis

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
本项目详细介绍请看:http://www.sojson.com/shiro (强烈推荐) Demo已经部署到线上,地址是http://shiro.itboy.net, 管理员帐号:admin,密码:sojson.com 如果密码错误,请用sojson。 PS:你可以注册自己的帐号,然后用管理员赋权限给你自己的帐号,但是,每20分钟会把数据初始化一次。建议自己下载源码,让Demo跑起来,然后跑的更快,有问题加群解决。 声明: 本人提供这个Shiro + SpringMvc + Mybatis + Redis 的Demo 本着学习的态度,如果有欠缺和不足的地方,给予指正,并且多多包涵。 “去其糟粕取其精华”。如果觉得写的好的地方就给个赞,写的不好的地方,也请多多包涵。 使用过程: 1.创建数据库。 创建语句 :tables.sql 2.插入初始化数据 插入初始化数据:init.data.sql 3.运行。 管理员帐号:admin 密码:sojson ps:定时任务的sql会把密码改变为sojson.com 新版本说明:http://www.sojson.com/blog/164.html 和 http://www.sojson.com/blog/165.html 主要解决是之前说的问题:Shiro 教程,关于最近反应的相关异常问题,解决方法合集。 项目在本页面的附件提取。 一、Cache配置修改。 配置文件(spring-cache.xml )已经修改为如下配置: <!-- redis 配置,也可以把配置挪到properties配置文件,再读取 --> <!-- 这种 arguments 构造的方式,之前配置有缺点。 这里之前的配置有问题,因为参数类型不一致,有时候jar和环境的问题,导致参数根据index对应,会处理问题, 理论上加另一个 name,就可以解决,现在把name 和type都加上,更保险。 --> 二、登录获取上一个URL地址报错。 当没有获取到退出前的request ,为null 的时候会报错。在(UserLoginController.java )135行处有所修改。 /** * shiro 获取登录之前的地址 * 之前0.1版本这个没判断空。 */ SavedRequest savedRequest = WebUtils.getSavedRequest(request); String url = null ; if(null != savedRequest){ url = savedRequest.getRequestUrl(); } /** * 我们平常用的获取上一个请求的方式,在Session不一致的情况下是获取不到的 * String url = (String) request.getAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE); */ 三、删除了配置文件的cookie写入域的问题。 在配置文件里(spring-shiro.xml )的配置有所修改。 <!-- 会话Cookie模板 --> <!--cookie的name,我故意取名叫xxxxbaidu --> <!--cookie的有效时间 --> <!-- 配置存储Session Cookie的domain为 一级域名 --> 上面配置是去掉了 Session 的存储Key 的作用域,之前设置的.itboy.net ,是写到当前域名的 一级域名 下,这样就可以做到N 个 二级域名 下,三级、四级....下 Session 都是共享的。 <!-- 用户信息记住我功能的相关配置 --> <!-- 配置存储rememberMe Cookie的domain为 一级域名 --> <!-- 30天时间,记住我30天 --> 记住我登录的信息配置。和上面配置是一样的道理,可以在相同 一级域名 下的所有域名都可以获取到登录的信息。 四、简单实现了单个帐号只能在一处登录。 我们在其他的系统可以看到,单个帐号只允许一人使用,在A处登录了,B处再登录,那A处就被踢出了。如下图所示。 但是此功能不是很完美,当A处被踢出后,再重新登录,这时候B处反应有点慢,具体我还没看,因为是之前加的功能,现在凌晨了,下次我有空再瞧瞧,同学你也可以看看,解决了和我说一声,我把功能修复。 五、修复功能(BUG) 1.修复权限添加功能BUG。 之前功能有问题,每当添加一个权限的时候,默认都给角色为“管理员”的角色默认添加当前新添加的权限。这样达到管理员的权限永远是最大的。由于代码有BUG ,导致所有权限删除了。现已修复。 2.修复项目只能部署到Root目录下的问题。 问题描述:之前项目只能部署到Root 下才能正常运行,目前已经修复,可以带项目路径进行访问了,之前只能这样访问,http://localhost:8080 而不能http://localhost:8080/shiro.demo/ 访问,目前是可以了。 解决方案:在 FreeMarkerViewExtend.java 33行处 增加了BasePath ,通过BasePath 来控制请求目录,在 Freemarker 可以自由使用,而 JSP 是直接在 JSP 获取BasePath 使用。 解决后遗症:因为我们的权限是通过URL 来控制的,那么增加了项目的目录,导致权限不能正确的判断,再加上我们的项目名称(目录)可以自定义,导致更不好判断。 后遗症解决方案:PermissionFilter.java 50行处 解决了这个问题,详情请看代码和注释,其实就是replace 了一下。 HttpServletRequest httpRequest = ((HttpServletRequest)request); /** * 此处是改版后,为了兼容项目不需要部署到root下,也可以正常运行,但是权限没设置目前必须到root 的URI, * 原因:如果你把这个项目叫 ShiroDemo,那么路径就是 /ShiroDemo/xxxx.shtml ,那另外一个人使用,又叫Shiro_Demo,那么就要这么控制/Shiro_Demo/xxxx.shtml * 理解了吗? * 所以这里替换了一下,使用根目录开始的URI */ String uri = httpRequest.getRequestURI();//获取URI String basePath = httpRequest.getContextPath();//获取basePath if(null != uri && uri.startsWith(basePath)){ uri = uri.replace(basePath, ""); } 3.项目启动的时候报错,关于JNDI的错误提示。 其实也不是错,但是看着不舒服,所以还得解决这个问题。解决这个问题需要在web.xml 的开始部位加入以下代码。 spring.profiles.active dev spring.profiles.default dev spring.liveBeansView.mbeanDomain dev 4.项目Maven打包问题。 打包的时候,不同版本的 Eclipse 还有IDEA 会有打包打不进去Mapper.xml 文件,这个时候要加如下代码(群里同学提供的)。 src/main/java **/*.properties **/*.xml false 在 标签内加入即可,如果还是不能解决,那么请你加群(改名后)说明你的问题,有人会回答你。 5.Tomcat7以上在访问JSP页面的时候,提示JSTL错误。 这个错误是因为Tomcat7 没有 JSTL 的jar包,现在已经在项目pom.xml 增加了如下 jar 的引入管理。 javax.servlet jstl 1.2 javax.servlet jsp-api 2.0 provided 如果还是不能解决问题,请在官方群(群号:259217951)内搜索“jstl” 如图下载依赖包。
资源介绍 本资源为基于Spring Boot开发的漫画网站毕业设计项目,包含完整的源代码、论文以及详细的说明文档。该项目旨在为学生提供一个实践Spring Boot框架的机会,并通过开发一个漫画网站,实现对漫画资源的展示、分类、搜索以及用户交互等基本功能。 在源代码方面,项目结构清晰,模块划分合理,易于理解与二次开发。采用了Spring Boot作为后端框架,整合了MyBatis、Spring Security等常用技术,实现了用户认证、权限控制、数据持久化等功能。前端则采用了HTML、CSS和JavaScript等技术,保证了页面的美观与交互性。同时,项目还使用了Redis进行缓存优化,提高了系统的响应速度。 论文部分详细阐述了项目的背景、意义、相关技术选型、设计思路以及实现过程,对于理解项目整体架构和细节实现具有重要的参考价值。此外,论文还对项目的亮点和创新点进行了深入的剖析,展现了学生在项目开发过程的思考与探索。 说明文档则对项目的关键模块、接口以及数据库设计进行了详细的解释,为后续的维护和二次开发提供了便利。文档还包括了项目的运行环境和依赖配置等信息,方便用户快速搭建项目环境。 总的来说,本资源不仅适合作为毕业设计的参考项目,也适合有一定Java Web开发基础的开发者进行学习和实践。通过该项目,开发者可以深入了解Spring Boot框架的应用以及漫画网站的开发流程,同时也可以根据自己的需求进行二次开发和定制,实现更多个性化的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曼诺尔雷迪亚兹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值