您好,登錄后才能下訂單哦!
無論是mysql數據庫、redis數據庫、activeMq,我們都需要創建客戶端連接、根據業務邏輯進行增刪改查、關閉客戶端連接等操作。在Spring中為例簡化這一系列的操作。提供了模板類。
將數據訪問中的固定和變化部分分開,將相同的數據訪問流程固話到模板類中,變化的部分通過回調接口開放出來,用于具體定義數據訪問和結果返回的操作,同時保證模板類是線程安全的,以便多個數據訪問線程共享同一個模板實例。
在S平日那個中有很多模板類,比如HibernateTemplate、JdbcTemplate、RedisTemplate等等。本文將以RedisTemplate、JdbcTemplate為例,講解創建連接、執行操作、釋放連接這一系列操作;
一、RedisTemplate
對于單個使用線程池的jedis操作步驟請看java操作redis的章節,對于spring整合redis也請看前面章節。本章主要講解源碼!
List<String> list=new ArrayList<String>(); list.add("value1"); list.add("value2"); ListOperations<String, String> listOperations=redisTemplate.opsForList(); listOperations.rightPushAll("listCol", list);
上面的代碼是一段向隊列中添加List的操作。我們以此為例講解:
1)首先涉及到的類有:
DefaultListOperation //主要用于封裝對List的操作,主要是調用RedisTemplate中的execute方法
StringRedisSerializer //key的序列化和反序列化的工具類
JdkSerializationRedisSerializer //value的序列化和反序列化的工具類
RedisCallback //回調接口,具體定義數據訪問和結果返回的操作
RedisTemplate //redis操作模板類,用于封裝redis的操作數據流程
RedisConnectionUtils //用于管理redis客戶端連接
TransactionSynchronizationManager //線程同步管理
JedisConnectionFactory //創建Jedis的工廠類
Jedis //redis的客戶端連接對象
JedisConnection //用于封裝真正的Jedis連接對象
2)分析上面代碼的源碼
redisTemplate.opsForList();//會創建DefaultListOperation 對象,該對象中封裝了RedisTemplate。
listOperations.rightPushAll("listCol", list);//具體方法代碼如下圖
/***** **DefaultListOperation類中主要的調用 ***主要成員變量:RedisTemplate ******/ @Override public Long rightPushAll(K key, Collection<V> values) { //序列化對象key、value //調用RedisTemplate的keySerializer、valueSerializer的serialize() final byte[] rawKey = rawKey(key); final byte[][] rawValues = rawValues(values); //調用RedisTemplate的方法execute,實現對Redis操作 return execute(new RedisCallback<Long>(){ //實現回調接口 public Long doInRedis(RedisConnection connection) { return connection.rPush(rawKey, rawValues); } }, true); //參數exposeConnection(公開連接):true } @SuppressWarnings("unchecked") byte[] rawKey(Object key) { Assert.notNull(key, "non null key required"); if (keySerializer() == null && key instanceof byte[]) { return (byte[]) key; } //實際調用RedisTemplate來序列化key return keySerializer().serialize(key); } //調用RedisTemplate的方法 RedisSerializer keySerializer() { return template.getKeySerializer(); } //調用RedisTemplate的方法 <T> T execute(RedisCallback<T> callback, boolean b) { return template.execute(callback, b); } /***** **RedisTemplate類中主要的調用 ***主要成員變量:JedisConnectionFactory ******/ public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) { //redis連接工廠,用于創建、關閉redis連接 RedisConnectionFactory factory = getConnectionFactory(); //內部封裝真正的redis連接,用于實現各種操作 RedisConnection conn = null; try { //默認不啟動事務,redis連接是通過RedisConnectionUtils獲得的 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(); } //是否為jedisConnection,創建動態代理對象(jdk動態代理技術) RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse)); //調用回調函數,執行數據庫操作,之部分是動態的,可以由用戶自己指定操作 T result = action.doInRedis(connToExpose); // close pipeline if (pipeline && !pipelineStatus) { connToUse.closePipeline(); } // TODO: any other connection processing? return postProce***esult(result, connToUse, existingConnection); } finally { //非事務操作,釋放連接 if (!enableTransactionSupport) { RedisConnectionUtils.releaseConnection(conn, factory); } } }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。