日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

spring-data-redis連接操作redis的實現(xiàn)

瀏覽:12日期:2023-07-03 10:54:32

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以及日志打印相關(guān)的三個jar包

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

<!-- 配置方法見 //www.jb51.net/database/201311/254449.html --> <bean class='redis.clients.jedis.JedisPoolConfig'> <property name='maxTotal' value='500'/> <!-- 控制一個pool可分配多少個jedis實例 --> <property name='maxIdle' value='100'/><!-- 最大能夠保持idel狀態(tài)的對象數(shù) --> <property name='maxWaitMillis' value='1000'/><!-- 表示當borrow一個jedis實例時,最大的等待時間,如果超過等待時間,則直接拋出JedisConnectionException --> <property name='timeBetweenEvictionRunsMillis' value='30000'/><!-- 多長時間檢查一次連接池中空閑的連接 --> <property name='minEvictableIdleTimeMillis' value='30000'/><!-- 空閑連接多長時間后會被收回, 單位是毫秒 --> <property name='testOnBorrow' value='true'/> <!-- 當調(diào)用borrow Object方法時,是否進行有效性檢查 --> <property name='testOnReturn' value='true'/> <!-- 當調(diào)用return Object方法時,是否進行有效性檢查 --> <property name='testWhileIdle' value='true'/> </bean> <span style='white-space:pre'> </span><!-- 直連master --> <bean 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 > <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中,這個時候可以將對象轉(zhuǎn)為json字符串之后再存儲,取出來的時候再將json字符串轉(zhuǎn)換為對象。這種操作還是比較方便的,都有線程的jar包。除了StringRedisTemplate之外,我們還可以使用RedisTemplate類,這里暫不介紹。

在application-context-redis.xml這個配置文件中還需要用到redis的host和port信息,我們可以配置一個文件properties文件如下:redis.properties

redis.hostName=127.0.0.1redis.port=6379

這個配置文件需要在application-contex.xml中加載,同時application-context.xml還需要加載application-context-redis.xml配置文件

<bean 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); }

接口實現(xiàn)如下:

@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); }}

在該實現(xiàn)中繼承了一個AbstractRedisDao,這個主要是提供getRedisTemplate()函數(shù),使我們能夠調(diào)用在application-context-redis.xml中配置的redisTemplate bean實例

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

主要的程序都已經(jīng)寫完了,接下來可以用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); } }

在這個測試類中,為了能夠運行這些測試函數(shù),需要對所有的bean進行實例化,這個過程是在 AbstractUnitTest中實現(xiàn)的,代碼如下:

@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一下等待線程結(jié)束 } }

AbstractUnitTest類可以作為測試spring的一個通用類。

主要的代碼就這些了,運行下可以看到結(jié)果是沒有問題的。下面我摘抄一段打印輸出說明一個問題:

016-08-02 20:43:16,608 DEBUG RedisConnectionUtils:125 - Opening RedisConnection2016-08-02 20:43:16,609 DEBUG RedisConnectionUtils:205 - Closing Redis Connection2016-08-02 20:43:16,610 INFO RedisServiceTest:54 - lpop value is 02016-08-02 20:43:16,610 DEBUG RedisConnectionUtils:125 - Opening RedisConnection2016-08-02 20:43:16,611 DEBUG RedisConnectionUtils:205 - Closing Redis Connection2016-08-02 20:43:16,611 INFO RedisServiceTest:54 - lpop value is 12016-08-02 20:43:16,611 DEBUG RedisConnectionUtils:125 - Opening RedisConnection2016-08-02 20:43:16,611 DEBUG RedisConnectionUtils:205 - Closing Redis Connection2016-08-02 20:43:16,612 INFO RedisServiceTest:54 - lpop value is 22016-08-02 20:43:16,612 DEBUG RedisConnectionUtils:125 - Opening RedisConnection2016-08-02 20:43:16,612 DEBUG RedisConnectionUtils:205 - Closing Redis Connection2016-08-02 20:43:16,612 INFO RedisServiceTest:54 - lpop value is 32016-08-02 20:43:16,612 DEBUG RedisConnectionUtils:125 - Opening RedisConnection2016-08-02 20:43:16,613 DEBUG RedisConnectionUtils:205 - Closing Redis Connection2016-08-02 20:43:16,613 INFO RedisServiceTest:54 - lpop value is 42016-08-02 20:43:16,613 DEBUG RedisConnectionUtils:125 - Opening RedisConnection2016-08-02 20:43:16,613 DEBUG RedisConnectionUtils:205 - Closing Redis Connection2016-08-02 20:43:16,613 INFO RedisServiceTest:54 - lpop value is 52016-08-02 20:43:16,613 DEBUG RedisConnectionUtils:125 - Opening RedisConnection2016-08-02 20:43:16,614 DEBUG RedisConnectionUtils:205 - Closing Redis Connection2016-08-02 20:43:16,614 INFO RedisServiceTest:54 - lpop value is 62016-08-02 20:43:16,614 DEBUG RedisConnectionUtils:125 - Opening RedisConnection2016-08-02 20:43:16,614 DEBUG RedisConnectionUtils:205 - Closing Redis Connection2016-08-02 20:43:16,618 INFO RedisServiceTest:54 - lpop value is 72016-08-02 20:43:16,618 DEBUG RedisConnectionUtils:125 - Opening RedisConnection2016-08-02 20:43:16,618 DEBUG RedisConnectionUtils:205 - Closing Redis Connection2016-08-02 20:43:16,618 INFO RedisServiceTest:54 - lpop value is 82016-08-02 20:43:16,618 INFO AbstractUnitTest:34 - unit test complete.

