02_Springboot集成Redis【單機/集群】

@author Jacky wang
轉(zhuǎn)載請注明出處 , http://www.reibang.com/p/4cfedabca746

2018年09月12日,第一次補充更新.

看了網(wǎng)上一些Springboot集成Redis的很多資料,發(fā)現(xiàn)對Redis的配置復(fù)雜了,自己總結(jié)了Springboot集成Redis的簡單方式冯袍。

一. SpringBoot集成Redis單機版

1.1. 創(chuàng)建Maven工程

搭建SpringBoot工程油宜,包結(jié)構(gòu)如下:

SpringBoot的標(biāo)準(zhǔn)包結(jié)構(gòu)···
3.png

1.2. pom文件添加依賴坯屿,properties添加配置

pom.xml :
<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.dream</groupId>
    <artifactId>spring-redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- Springboot集成Redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!-- Springboot測試 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- 熱部署插件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

-----------------------------------------------------------------------------------------------------

application.properties:(很多其實是默認(rèn)的,這里全部列出來)
    #指定連接工廠使用的Database index,默認(rèn)為: 0
    spring.redis.database=0
    #指定Redis server host豁状,默認(rèn)為: localhost
    spring.redis.host=127.0.0.1
    #指定Redis server的密碼
    #spring.redis.password=
    #指定連接池最大的活躍連接數(shù)蓝仲,-1表示無限稿械,默認(rèn)為8
    spring.redis.pool.max-active=8
    #指定連接池最大的空閑連接數(shù)我抠,-1表示無限,默認(rèn)為8
    spring.redis.pool.max-idle=8
    #指定當(dāng)連接池耗盡時决记,新獲取連接需要等待的最大時間摧冀,以毫秒單位,-1表示無限等待
    spring.redis.pool.max-wait=-1
    #指定連接池中空閑連接的最小數(shù)量系宫,默認(rèn)為0
    spring.redis.pool.min-idle=2
    #指定redis服務(wù)端端口索昂,默認(rèn): 6379
    spring.redis.port=6379
    #指定redis server的名稱
    #spring.redis.sentinel.master
    #指定sentinel節(jié)點,逗號分隔笙瑟,格式為host:port.
    #spring.redis.sentinel.nodes
    #指定連接超時時間楼镐,毫秒單位,默認(rèn)為0
    spring.redis.timeout=0

1.3. RedisTemplate的處理

/**
 * Redis數(shù)據(jù)庫操作對象
 * @author wwj
 */
@Component
public class RedisClient {

    @Autowired
    private RedisTemplate redisTemplate;
    
