iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >spring-data-redis连接操作redis的实现
  • 132
分享到

spring-data-redis连接操作redis的实现

2024-04-02 19:04:59 132人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

Java连接Redis的客户端有很多,其中比较常用的是Jedis. (参考:redis client) spring-data-redis则是对Jedis进行了高度封装,使用起来非常

Java连接Redis的客户端有很多,其中比较常用的是Jedis. (参考:redis client)

spring-data-redis则是对Jedis进行了高度封装,使用起来非常方便。下面就以代码为例说明spring-data-redis的使用。

整个项目使用Maven管理jar包,pom文件如下:


<project xmlns="Http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 
 <groupId>com.snow</groupId>
 <artifactId>redis-test</artifactId>
 <version>0.0.1</version>
 <packaging>jar</packaging>
 
 <name>redis-test</name>
 <url>http://maven.apache.org</url>
 
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <spring.version>4.3.2.RELEASE</spring.version>
  <slf4j.version>1.7.12</slf4j.version>
  <log4j.version>1.2.17</log4j.version>
  <junit.version>4.12</junit.version>
  <spring-data-redis.version>1.7.2.RELEASE</spring-data-redis.version>
 </properties>
 
 <dependencies>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>${spring.version}</version>
   <scope>test</scope>
  </dependency>
 
  <dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>2.5.0</version>
   <type>jar</type>
  </dependency>
  <dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-redis</artifactId>
   <version>${spring-data-redis.version}</version>
   <type>jar</type>
  </dependency>
 
  <!-- log -->
  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>${log4j.version}</version>
  </dependency>
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-log4j12</artifactId>
   <version>${slf4j.version}</version>
  </dependency>
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>${slf4j.version}</version>
  </dependency>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>${junit.version}</version>
   <scope>test</scope>
  </dependency>
 </dependencies>
</project>

主要用到的jia包是spring-context、spring-data-redis、jedis以及日志打印相关的三个jar包

配置spring-data-redis如下application-context-redis.xml:


    <!-- 配置方法见 //www.jb51.net/database/201311/254449.html -->
 <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
   <property name="maxTotal" value="500"/> <!-- 控制一个pool可分配多少个jedis实例 --> 
   <property name="maxIdle" value="100"/><!-- 最大能够保持idel状态的对象数 -->
   <property name="maxWaitMillis" value="1000"/><!-- 表示当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException --> 
   <property name="timeBetweenEvictionRunsMillis" value="30000"/><!-- 多长时间检查一次连接池中空闲的连接 -->
   <property name="minEvictableIdleTimeMillis" value="30000"/><!-- 空闲连接多长时间后会被收回, 单位是毫秒 -->
   <property name="testOnBorrow" value="true"/> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->
   <property name="testOnReturn" value="true"/> <!-- 当调用return Object方法时,是否进行有效性检查 -->
   <property name="testWhileIdle" value="true"/>
 </bean>
      
   <span style="white-space:pre"> </span><!-- 直连master -->
 <bean id="jedisConnectionFactory"
  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
  <constructor-arg ref="jedisPoolConfig" />
  <property name="hostName" value="${redis.hostName}" />
  <property name="port" value="${redis.port}" />
  <!-- <property name="passWord" value ="${redis.password}" /> -->
 </bean> 
    
    <span style="white-space:pre"> </span><bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" > 
     <span style="white-space:pre"> </span><property name="connectionFactory" ref="jedisConnectionFactory" />  
    <span style="white-space:pre"> </span></bean>

在配置文件中先配置一个连接池,然后配置一个connection工厂,最后配置bean redisTemplate,我们使用的class是StringRedisTemplate,从而决定我们后面的操作key及value都必须是String类型的。而通常我们希望将一个对象存入到redis中,这个时候可以将对象转为JSON字符串之后再存储,取出来的时候再将json字符串转换为对象。这种操作还是比较方便的,都有线程的jar包。除了StringRedisTemplate之外,我们还可以使用RedisTemplate类,这里暂不介绍。

在application-context-redis.xml这个配置文件中还需要用到redis的host和port信息,我们可以配置一个文件properties文件如下:redis.properties


redis.hostName=127.0.0.1
redis.port=6379

这个配置文件需要在application-contex.xml中加载,同时application-context.xml还需要加载application-context-redis.xml配置文件


 <bean id="dbPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="ignoreUnresolvablePlaceholders" value="true" />
  <property name="locations">
   <list>
    <value>classpath:redis.properties</value>
   </list>
  </property>
  <property name="fileEncoding" value="UTF-8" /><!-- 资源文件的编码 -->
 </bean> 
 <import resource="classpath:application-context-redis.xml" />  

接下来可以写个redis操作的接口