這段輸出是運行testLPopList得到的,這里面opening RedisConnection進行了9次,然后又Closing Redis Connection 9次,這是不是說每次執(zhí)行redis操作都需要創(chuàng)建一個連接,操作完然后又關(guān)閉連接呢?實際上不是這樣的,閱讀源代碼我們可以發(fā)現(xiàn)我們對redis的所有操作都是通過回調(diào)execute函數(shù)執(zhí)行的,其代碼如下:

public <T> T execute(RedisCallback<T> action, boolean exposeConnection) { return execute(action, exposeConnection, false);}// execute實現(xiàn)如下:// org.springframework.data.redis.core.RedisTemplate<K, V> --- 最終實現(xiàn)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 pipelineif (pipeline && !pipelineStatus) { connToUse.closePipeline();}// TODO: any other connection processing?return postProcessResult(result, connToUse, existingConnection); } finally {if (!enableTransactionSupport) { RedisConnectionUtils.releaseConnection(conn, factory);} }}

這里面每次執(zhí)行action.doInRedis(connToExpose)前都要調(diào)用RedisConnectionUtils.getConnection(factory);獲得一個連接,進入RedisConnnectionUtils類中,getConnection(factory)最終調(diào)用的是doGetConnection(factory, true, false, enableTranactionSupport)這個函數(shù)。這個函數(shù)我們可以看下api文檔,發(fā)現(xiàn)實際上并不是真的創(chuàng)建一個新的redis連接,它只是在connectFactory中獲取一個連接,也就是從連接池中取出一個連接。當然如果connectFactory沒有連接可用,此時如果allowCreate=true便會創(chuàng)建出一個新的連接,并且加入到connectFactory中?;旧峡梢源_定真實的情況是spring-data-redis已經(jīng)幫我們封裝了連接池管理,我們只需要調(diào)用一系列操作函數(shù)即可,這給操作redis帶來了極大的方便。

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