    /**
     * 寫入緩存
     * @param key
     * @param value
     * @return
     */
    
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    
    /**
     * 寫入緩存設(shè)置時效時間
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    
    /**
     * 讀取緩存
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }
    
    /**
     * 判斷緩存中是否有對應(yīng)的value
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }
    
    /**
     * 刪除對應(yīng)的value
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }
    
    /**
     * 批量刪除對應(yīng)的value
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    /**
     * 批量刪除key
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0)
            redisTemplate.delete(keys);
    }

    /**
     * 哈希 添加
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value){
        HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
        hash.put(key,hashKey,value);
    }

    /**
     * 哈希獲取數(shù)據(jù)
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey){
        HashOperations<String, Object, Object>  hash = redisTemplate.opsForHash();
        return hash.get(key,hashKey);
    }

    /**
     * 列表添加
     * @param k
     * @param v
     */
    public void lPush(String k,Object v){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k,v);
    }

    /**
     * 列表獲取
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1){
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k,l,l1);
    }

    /**
     * 集合添加
     * @param key
     * @param value
     */
    public void add(String key,Object value){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key,value);
    }

    /**
     * 集合獲取
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key){
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }

    /**
     * 有序集合添加
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key,Object value,double scoure){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key,value,scoure);
    }

    /**
     * 有序集合獲取
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key,double scoure,double scoure1){
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }
}

到這里就可以使用,RedisClientRedis進(jìn)行操作了,上面給出的方法比較全,可以選擇需要用到的進(jìn)行使用往枷。

1.4. 測試

1.4.1 Application入口類
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
1.4.2 User實體類
為了測試,還提供了一個User實體類,因為產(chǎn)生了傳輸過程,因此這里必須要實現(xiàn)Serializable接口凄杯。
public class User implements Serializable {
        private static final long serialVersionUID = 1L;
        private String username;
        private int age;
        
        public User() {
            super();
        }
    
        public User(String username, int age) {
            super();
            this.username = username;
            this.age = age;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User [username=" + username + ", age=" + age + "]";
        }
    }
1.4.3 SpringbootRedisTest測試類
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)//指定springboot的啟動類
public class SpringBootRedisTest {

    @Autowired
    private RedisClient redisClient;
    
    @Test
    public void testSet() {
        String key = "keyTest";
        String val = "keyVal2";
        redisClient.set(key, val);
        User user = new User("jack", 24);
        redisClient.set("user", user);
    }
    
    @Test
    public void testGet() {
        String key = "keyTest";
        String key2 = "user";
        String val = (String)redisClient.get(key);
        User user = (User)redisClient.get(key2);
        System.err.println(val);
        System.err.println(user);
    }

    @Test
    public void testRemove() {
        String key = "keyTest";
        String key2 = "user";
        redisClient.remove(key);
        redisClient.remove(key2);
    }
    
    @Test
    public void testSetExpire() throws Exception {
        String key = "testExpire";
        String value = "hello";
        long expireTime = 60L;//60秒后消失
        redisClient.set(key, value, expireTime);
    }
}

以上就是Springboot集成Redis的全部過程,實現(xiàn)起來是非常簡單的错洁。到這里總結(jié)一下:

1. 添加pom.xml : spring-boot-starter-data-redis的依賴
2. 配置application.properties
3. 對RedisTemplate進(jìn)行部分功能的封裝。

具體的測試結(jié)果就不貼出來了戒突,這里貼一下testSetExpire()的結(jié)果屯碴。

1.png

二. SpringBoot集成Redis集群版

2.1. SpringBoot集成Redis集群的兩種方式:

2.1.1. SpringBoot內(nèi)置配置支持:

步驟:

  • 引入RedisMaven依賴
  • 配置application.properties支持Redis集群
  • 引入RedisTemplate使用
  • 測試
1. Maven依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        
2. 配置application.properties支持Redis集群
    # RedisProperties
    # 在群集中執(zhí)行命令時要遵循的最大重定向數(shù)目。
    spring.redis.cluster.max-redirects=3
    # (普通集群膊存,不使用則不用開啟)以逗號分隔的“主機:端口”對列表進(jìn)行引導(dǎo)导而。
    spring.redis.cluster.nodes=192.168.5.122:9001,192.168.5.122:9002
    spring.redis.cluster.timeout=1000\
    
3. 引入RedisTemplate使用
    見單機版的RedisClient
    
4. 測試

@SpringBootTest(classes = Application.class)
@RunWith(value = SpringRunner.class)
public class TestRedis {

    @Autowired
    private RedisClient redisClient;
    
    @Test
    public void setTest() throws Exception {
        List<User> users = new ArrayList<User>();
        User user = new User("coco", "coco", "on");     
        User user2 = new User("jack", "jack", "on");
        user.setCreateDate(new Date());
        user2.setCreateDate(new Date());
        users.add(user);
        users.add(user2);
        redisClient.set("users", FastJsonUtils.toJSONStringWithDateFormat(users));
    }
    
    @Test
    public void getTest() throws Exception {
        String json = (String) redisClient.get("users");
        List<User> users = FastJsonUtils.toList(json, User.class);
        for (User record : users) {
            System.err.println(record.getUsername());
        }
    }
}

操作成功。
2.1.2 . 自定義JedisClusterConfig配置類支持Redis集群

步驟:

  • 引入RedisMaven依賴

  • 自定義Redis的集群配置并以實體類接收

  • 編寫JedisClusterConfig的配置類

  • 使用JedisCluster操作Redis

1. 引入Redis的Maven依賴(省略)
2. 自定義Redis的集群配置并以實體類接收

config/redis.properties:

# 本地環(huán)境集群
jack.redis.pool.nodes=192.168.5.122:9001,192.168.5.122:9002,192.168.5.122:9003
#redis超時時間,單位:秒
jack.redis.pool.timeout=7200
jack.redis.pool.maxAttempts=5
    
@Component
@ConfigurationProperties(prefix = "jack.redis.pool")
@PropertySource("classpath:/config/redis.properties")
public class RedisProperty {

    private String nodes;// redis集群節(jié)點
    private int timeout;// 連接超時時間
    private int maxAttempts;// 重連次數(shù)
 
    省略getter();setter();
}

3.  編寫 JedisClusterConfig 的配置類
    
@SpringBootConfiguration
public class JedisClusterConfig {

    @Autowired
    private RedisProperty redisProperty;
    
    @Bean
    public JedisCluster getJedisCluster() {
        String[] redisArray = redisProperty.getNodes().split(",");//獲取服務(wù)器數(shù)組,不考慮空指針問題
        Set<HostAndPort> nodes = new HashSet<>();
        for (String ipport : redisArray) {
            String[] ipports = ipport.split(":");
            nodes.add(new HostAndPort(ipports[0].trim(), Integer.valueOf(ipports[1].trim())));
        }
        return new JedisCluster(nodes, redisProperty.getTimeout(), redisProperty.getMaxAttempts());
    }
}

4. 使用配置類中的JedisCluster操作Redis

/**
 * @ClassName: JedisClusterClient
 * @Description:TODO(redis集群的基礎(chǔ)操作工具)
 * @author: wwj
 * @date: 2018年8月27日 下午3:15:22
 */
