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

您的位置:首頁技術文章
文章詳情頁

spring-data-redis連接操作redis的實現

瀏覽:13日期: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以及日志打印相關的三個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狀態的對象數 --> <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 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中,這個時候可以將對象轉為json字符串之后再存儲,取出來的時候再將json字符串轉換為對象。這種操作還是比較方便的,都有線程的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); }

接口實現如下:

@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 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次,這是不是說每次執行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 pipelineif (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內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
裤袜国产欧美精品一区| 日韩av在线中文字幕| 亚洲精品乱码| 国产精品任我爽爆在线播放| 成人亚洲精品| 亚洲欧美不卡| 婷婷激情图片久久| 久久gogo国模啪啪裸体| 黄色网一区二区| 久久精品女人| sm久久捆绑调教精品一区| 久久香蕉精品| 欧美日韩亚洲一区二区三区在线| 国产福利片在线观看| 日韩中文字幕亚洲一区二区va在线| 国产精品一区二区99| 日韩毛片在线| 青草av.久久免费一区| 亚洲黄色免费av| 亚洲精品影视| 亚洲精品国产嫩草在线观看| 中文字幕av一区二区三区人| 日韩成人免费| 五月亚洲婷婷 | 久久av网址| 黄色欧美日韩| 国产一区二区三区四区| 丝袜a∨在线一区二区三区不卡 | 精品在线99| 麻豆精品视频在线观看| 亚洲一区二区免费看| 九九久久国产| 日韩有吗在线观看| 久久久夜精品| 国产极品一区| 一本综合精品| 今天的高清视频免费播放成人| 国产精品男女| 午夜在线精品| 日韩欧美精品综合| 国产欧美啪啪| 久久xxxx精品视频| 91亚洲人成网污www| 亚洲精品无播放器在线播放| 久久激情婷婷| 国产成人久久精品麻豆二区 | 日韩在线不卡| 国产精品久久久一区二区| 天使萌一区二区三区免费观看| 97精品97| 欧美精品成人| 青青草伊人久久| 亚洲欧美高清| 免费av一区| 色偷偷色偷偷色偷偷在线视频| 国产精品亚洲产品| 麻豆视频一区二区| 亚洲性色av| 日本欧美久久久久免费播放网| 国产精品原创| 亚洲人成精品久久久| 中文在线资源| 欧美一区二区三区久久精品| 欧美.日韩.国产.一区.二区| 国产+成+人+亚洲欧洲在线| 99国产精品私拍| 欧洲激情综合| 国产精品av久久久久久麻豆网| 蜜桃av在线播放| 国产精品成久久久久| 久久一区亚洲| 国产欧美日韩在线一区二区| 日本在线不卡视频| 蜜臀久久99精品久久久久久9| 99久久视频| 久久精品主播| 久久久久久久久久久妇女| 夜鲁夜鲁夜鲁视频在线播放| 高清一区二区三区av| 精品国产亚洲日本| 国产精品观看| 欧美精品99| 久久爱www成人| 国产精品传媒麻豆hd| 欧美日韩亚洲一区二区三区在线| 日本亚州欧洲精品不卡| 亚洲精品系列| 日韩精品视频中文字幕| 亚洲精品欧洲| 亚洲精品第一| 亚久久调教视频| 日韩精品一页| 国产无遮挡裸体免费久久| 欧美日韩亚洲一区二区三区在线| 日韩成人一级| 国产欧美日韩一区二区三区四区 | 精品国产欧美| 久久精品国产久精国产| 国产精品网址| 久久av国产紧身裤| 国产精品精品| 日韩精品首页| av亚洲在线观看| 丝袜美腿亚洲一区| 日韩精品午夜视频| 国产精品一国产精品| 欧美aaaaaa午夜精品| 国产一区二区三区网| 日韩大片在线观看| 欧美理论视频| 亚洲97av| 久久精品系列| 国产精品亚洲一区二区三区在线观看| 日韩精品久久久久久久电影99爱 | 久久99伊人| 日本亚洲欧洲无免费码在线| 欧美亚洲专区| 日本一二区不卡| 九一国产精品| 日韩精品视频一区二区三区| 美女高潮久久久| 高清不卡亚洲| 好吊一区二区三区| 日本不卡的三区四区五区| 国产精品亚洲综合色区韩国| 精品国内亚洲2022精品成人| av资源亚洲| 99精品99| 国产精品一级| 成人午夜国产| 日韩在线观看一区二区| 国产亚洲欧美日韩精品一区二区三区| 精品久久久久中文字幕小说| 欧美日韩黑人| 国产调教精品| 91精品国产乱码久久久久久久| 国产精品毛片| 国产日韩欧美三级| 成人羞羞在线观看网站| 蜜臀久久99精品久久久久久9 | 三级在线看中文字幕完整版| 日韩视频二区| 国产精品一级在线观看| 国产v综合v| 日韩一区二区三区精品视频第3页| 久久精品国产99| aⅴ色国产欧美| 久久久久九九精品影院| 午夜久久一区| 美女视频黄免费的久久| 亚洲激情精品| 国产日本久久| 婷婷激情久久| 欧美亚洲二区| 欧美69视频| 国产欧美一区二区三区米奇| 欧美日韩在线二区| 青青青国产精品| 99久久99视频只有精品| 日韩在线视频一区二区三区| 高清av不卡| 日韩二区三区在线观看| 日韩精品影视| 国产精品久久久久久久免费软件| 韩日一区二区三区| 牛牛精品成人免费视频| 亚洲欧美伊人| 国产精品一级| 鲁大师影院一区二区三区| 三上亚洲一区二区| 日本伊人久久| 九九在线精品| 精品精品99| 日本va欧美va瓶| 国产综合色产| 精品国产亚洲一区二区三区大结局| 男人的天堂亚洲一区| 色综合www| 精品一区二区三区四区五区| 亚洲一区免费| 精品成人免费一区二区在线播放| 日本成人中文字幕在线视频| 国产综合精品一区| 久久久久久一区二区| 欧美另类中文字幕| 老鸭窝毛片一区二区三区| 成人啊v在线| 精品黄色一级片| 国产日韩精品视频一区二区三区| 国产精品社区| 久久国产精品成人免费观看的软件| 欧美国产亚洲精品| 91欧美日韩在线| 亚洲伊人精品酒店| 狠狠色综合网| 91精品一区二区三区综合| 精品资源在线| 国产精品一区二区三区av麻| 日韩黄色av| 日精品一区二区三区|