public interface RedisService { 
    public void setStr(String key, String value);    
    public String getStr(String key);    
    public void rPushList(String key, String value);
    public String lPopList(String key); 
    public void delkey(String key); 
}

接口实现如下:


@Service(value = "redisService")
public class RedisServiceImpl extends AbstractRedisDao<String, String> implements RedisService {
 
    @Override
    public void setStr(String key, String value) {
        getRedisTemplate().opsForValue().set(key, value);
    }
 
    @Override
    public String getStr(String key) {
        return getRedisTemplate().opsForValue().get(key);
    }
 
    @Override
    public void rPushList(String key, String value) {
        getRedisTemplate().opsForList().rightPush(key, value);
 
    }
 
    @Override
    public String lPopList(String key) {
        return getRedisTemplate().opsForList().leftPop(key);
    }
    
    @Override
    public void delKey(String key) {
        getRedisTemplate().delete(key);
    }
}

在该实现中继承了一个AbstractRedisDao,这个主要是提供getRedisTemplate()函数,使我们能够调用在application-context-redis.xml中配置的redisTemplate bean实例


public abstract class AbstractRedisDao<K, V> {
 
    @Autowired
    protected RedisTemplate<K, V> redisTemplate;
 
    // 设置redisTemplate
    public void setRedisTemplate(RedisTemplate<K, V> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
 
    public RedisTemplate<K, V> getRedisTemplate() {
        return redisTemplate;
    }
}

主要的程序都已经写完了,接下来可以用Junit写个单元测试对接口测试下。


public class RedisServiceTest extends AbstractUnitTest {
    private static final Logger logger = LoggerFactory.getLogger(RedisServiceTest.class);
 
    @Resource
    private RedisService redisService;
 
    @Test
    public void testSetStr() {
        String key = "test";
        String value = "valuetest";
        redisService.setStr(key, value);
    }
 
    @Test
    public void testGetStr() {
        String key = "test";
        String value = redisService.getStr(key);
        logger.info("The value is {}", value);
    }
 
    @Test
    public void testRPushList() {
        String key = "list";
        for (int i = 0; i < 10; i++) {
            redisService.rPushList(key, String.valueOf(i));
        }
    }
       
    @Test
    public void testLPopList() {
        String key = "list";
        
        for(int i = 0; i < 9; i++) {
            String value = redisService.lPopList(key);
            logger.info("lpop value is {}", value);
        }
    }
    
    @Test
    public void testDelKey() {
        String key = "list";
        redisService.delKey(key);
    } 
}

在这个测试类中,为了能够运行这些测试函数,需要对所有的bean进行实例化,这个过程是在 AbstractUnitTest中实现的,代码如下:


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application-context.xml"})
public abstract class AbstractUnitTest {
    private static final Logger logger = LoggerFactory.getLogger(AbstractUnitTest.class);
 
//    @Test
//    public void stub() {
//        logger.info("msg from abstract unit test, just ignore this.");
//    }
 
