1. 程式人生 > >如何在web專案中新增redis快取

如何在web專案中新增redis快取

  • redis 是什麼?這個應該是你做一下工作的前提,不明白的可以百科一下。如果你大概明白了redis的工作原理。那麼請繼續往下看:

    一。首先你需要明白,為什麼要在你的專案中使用redis快取?

    現在很多應用程式要儲存結構簡單更新頻繁的資料,在我看來,字典表裡的資料就是儲存結構簡單且更新頻繁的資料,因此,需要讀取字典表裡的資料時,可以考慮使用redis了。

    這只是其中之一的例子。

    二。如何在web專案新增redis?

    在java專案中,redis提供了很多客戶端庫,我用的jedis,它封裝了對redis資料庫的所有操作。

    一般web應用中,我們還會用到spring,方便的地方在於spring本身也提供了對redis的支援--spring-data-redis,可以到官網檢視文件,並有例項。

    具體步驟:

    1.引入pom依賴(如果沒用maven的話,自行引入jar包吧)

    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.5.0.RELEASE</version>
        </dependency>
    </dependencies>

    同時將jedis也依賴上,因為spring-data-redis底層就是用的jedis:

         <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>2.6.0</version>
                <type>jar</type>
                <scope>compile</scope>
            </dependency>

    2.在容器中配置RedisTemplate例項

    <bean id="jedisConnFactory" 
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
        p:use-pool="true"/>
    
    <!-- redis template definition -->
    <bean id="redisTemplate" 
        class="org.springframework.data.redis.core.RedisTemplate" 
        p:connection-factory-ref="jedisConnFactory"/>

    注意:這是官網直接複製過來的,我這樣直接放在xml中,會報錯,即使是引入p的名稱空間。然後我就嘗試將p屬性寫成property後,就沒有報錯了,但是在後面用的時候會key和value會出現類似"\xac\xed\x00\x05t\x00\tb "這樣的情況,查詢得知這是因為spring-data-redis需要將資料儲存到jedis中,這中間需要序列化,再由jedis儲存到資料庫,問題就出在序列化上了,它會將key和value的型別資訊也序列化後帶上,這顯然不是我們想要的結果。

    所以RedisTemplate提供了對key和value序列化類,於是我打算這樣:

    <bean id="redisTemplate"
              class="org.springframework.data.redis.core.RedisTemplate">
            <property name="connectionFactory" ref="jedisConnFactory"/>
            <property name="keySerializer">
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
            </property>
            <property name="hashKeySerializer">
                <bean class="org.springframework.data.redis.serializer.GenericToStringSerializer"/>
            </property>
            <property name="valueSerializer">
                <bean class="org.springframework.data.redis.serializer.GenericToStringSerializer"/>
            </property>
            <property name="hashValueSerializer">
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
            </property>
        </bean>

    可是中間兩個序列化類還是報錯,沒有無參構造器,所以就準備採用構造器注入的方式,但是要求注入的引數是一個Object.class型別,我也不知道怎麼注入這種型別的,搞來搞去還是乾脆就不要xml了,直接寫配置類:

    @Configuration
    public class RedisConfig {
        @Bean
        JedisConnectionFactory jedisConnectionFactory() {
            return new JedisConnectionFactory();
        }
    
        @Bean
        RedisTemplate<String, Object> redisTemplate() {
            final RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(jedisConnectionFactory());
            template.setKeySerializer(new StringRedisSerializer());
            template.setHashKeySerializer(new GenericToStringSerializer<>(Object.class));
            template.setValueSerializer(new GenericToStringSerializer<>(Object.class));
            return template;
        }
    }

    這下可算可以了(當然要注意掃描包)。

    有了RedisTemplate之後,就可以寫具體的實現業務類了,RedisTemplate基本支援所有redis操作,比如:

    @Component
    public class SpringRedisClientImpl implements SpringRedisClient {
        @Autowired
        private RedisTemplate<String, Object> template;
        @Autowired
        private JedisConnectionFactory jedisConnectionFactory;
    
        @Override
        public void setKey(String key, String value) {
            template.opsForValue().set(key, value);
        }
    
        @Override
        public Object getKey(String key) {
            return template.opsForValue().get(key);
        }
    
        @Override
        public void incr(String key) {
            template.opsForValue().increment(key, 1);
        }
    
        @Override
        public void lPush(String key, String value) {
            template.opsForList().leftPush(key, value);
        }
    
        @Override
        public boolean checkKey(String key) {
            return template.hasKey(key);
        }
    
        @Override
        public Object lIndex(String key) {
            return template.opsForList().index(key, 0);
        }
    
        @Override
        public Long llength(String key) {
            return template.opsForList().size(key);
        }
    
        @Override
        public String lpop(String key) {
    
            return (String) template.opsForList().leftPop(key);
        }
    
        @Override
        public Set<String> getKeys(String pattern) {
            return template.keys(pattern);
        }
    
        @Override
        public void flushAll() {
            Jedis jedis = jedisConnectionFactory.getShardInfo().createResource();
            jedis.flushAll();
            jedis.close();
        }
    }

    最後,啟動redis-server.exe就可以了(這裡要注意要先啟動這個,再啟動web專案,否則啟動不了,原因未知),如果對redis比較熟悉的,可以自行配置redis.windows.conf檔案。其實我也不太熟悉conf檔案裡面的配置,尤其是持久化到磁碟那個。所以在我的專案裡,我是將資料以每天為單位儲存到mysql中,並清空redis。