到此這篇關(guān)于spring-data-redis連接操作redis的實現(xiàn)的文章就介紹到這了,更多相關(guān)spring-data-redis連接操作redis內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
欧美xxxx中国| 国产精品xxx| 麻豆精品国产91久久久久久| 亚洲三级在线| 天堂av一区| 日韩亚洲国产欧美| 日韩中文影院| 日本精品一区二区三区在线观看视频| 不卡中文一二三区| 日韩精品1区| 里番精品3d一二三区| 日韩高清在线不卡| 水野朝阳av一区二区三区| 久久伊人亚洲| 美女在线视频一区| 欧美一级二级三级视频| 一本一道久久a久久| 欧美精品自拍| 欧美日韩中文字幕一区二区三区| 国产精品4hu.www| 亚洲不卡视频| 日韩一区二区三区四区五区 | 香蕉久久夜色精品国产| 亚洲黑丝一区二区| 婷婷亚洲综合| 久久国产精品99国产| 国产精品xxx在线观看| 日本欧美国产| 欧美丝袜一区| 免费日韩av| 国产日韩欧美三级| 国产激情欧美| 日韩精品一区二区三区免费观影| 尹人成人综合网| 蜜乳av另类精品一区二区| 中文字幕一区二区精品区| 综合亚洲视频| 国产精品一区二区免费福利视频 | 香蕉国产精品| 日韩手机在线| 精品黄色一级片| 欧美日韩精品免费观看视欧美高清免费大片 | 日韩精品免费一区二区夜夜嗨 | 国产手机视频一区二区| 久久不卡国产精品一区二区| 久久精品免视看国产成人| 亚洲黑丝一区二区| 911精品国产| 久久精选视频| 男女男精品网站| 国产一区二区视频在线看| 亚洲激情欧美| 久草精品视频| 中文字幕日韩亚洲| 999久久久亚洲| 国产欧美精品久久| 亚洲国产日韩欧美在线| 国产精品久久久久久妇女| 国产成人精品亚洲线观看| 美女91精品| 人人草在线视频| 国产欧美激情| 久久亚洲图片| 91精品啪在线观看国产18| 精品一区毛片| 日本一区二区高清不卡| 97久久中文字幕| 亚洲欧洲一区| 日本欧美国产| 国产精品久久久久77777丨| 精品色999| 国产精品最新| 国产午夜精品一区在线观看| 石原莉奈在线亚洲三区| 日韩亚洲一区在线| 久久中文字幕一区二区三区| 日本成人在线网站| 久久高清国产| 日韩精品一二三四| 亚洲精品中文字幕乱码| 亚洲午夜黄色| 在线日韩一区| 五月婷婷六月综合| 久久最新视频| 中文字幕一区二区三区四区久久 | 亚洲激情中文在线| 成人日韩在线观看| 在线看片国产福利你懂的| 精品丝袜久久| 精品国产网站| 日韩久久视频| 国产一区二区三区四区五区| 国内在线观看一区二区三区| 日韩国产在线不卡视频| 欧美伊人久久| 国产在线一区不卡| 日韩在线短视频| 99国产精品99久久久久久粉嫩| 午夜在线视频观看日韩17c| 亚洲免费影院| 日本成人在线视频网站| 日韩欧美三区| 国产精选在线| 久久久久久久久丰满| 欧美精品黄色| 国产精品尤物| 国内精品麻豆美女在线播放视频| 欧美天堂视频| 丝袜脚交一区二区| 国产精品视频一区视频二区| 日韩国产一区二区三区| 午夜在线精品偷拍| 麻豆精品视频在线观看| 午夜久久黄色| 欧美午夜网站| 精品捆绑调教一区二区三区| 日韩制服丝袜先锋影音| 国产va免费精品观看精品视频| 日韩一级精品| 国产欧美久久一区二区三区| 欧美精品aa| 婷婷成人在线| 国产欧美日韩在线观看视频| 欧美精选一区二区三区| 免费人成在线不卡| 欧美日韩伊人| 国产精品婷婷| 国产另类在线| 欧美aa在线视频| 蜜臀av一区二区三区| 黄在线观看免费网站ktv| 久久国产免费看| 亚欧洲精品视频在线观看| 国产66精品| 日韩综合一区二区三区| 中文字幕一区二区av| 亚洲精品观看| 高清一区二区三区| 美腿丝袜亚洲一区| 卡一卡二国产精品| 国产精品mv在线观看| 欧美精品影院| 欧美成人精品一级| 欧美国产三级| 麻豆国产91在线播放| 精品午夜av| 日韩av资源网| 日本久久一区| 亚洲精品在线观看91| 新版的欧美在线视频| 日韩中文字幕| 国产+成+人+亚洲欧洲在线| 97久久亚洲| 日韩在线a电影| 亚洲激情不卡| 欧美福利专区| 亚洲精品成人图区| 欧美久久一区二区三区| 久久亚洲视频| 欧美日韩亚洲在线观看| 日韩网站中文字幕| 中文字幕高清在线播放| 欧美激情视频一区二区三区免费 | 丝袜美腿诱惑一区二区三区 | 国产精品sss在线观看av| 国产免费播放一区二区| 国产精品久久久久久久久久齐齐| 国产一卡不卡| 欧美精品羞羞答答| 亚洲三级国产| 日本不卡视频在线观看| 欧美黄色精品| 日本不卡在线视频| 久久青草久久| 婷婷成人av| 欧美亚洲国产一区| 麻豆极品一区二区三区| 久久伊人亚洲| 四虎精品一区二区免费| 欧美不卡高清| 福利片在线一区二区| 性欧美69xoxoxoxo| 激情国产在线| 亚洲精品va| 精品国产乱码久久久久久樱花 | 91成人精品| 国产精品三p一区二区| 麻豆国产91在线播放| 日韩高清一区| 欧美日一区二区| 精品一区二区三区在线观看视频 | 欧美.日韩.国产.一区.二区 | 日韩三级一区| 午夜久久福利| 99成人在线视频| 欧美国产一级| 18国产精品| 免费成人性网站| 日韩精品免费一区二区三区| 久久精品国产网站|