    @After
    public void teardown() throws InterruptedException {
        logger.info("unit test complete.");
        TimeUnit.MILLISECONDS.sleep(500);// 因为有些测试是需要异步插入操作记录的,sleep一下等待线程结束
    } 
}

AbstractUnitTest类可以作为测试spring的一个通用类。

主要的代码就这些了,运行下可以看到结果是没有问题的。下面我摘抄一段打印输出说明一个问题:

016-08-02 20:43:16,608 DEBUG RedisConnectionUtils:125 - Opening RedisConnection
2016-08-02 20:43:16,609 DEBUG RedisConnectionUtils:205 - Closing Redis Connection
2016-08-02 20:43:16,610  INFO RedisServiceTest:54 - lpop value is 0
2016-08-02 20:43:16,610 DEBUG RedisConnectionUtils:125 - Opening RedisConnection
2016-08-02 20:43:16,611 DEBUG RedisConnectionUtils:205 - Closing Redis Connection
2016-08-02 20:43:16,611  INFO RedisServiceTest:54 - lpop value is 1
2016-08-02 20:43:16,611 DEBUG RedisConnectionUtils:125 - Opening RedisConnection
2016-08-02 20:43:16,611 DEBUG RedisConnectionUtils:205 - Closing Redis Connection
2016-08-02 20:43:16,612  INFO RedisServiceTest:54 - lpop value is 2
2016-08-02 20:43:16,612 DEBUG RedisConnectionUtils:125 - Opening RedisConnection
2016-08-02 20:43:16,612 DEBUG RedisConnectionUtils:205 - Closing Redis Connection
2016-08-02 20:43:16,612  INFO RedisServiceTest:54 - lpop value is 3
2016-08-02 20:43:16,612 DEBUG RedisConnectionUtils:125 - Opening RedisConnection
2016-08-02 20:43:16,613 DEBUG RedisConnectionUtils:205 - Closing Redis Connection
2016-08-02 20:43:16,613  INFO RedisServiceTest:54 - lpop value is 4
2016-08-02 20:43:16,613 DEBUG RedisConnectionUtils:125 - Opening RedisConnection
2016-08-02 20:43:16,613 DEBUG RedisConnectionUtils:205 - Closing Redis Connection
2016-08-02 20:43:16,613  INFO RedisServiceTest:54 - lpop value is 5
2016-08-02 20:43:16,613 DEBUG RedisConnectionUtils:125 - Opening RedisConnection
2016-08-02 20:43:16,614 DEBUG RedisConnectionUtils:205 - Closing Redis Connection
2016-08-02 20:43:16,614  INFO RedisServiceTest:54 - lpop value is 6
2016-08-02 20:43:16,614 DEBUG RedisConnectionUtils:125 - Opening RedisConnection
2016-08-02 20:43:16,614 DEBUG RedisConnectionUtils:205 - Closing Redis Connection
2016-08-02 20:43:16,618  INFO RedisServiceTest:54 - lpop value is 7
2016-08-02 20:43:16,618 DEBUG RedisConnectionUtils:125 - Opening RedisConnection
2016-08-02 20:43:16,618 DEBUG RedisConnectionUtils:205 - Closing Redis Connection
2016-08-02 20:43:16,618  INFO RedisServiceTest:54 - lpop value is 8
2016-08-02 20:43:16,618  INFO AbstractUnitTest:34 - unit test complete.

这段输出是运行testLPopList得到的,这里面opening RedisConnection进行了9次,然后又Closing Redis Connection 9次,这是不是说每次执行redis操作都需要创建一个连接,操作完然后又关闭连接呢?实际上不是这样的,阅读源代码我们可以发现我们对redis的所有操作都是通过回调execute函数执行的,其代码如下:


public <T> T execute(RedisCallback<T> action, boolean exposeConnection) {
    return execute(action, exposeConnection, false);
}
// execute实现如下:
// org.springframework.data.redis.core.RedisTemplate<K, V> --- 最终实现
public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
    Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
    Assert.notNull(action, "Callback object must not be null");
    RedisConnectionFactory factory = getConnectionFactory();
    RedisConnection conn = null;
    try {
        if (enableTransactionSupport) {
            // only bind resources in case of potential transaction synchronization
            conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
        } else {
            conn = RedisConnectionUtils.getConnection(factory);
        }
        boolean existinGConnection = TransactionSynchronizationManager.hasResource(factory);
        RedisConnection connToUse = preProcessConnection(conn, existingConnection);
        boolean pipelineStatus = connToUse.isPipelined();
        if (pipeline && !pipelineStatus) {
            connToUse.openPipeline();
        }
        RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
        T result = action.doInRedis(connToExpose);
        // close pipeline
        if (pipeline && !pipelineStatus) {
            connToUse.closePipeline();
        }
        // TODO: any other connection processing?
        return postProcessResult(result, connToUse, existingConnection);
    } finally {
        if (!enableTransactionSupport) {
            RedisConnectionUtils.releaseConnection(conn, factory);
        }
    }
}

这里面每次执行action.doInRedis(connToExpose)前都要调用RedisConnectionUtils.getConnection(factory);获得一个连接,进入RedisConnnectionUtils类中,getConnection(factory)最终调用的是doGetConnection(factory, true, false, enableTranactionSupport)这个函数。这个函数我们可以看下api文档,发现实际上并不是真的创建一个新的redis连接,它只是在connectFactory中获取一个连接,也就是从连接池中取出一个连接。当然如果connectFactory没有连接可用,此时如果allowCreate=true便会创建出一个新的连接,并且加入到connectFactory中。
基本上可以确定真实的情况是spring-data-redis已经帮我们封装了连接池管理,我们只需要调用一系列操作函数即可,这给操作redis带来了极大的方便。

最后附上本文源代码:redis-test

到此这篇关于spring-data-redis连接操作redis的实现的文章就介绍到这了,更多相关spring-data-redis连接操作redis内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: spring-data-redis连接操作redis的实现