@Component
public class JedisClusterClient {

    @Autowired
    private JedisCluster jedisCluster;
    @Autowired
    private RedisProperty redisProperty;

    /**
     * 寫入緩存
     * 
     * @param key
     * @param value
     * @return
     */

    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            if (value instanceof String) {
                jedisCluster.set(key, value.toString());
            } else {
                jedisCluster.set(key, FastJsonUtils.toJSONStringWithDateFormat(value));
            }
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 寫入緩存設(shè)置時效時間
     * 
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            if (value instanceof String) {
                jedisCluster.setex(key, Integer.valueOf(expireTime + ""), value.toString());
            } else {
                jedisCluster.setex(key, Integer.valueOf(expireTime + ""), FastJsonUtils.toJSONStringWithDateFormat(value));
            }
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 設(shè)置緩存隔崎,并且由配置文件指定過期時間
     * 
     * @param key
     * @param value
     */
    public void setWithExpireTime(String key, String value) {
        try {
            int expireSeconds = redisProperty.getTimeout();
            set(key, value, Long.valueOf(expireSeconds));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 讀取緩存
     * 
     * @param key
     * @return
     */
    public String get(final String key) {
        return jedisCluster.get(key);
    }

    /**
     * 判斷緩存中是否有對應(yīng)的value
     * 
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return jedisCluster.exists(key);
    }

    /**
     * 刪除對應(yīng)的value
     * 
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            jedisCluster.del(key);
        }
    }

    /**
     * 批量刪除對應(yīng)的value
     * 
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末今艺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子爵卒,更是在濱河造成了極大的恐慌虚缎,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,423評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钓株,死亡現(xiàn)場離奇詭異实牡,居然都是意外死亡,警方通過查閱死者的電腦和手機轴合,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評論 2 385
  • 文/潘曉璐 我一進(jìn)店門创坞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人受葛,你說我怎么就攤上這事题涨≠怂” “怎么了?”我有些...
    開封第一講書人閱讀 157,019評論 0 348
  • 文/不壞的土叔 我叫張陵携栋,是天一觀的道長搭盾。 經(jīng)常有香客問我,道長婉支,這世上最難降的妖魔是什么鸯隅? 我笑而不...
    開封第一講書人閱讀 56,443評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮向挖,結(jié)果婚禮上蝌以,老公的妹妹穿的比我還像新娘。我一直安慰自己何之,他們只是感情好跟畅,可當(dāng)我...
    茶點故事閱讀 65,535評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著溶推,像睡著了一般徊件。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒜危,一...
    開封第一講書人閱讀 49,798評論 1 290
  • 那天虱痕,我揣著相機與錄音,去河邊找鬼辐赞。 笑死部翘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的响委。 我是一名探鬼主播新思,決...
    沈念sama閱讀 38,941評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼赘风!你這毒婦竟也來了夹囚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,704評論 0 266
  • 序言:老撾萬榮一對情侶失蹤贝次,失蹤者是張志新(化名)和其女友劉穎崔兴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛔翅,經(jīng)...
    沈念sama閱讀 44,152評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡敲茄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,494評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了山析。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片堰燎。...
    茶點故事閱讀 38,629評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖笋轨,靈堂內(nèi)的尸體忽然破棺而出秆剪,到底是詐尸還是另有隱情赊淑,我是刑警寧澤,帶...
    沈念sama閱讀 34,295評論 4 329
  • 正文 年R本政府宣布仅讽,位于F島的核電站陶缺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏洁灵。R本人自食惡果不足惜饱岸,卻給世界環(huán)境...
    茶點故事閱讀 39,901評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望徽千。 院中可真熱鬧苫费,春花似錦、人聲如沸双抽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牍汹。三九已至铐维,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間慎菲,已是汗流浹背方椎。 一陣腳步聲響...
    開封第一講書人閱讀 31,978評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钧嘶,地道東北人。 一個月前我還...
    沈念sama閱讀 46,333評論 2 360
  • 正文 我出身青樓琳疏,卻偏偏與公主長得像有决,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子空盼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,499評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理书幕,服務(wù)發(fā)現(xiàn),斷路器揽趾,智...
    卡卡羅2017閱讀 134,631評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,773評論 6 342
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,764評論 25 707
  • 閑坐品茶與讀書台汇, 靜心修養(yǎng)萬事闊。 詩書下酒味無窮篱瞎, 良辰美景盡其中苟呐。 (注,無押韻俐筋,自由體隨意詩牵素。)
    凡高瀟湘花子閱讀 64評論 0 1
  • 上帝在創(chuàng)造牛的時候,對牛說道:“你只能活60年澄者。但要一生為人類干活笆呆∏肓眨” 于是牛放棄了30年的生命,只愿活到30歲赠幕。...
    劉鼻涕26閱讀 213評論 0 0