Springboot 與 Redis 集成 簡易Redis工具類實現

最近項目須要處理一項數據量比較大的業務,考慮之下,高頻訪問/讀取決定使用Redis.本身的Springboot框架下研究了Redis兩天,把成果總結一下redis

開發環境介紹

  • JDK1.7
  • Redis

基礎依賴

<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>1.3.1</version>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Redis配置

省略部份內容的application.yml, 都是默認配置,能夠沒有. 同時也能夠在這裏配置超時時間 最大鏈接 等屬性,能夠考慮參照其餘網絡博客spring

server:
    redis:
        host: localhost  # 162上面的Redis
        port: 6379
        password:

建立RedisConfig,用來配置一些自定義內容.我配置的比較簡略,只註冊了一個按JDK序列化數據的RedisTemplate數據庫

@Configuration
public class RedisConfig extends CachingConfigurerSupport{
    /**
     * 注入 RedisConnectionFactory
     */
    @Autowired
    RedisConnectionFactory redisConnectionFactory;

    /**
     * 實例化 RedisTemplate 對象
     * Primary 在autoware時優先選用我註冊的bean. 
     * 由於在redis框架中有註冊一個StringRedisTemplate,避免注入衝突
     * @return
     */
    @Bean
    @Primary
    public RedisTemplate<String, Object> functionDomainRedisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
        return redisTemplate;
    }

    /**
     * 設置數據存入 redis 的序列化方式
     *
     * @param redisTemplate
     * @param factory
     */
    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setConnectionFactory(factory);
    }
}

Springboot倡導開箱即用,這個Redis依賴很符合這個理念,事實上,即便你不作任何配置,依舊能夠正常鏈接.數組

最後,在springboot主類上添加@EnableCaching,啓用緩存管理,這個不能省略緩存

@EnableCaching
class Application {

	static void main(String[] args) {
		SpringApplication.run (Application.class , args)
	}
}

Redis輔助類

根據分層思想,對Redis數據庫的操做屬於Dao層,不該該直接在Service操做數據, 而Redis是否有ORM框架我也不太清楚,因此爲方便操做Redis數據庫,封裝了RedisDBHelper方便操做,先上接口springboot

/**
 * K 指以hash結構操做時 鍵類型
 * T 爲數據實體 應實現序列化接口,並定義serialVersionUID
 * RedisTemplate 提供了五種數據結構操做類型 hash / list / set / zset / value
 * 方法命名格式爲 數據操做類型 + 操做 如 hashPut 指以hash結構(也就是map)想key添加鍵值對
 * Created by hp on 2018/3/1.
 */
public interface RedisDBHelper<HK, T> {
    /**
     * Hash結構 添加元素
     * @param key key
     * @param hashKey hashKey
     * @param domain 元素
     */
    void hashPut(String key, HK hashKey,T domain);

    /**
     * Hash結構 獲取指定key全部鍵值對
     * @param key
     * @return
     */
    Map< HK, T> hashFindAll(String key);

    /**
     * Hash結構 獲取單個元素
     * @param key
     * @param hashKey
     * @return
     */
    T hashGet(String key,HK hashKey);

    void hashRemove(String key, HK hashKey);

    /**
     * List結構 向尾部(Right)添加元素
     * @param key
     * @param domain
     * @return
     */
    Long listPush(String key, T domain);

    /**
     * List結構 向頭部(Left)添加元素
     * @param key
     * @param domain
     * @return
     */
    Long listUnshift(String key, T domain);

    /**
     * List結構 獲取全部元素
     * @param key
     * @return
     */
    List<T> listFindAll(String key);

    /**
     * List結構 移除並獲取數組第一個元素
     * @param key
     * @return
     */
    T listLPop(String key);

    void remove(String key);

/**
     * 設置過時時間
     * @param key 鍵
     * @param timeout 時間
     * @param timeUnit 時間單位
     */
    boolean expirse(String key, long timeout, TimeUnit timeUnit);
}