本文链接: https://www.lsjlt.com/news/130454.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • spring-data-redis连接操作redis的实现
    Java连接redis的客户端有很多,其中比较常用的是Jedis. (参考:redis client) spring-data-redis则是对Jedis进行了高度封装,使用起来非常...
    99+
    2022-11-12
  • spring-data-redis连接操作redis的实现方法
    本篇内容介绍了“spring-data-redis连接操作redis的实现方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java连接re...
    99+
    2023-06-20
  • Spring-data-redis操作redis知识总结
    什么是spring-data-redisspring-data-redis是spring-data模块的一部分,专门用来支持在spring管理项目对redis的操作,使用java操作redis最常用的是使用jedis,但并不是只有jedis...
    99+
    2023-05-31
    spring data redis
  • 在spring时使用RedisTemplate如何实现连接并操作Redis
    在spring时使用RedisTemplate如何实现连接并操作Redis?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。事务需要开启enableTransact...
    99+
    2023-05-31
    spring redistemplate redis
  • python redis的连接及相关操作
    redis连接、及存取值 import redis r = redis.Redis(host="192.168.2.22",port=6379,db=2,password= "redis") r.set("name","Delia") ...
    99+
    2016-07-13
    python redis的连接及相关操作
  • python2.7连接操作redis的几种方法
    python版本:2.7首先需要先安装redis模块:wget https://pypi.python.org/packages/source/r/redis/redis-2.10.3.tar.gztar zxvf redis-2.10.3...
    99+
    2023-06-02
  • Spring Boot集成Redis实战操作
    最近在使用Spring Boot,发现其功能真是强大,可以快速的集成很多的组件功能,非常方便:今天就来介绍下,如何集成Redis。定义Redis 是一个高性能的key-value数据库。它支持存储的value类型很多,包括string(字符...
    99+
    2023-06-02
  • node连接redis的方法实现
    本篇文章介绍nodejs连接redis,以及redis的基本使用。 安装redis。 cnpm i redis -S 封装redis配置信息。 config/db.js // re...
    99+
    2023-02-27
    node连接redis node redis连接
  • RedisDesktopManager远程连接redis的实现
    目录1.下载RedisDesktopManager2.安装RedisDesktopManager3.建立远程连接1.下载RedisDesktopManager 直接去官网或者csdn...
    99+
    2022-11-13
  • Redis远程连接Redis客户端的实现步骤
    目录一 进入redis下的目录二 启动 redis服务三 连接客户端四 在windows本地中安装 redis可视化软件五 在linux关闭客户端六 设置防火墙规则:我的因为已经设置...
    99+
    2022-11-13
  • redis如何使用jedis连接并操作
    本篇文章给大家分享的是有关redis如何使用jedis连接并操作,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Redis是一个著名的key-value存储系统,也是nosql中...
    99+
    2023-05-31
    jedis
  • python连接读写操作redis的完整代码实例
    python读写操作redis数据库 redis有16个逻辑数据库(编号db0到db15),每个逻辑数据库数据是隔离的,默认db0。选择第n个逻辑数据库,命令select ...
    99+
    2023-01-07
    python连接redis python读写操作redis代码实例 redis-sentinel哨兵模式下Python操作redis redis-cluster(集群)模式下Python操作redis
  • Spring整合redis的操作代码
    目录导入坐标配置文件进行操作StringRedisTemplatejedis导入坐标 <dependency> <groupId>or...
    99+
    2022-11-13
  • Go实现Redis连接池方法
    目录一、什么是连接池,连接池有什么用 二、代码展示 一、什么是连接池,连接池有什么用 先看看别人是怎么介绍连接池的吧: 连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存...
    99+
    2022-11-12
  • Spring Boot中怎么利用Redis 实现缓存操作
    这期内容当中小编将会给大家带来有关Spring Boot中怎么利用Redis 实现缓存操作,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、缓存的应用场景二、更新缓存的策略三、运行 springboot-...
    99+
    2023-06-17
  • 在Java项目中使用Jedis如何实现连接并操作Redis
    在Java项目中使用Jedis如何实现连接并操作Redis?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一.   redis的安装下载源码,解压缩后编译源码...
    99+
    2023-05-31
    jedis redis java
  • 怎么用Java实现redis连接池
    这篇文章主要介绍“怎么用Java实现redis连接池”,在日常操作中,相信很多人在怎么用Java实现redis连接池问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用Jav...
    99+
    2022-10-18
  • Redis教程(十五):C语言连接操作代码实例
    在之前的博客中已经非常详细的介绍了Redis的各种操作命令、运行机制和服务器初始化参数配置。本篇博客是该系列博客中的最后一篇,在这里将给出基于Redis客户端组件访问并操作Redis服务器的代码示例。然而需...
    99+
    2022-06-04
    实例 语言 代码
  • java客户端中如何使用Jedis实现操作Redis Sentinel 连接池
    这篇文章给大家介绍java客户端中如何使用Jedis实现操作Redis Sentinel 连接池,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。pom.xml配置<dependency> <grou...
    99+
    2023-05-31
    jedis sentinel java
  • golang连接redis库及基本操作示例过程
    目录Redis介绍Redis支持的数据结构Redis应用场景准备Redis环境go-redis库安装连接V8新版本相关连接Redis哨兵模式连接Redis集群基本使用HValsset...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作