這裏我只根據我目前的業務須要添加了幾個接口, 若有其它須要能夠自行添加並實現.對這個接口我提供了簡單的實現服務器

/**
 * 接口的簡單實現
 * Created by hp on 2018/3/1.
 */
@Service("RedisDBHelper")
public class RedisDBHelperImpl<HK, T> implements RedisDBHelper<HK, T>{

    // 在構造器中獲取redisTemplate實例, key(not hashKey) 默認使用String類型
    private RedisTemplate<String, T> redisTemplate;

    // 在構造器中經過redisTemplate的工廠方法實例化操做對象
    private HashOperations<String, HK, T> hashOperations;

    private ListOperations<String, T> listOperations;

    private ZSetOperations<String, T> zSetOperations;

    private SetOperations<String, T> setOperations;

    private ValueOperations<String, T> valueOperations;

    // IDEA雖然報錯,可是依然能夠注入成功, 實例化操做對象後就能夠直接調用方法操做Redis數據庫
    @Autowired
    public RedisDBHelperImpl (RedisTemplate<String, T>  redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.hashOperations = redisTemplate.opsForHash();
        this.listOperations = redisTemplate.opsForList();
        this.zSetOperations = redisTemplate.opsForZSet();
        this.setOperations = redisTemplate.opsForSet();
        this.valueOperations = redisTemplate.opsForValue();
    }


    @Override
    public void hashPut(String key, HK hashKey, T domain) {
        hashOperations.put(key, hashKey, domain);
    }

    @Override
    public Map<HK, T> hashFindAll(String key) {
        return hashOperations.entries(key);
    }

    @Override
    public T hashGet(String key, HK hashKey) {
        return hashOperations.get(key, hashKey);
    }

    @Override
    public void hashRemove(String key, HK hashKey) {
        hashOperations.delete(key, hashKey);
    }

    @Override
    public Long listPush(String key, T domain) {
        return listOperations.rightPush(key, domain);
    }

    @Override
    public Long listUnshift(String key, T domain) {
        return listOperations.leftPush(key, domain);
    }

    @Override
    public List<T> listFindAll(String key) {
        if (! redisTemplate.hasKey(key)){
            return null;
        }
        return listOperations.range(key,0, listOperations.size(key));
    }

    @Override
    public T listLPop(String key) {
        return listOperations.leftPop(key);
    }

    @Override
    public void remove(String key) {
        redisTemplate.delete(key);
    }

    @Override
    public boolean expire(String key, long timeout, TimeUnit timeUnit) {
        return redisTemplate.expire(key, timeout, timeUnit);
    }
}

總體而言就是對Operations的簡單封裝,讓本身可使用的更駕輕就熟一點.那麼RedisDBHelper應該怎麼使用呢?首先定義一個簡單實體網絡

public class Person implements Serializable {
    // 爲了可以正確得序列化和反序列化,這個屬性必不可少
    private static final long serialVersionUID = - 1L;

    private String id;

    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

PersonServiceImpl超簡易示例數據結構

使用方式就是直接autoware注入RedisDBHelper的實例,按需求定義泛型便可mybatis

@Service
public class PersonServiceImpl implements PersonService{
    @Autowired
    RedisDBHelper<String, Person> redisDBHelper;

    // 你能夠理解爲這個是表名
    private static final String KEY= "PERSON_KEY";

    /**
     * 儲存一個Person到一個Map結構中
     * @param person
     */
    public void putPerson(Person person) {
        redisDBHelper.hashPut(KEY, person.getId(), person);
    }
}

由於以上代碼都是從項目代碼中摘錄出來的,因此沒有作嚴格測試,本身在項目上,數據存刪 50條/秒 基本沒有什麼問題,由於是遠程其餘redis服務器因此偶有Read time out.若是發現有什麼問題歡迎反饋交流,謝謝!

相關文章
相關標籤/搜索