Redis入門及在項目中的使用

redis屬于NoSql分類瀑踢,它把數(shù)據(jù)都是緩存在內(nèi)存中的擂啥,我們都知道內(nèi)存的讀寫效率跟硬盤不是一個級別的哄陶,最后redis會周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件。既然用redis讀取效率那么高哺壶,最后內(nèi)容也會添加到磁盤那么我們就當(dāng)然要使用它了屋吨。

一、redis的基本操作
redis是一個key-value存儲系統(tǒng)山宾。它支持存儲的value類型相對更多至扰,包括string(字符串)、list(鏈表)资锰、set(集合)敢课、zset(sortedset–有序集合)和hash(哈希類型)五種數(shù)據(jù)類型,存儲形式均為字符串绷杜。

啟動redis
啟動redis服務(wù):[root@itheima32 src]# ./redis-server redis.conf
查看進程:[root@itheima32 bin]# ps aux|grep redis
root 1793 0.3 0.0 34992 1772 ? Ssl 10:29 0:00 ./redis-server *:6379
root 1797 0.0 0.0 5532 812 pts/0 S+ 10:29 0:00 grep redis
表示啟動成功直秆。
啟動客戶端:[root@itheima32 src]# ./redis-cli
127.0.0.1:6379>
其中6379表示本機的6379端口服務(wù)。
連接到該linux:ctrl+c退出鞭盟,接著切換
[root@itheima32 bin]# ./redis-cli -h 192.168.25.128 -p 6379
192.168.25.128:6379>
這就切換成功了圾结。接下來進行操作。

1.1懊缺、String類型
為了看的更直觀疫稿,這里就直接展示操作內(nèi)容培他。
存儲:set key value
取值:get key
刪除:del key
查看所有鍵:keys *
示例:

192.168.25.128:6379> set str1 123
OK
192.168.25.128:6379> set str2 abc
OK
192.168.25.128:6379> set str3 xixi
OK
192.168.25.128:6379> get str1
"123"
192.168.25.128:6379> get str2
"abc"
192.168.25.128:6379> get str3
"xixi"
192.168.25.128:6379> del str1
(integer) 1
192.168.25.128:6379> keys *
 1) "str2"
2) "str3"

增1:incr key
減1:decr key
注意, 雖然redis存儲形式都是字符串遗座,但是自增減的時候要求value必須能解析成數(shù)值類型舀凛,比如你的value是”1ad”那就不行。

示例:先添加鍵值對 str1 3,再自增就成了4

192.168.25.128:6379> set str1 3
OK
192.168.25.128:6379> incr str1
(integer) 4

1.2途蒋、Hash類型
相當(dāng)于一個key對于一個map猛遍,map中還有key-value
存儲:hset key field value
取值:hget key field
查看某個鍵對應(yīng)的map里面的所有key:hkeys key
查看某個鍵對應(yīng)的map里面的所有的value:hvals key
查看某個鍵的map:hgetall key

示例:

192.168.25.128:6379> hset hone field1 123
(integer) 1
192.168.25.128:6379> hset hone field2 abc
(integer) 1
192.168.25.128:6379> hset hone field3 haha
(integer) 1
192.168.25.128:6379> hget hone field1
"123"
192.168.25.128:6379> hget hone field2
"abc"
192.168.25.128:6379> hget hone field3
"haha"
192.168.25.128:6379> hkeys hone
1) "field1"
2) "field2"
3) "field3"
192.168.25.128:6379> hvals hone
1) "123"
2) "abc"
3) "haha"
192.168.25.128:6379> hgetall hone
1) "field1"
2) "123"
3) "field2"
4) "abc"
5) "field3"
6) "haha"

1.3、List類型
存儲:push,分為lpush list v1 v2 v3 v4 …(左邊添加)号坡,rpush list v1 v2 v3 v4 …(右邊添加)
取值:pop,分為lpop lpop list(左邊取,移除list最左邊的值) 懊烤,rpop rpop list(右邊取,移除list最右邊的值)
查看list:lrange key 0 -1(0 -1表示查看所有)
存儲,取值操作跟棧的存儲,取值方法是一樣的宽堆,而不是add腌紧,get,存儲的值有序可以重復(fù)。用pop取值取完后該值就從list中移除了畜隶。

示例:

```
192.168.25.128:6379> lpush list1 1 2 3 4 5 6
(integer) 6
192.168.25.128:6379> rpush list1 a b c d e 
(integer) 11
192.168.25.128:6379> lrange list1 0 -1
 1) "6"
 2) "5"
 3) "4"
 4) "3"
 5) "2"
 6) "1"
 7) "a"
 8) "b"
 9) "c"
10) "d"
11) "e"
192.168.25.128:6379> lpop list1
"6"
192.168.25.128:6379> lrange list1 0 -1
 1) "5"
 2) "4"
 3) "3"
 4) "2"
 5) "1"
 6) "a"
 7) "b"
 8) "c"
 9) "d"
10) "e"
192.168.25.128:6379> rpop list1
"e"
192.168.25.128:6379> lrange list1 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
6) "a"
7) "b"
8) "c"
9) "d"

1.4壁肋、Set類型
set中的元素是無序不重復(fù)的,出現(xiàn)重復(fù)會覆蓋
存儲:sadd key v1 v2 v3 …
移除:srem key v
查看set集合: smembers key
另外還提供了差集,交集籽慢,并集操作
差集:sdiff seta setb(seta中有setb中沒有的元素)
交集:sinter seta setb
并集:sunion seta setb

192.168.25.128:6379> sadd set a b a b c d
(integer) 4
192.168.25.128:6379> srem set a
(integer) 1
192.168.25.128:6379> smembers set
1) "d"
2) "b"
3) "c"
192.168.25.128:6379> sadd seta a b c d e
(integer) 5
192.168.25.128:6379> sadd setb c d e f g 
(integer) 5
192.168.25.128:6379> sdiff seta setb(差集浸遗,seta有setb沒有)
1) "a"
2) "b"
192.168.25.128:6379> sdiff setb seta (差集,setb有seta沒有)
1) "g"
2) "f"
192.168.25.128:6379> sinter seta setb(交集)
1) "d"
2) "e"
3) "c"
192.168.25.128:6379> sunion seta setb(并集)
1) "a"
2) "b"
3) "d"
4) "g"
5) "f"
6) "e"
7) "c"

1.5箱亿、SortedSet,有序Set
存儲:存儲的時候要求對set進行排序跛锌,需要對存儲的每個value值進行打分,默認排序是分?jǐn)?shù)由低到高届惋。zadd key 分?jǐn)?shù)1 v1 分?jǐn)?shù)2 v2 分?jǐn)?shù)3 v3…
取值:取指定的值 zrem key value
取所有的值(不包括分?jǐn)?shù)):zrange key 0 -1髓帽,降序取值用zrevrange key 0 -1
取所有的值(帶分?jǐn)?shù)):zrange(zrevrange) key 0 -1 withscores

示例:

192.168.25.128:6379> zadd zset1 1 a 3 b 2 c 5 d(要求給定分?jǐn)?shù),從而達到排序效果,默認升序)
(integer) 4
192.168.25.128:6379> zrange zset1 0 -1
1) "a"
2) "c"
3) "b"
4) "d"
192.168.25.128:6379> zrem zset1 a 
(integer) 1
192.168.25.128:6379> zrange zset1 0 -1
1) "c"
2) "b"
3) "d"
192.168.25.128:6379> zrevrange zset1 0 -1(按分?jǐn)?shù)降序排)
1) "d"
2) "b"
3) "c"
192.168.25.128:6379> zrevrange zset1 0 -1 withscores
1) "d"
2) "5"
3) "b"
4) "3"
5) "c"
6) "2"

1.6盼樟、key命令
由于redis是內(nèi)存存儲數(shù)據(jù)氢卡,所以不能夠存儲過大的數(shù)據(jù)量,所以存儲在redis中的數(shù)據(jù)晨缴,在不再需要的時候應(yīng)該清除掉。比如峡捡,用戶買完東西下訂單击碗,生成的訂單信息存儲了在redis中,但是用戶一直沒支付那么存儲在redis中的訂單信息就應(yīng)該清除掉们拙,這個時候就可以通過設(shè)置redis的過期時間來完成稍途,一旦達到了過期時間就清除該信息。
設(shè)置key的過期時間:expired key 過期時間(秒)
查看key的有效剩余時間:ttl key
清除key的過期時間砚婆,持久化該key:persist key
-1:表示持久化
-2: 表示該key不存在

示例:

192.168.25.128:6379> expire zone 60
(integer) 1
192.168.25.128:6379> ttl zone
(integer) 55
192.168.25.128:6379> ttl zone
(integer) 51
192.168.25.128:6379> ttl zone
(integer) 48
192.168.25.128:6379> ttl zone
(integer) 37
192.168.25.128:6379> ttl zone
(integer) 16
192.168.25.128:6379> ttl zone
(integer) -2  -->(該key已經(jīng)不存在)
192.168.25.128:6379> expire sone 30
(integer) 1
192.168.25.128:6379> ttl sone
(integer) 22
192.168.25.128:6379> persist sone
(integer) 1
192.168.25.128:6379> ttl sone
(integer) -1  -->(該key是持久化的)

對與上面的基本操作械拍,就我個人在案例中以及實習(xí)的真實項目中來說突勇,至少得要掌握String類型,Hash類型以及key命令坷虑。
二甲馋、項目中使用redis

2.1、使用jedis操作redis測試

進行測試之前需要引入依賴

<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.9.0</version>
</dependency>

測試:

@Test
    public void testJedis() throws Exception{
        //創(chuàng)建一個連接jedis對象迄损,參數(shù):host,port
        Jedis jedis = new Jedis("192.168.25.128", 6379);
        //直接使用jedis來操作redis,所有jedis的命令都對應(yīng)一個方法
        jedis.set("test123", "my first jedis test");
        String s = jedis.get("test123");
        System.out.println(s);
        //關(guān)閉連接
        jedis.close();
    }
    輸出結(jié)果:my first jedis test
    去客戶端查看:
    192.168.25.128:6379> get test123
    "my first jedis test"

這里只測試了String類型,Jedis提供了與redis操作對應(yīng)的方法來操作redis定躏。
操作hash類型主要有:hset(…),hget(…)芹敌,hdel(…)痊远,hexist(…)
key命令:persist(key),expire(key,seconds)
具體的根據(jù)提示來選擇自己需要的。

測試氏捞,從連接池獲取jedis:

    @Test//連接
    public void testJedisPool() throws Exception{
        JedisPool jedisPool = new  JedisPool("192.168.25.128", 6379);
        //從連接池獲得一個連接,就是一個jedis對象
        Jedis jedis = jedisPool.getResource();
        //操作redis
        String s = jedis.get("test123");
        System.out.println(s);
        //關(guān)閉連接,每次使用完畢后關(guān)閉連接,連接池回收資源
        jedis.close();
        //關(guān)閉連接池
        jedisPool.close();
    }

這個就跟從數(shù)據(jù)庫連接池獲取連接道理是一樣的碧聪,需要連接的時候從連接池中取獲取一個連接就行,使用完后就放回連接池液茎,而不用重新去創(chuàng)建一個連接逞姿,這項技術(shù)能大大提高操作redis的性能。

2.2豁护、使用JedisClient操作redis

測試的時候我們發(fā)現(xiàn)哼凯,每次都要自己創(chuàng)建關(guān)閉連接,頻繁使用的話會顯得很繁瑣楚里。所以我們可以一開始就定義好對應(yīng)方法來幫我們關(guān)閉連接断部。使用的時候調(diào)用自己的方法即可。

接口如下:

public interface JedisClient {
    String set(String key, String value);
    String get(String key);
    Boolean exists(String key);
    Long expire(String key, int seconds);
    Long ttl(String key);
    Long incr(String key);
    Long hset(String key, String field, String value);
    String hget(String key, String field);
    Long hdel(String key, String... field);
    Boolean hexists(String key, String field);
    List<String> hvals(String key);
    Long del(String key);
}

這里定義的方法主要是針對String類型班缎,Hash類型蝴光,key命令。
比如String類型达址,Hash類型的存儲蔑祟、獲取、刪除沉唠、是否存在指定key疆虚,設(shè)置過期時間,自增满葛,自間径簿,有效時間等。

實現(xiàn)類如下:

public class JedisClientPool implements JedisClient {

    private JedisPool jedisPool;

    public JedisPool getJedisPool() {
        return jedisPool;
    }
    public void setJedisPool(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }
    public String set(String key, String value) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.set(key, value);
        jedis.close();
        return result;
    }
    public String get(String key) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.get(key);
        jedis.close();
        return result;
    }
    public Boolean exists(String key) {
        Jedis jedis = jedisPool.getResource();
        Boolean result = jedis.exists(key);
        jedis.close();
        return result;
    }
    public Long expire(String key, int seconds) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.expire(key, seconds);
        jedis.close();
        return result;
    }
    public Long ttl(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.ttl(key);
        jedis.close();
        return result;
    }

    public Long incr(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.incr(key);
        jedis.close();
        return result;
    }
    public Long hset(String key, String field, String value) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hset(key, field, value);
        jedis.close();
        return result;
    }
    public String hget(String key, String field) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.hget(key, field);
        jedis.close();
        return result;
    }
    public Long hdel(String key, String... field) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hdel(key, field);
        jedis.close();
        return result;
    }
    public Boolean hexists(String key, String field) {
        Jedis jedis = jedisPool.getResource();
        Boolean result = jedis.hexists(key, field);
        jedis.close();
        return result;
    }
    public List<String> hvals(String key) {
        Jedis jedis = jedisPool.getResource();
        List<String> result = jedis.hvals(key);
        jedis.close();
        return result;
    }
    public Long del(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.del(key);
        jedis.close();
        return result;
    }
}

其實這些方法主要還是調(diào)用了jedis的方法嘀韧,主要是幫我們創(chuàng)建篇亭、關(guān)閉了連接然后進行封裝,從而在項目中使用可以簡化操作锄贷。

2.3译蒂、從Spring容器中獲取JedisClient

在案例中曼月,JedisClient是與Spring整合的。不然每次都要自己創(chuàng)建JedisClient對象柔昼,使用Spring那么就不用我們自己創(chuàng)建對象了哑芹。

JedisClient與spring整合:applicationContext-redis.xml

    配置jedis連接池
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg name="host" value="192.168.25.128"/>
        <constructor-arg name="port" value="6379"/>
    </bean>
<!-- 連接-->
    <bean class="com.neusoft.util.JedisClientPool">
        <property name="jedisPool" ref="jedisPool"/>
    </bean>

這樣初始化Spring容器的時候就會創(chuàng)建JedisClient了

測試:

public void testJedisClient() throws Exception{
        ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-redis.xml");
        //從容器中拿到JedisClient對象
        JedisClient jc = ac.getBean(JedisClient.class);
        jc.set("mytest", "jedisClient");
        String s = jc.get("mytest");
        System.out.println(s);  
    }
    輸出:jedisClient

到這里就可以大膽的在項目中使用JedisClient來操作redis了。

2.4岳锁、實現(xiàn)redis在文章案例中進行緩存

2.4.1绩衷、在文章詳情中使用redis
點擊某篇文章會進入到文章詳情頁。這里也使用了redis激率,比如某篇文章很熱門咳燕,那么單位時間的瀏覽量就會很高,對于這種情況我們可以將文章信息添加到redis中乒躺。

點擊文章的時候會根據(jù)文章id去redis中查詢是否存在該文章信息招盲,有的話直接響應(yīng),如果沒有那么就去查數(shù)據(jù)庫嘉冒,查出來的數(shù)據(jù)存到redis中再做響應(yīng)曹货。

但文章信息不能一直在redis中存放,文章過多的話非常耗費redis的存儲空間讳推,所以需要設(shè)置一下過期時間顶籽,如果這段時間該文章沒人訪問的話就應(yīng)該將該文章信息從redis中清除來釋放空間,如果有人訪問的話那么就重新設(shè)置回原來的過期時間银觅。

@Service
public class ArticleService implements IArticleService {

    @Autowired
    ArticleMapper articleMapper;

    @Autowired
    CommentMapper commentMapper;
    @Autowired
    private SolrServer solrServer;

    @Autowired
    private JedisClient jedisClient;
    @Value("${REDIS_ITEM_PRE}")
    private String REDIS_ITEM_PRE;
    @Value("${ITEM_CACHE_EXPIRE}")
    private Integer ITEM_CACHE_EXPIRE;


  
    @Override
    public Article getArticleByID(int aid) {
        try {
            String string = jedisClient.get(REDIS_ITEM_PRE+":"+aid+":BASE");

            if(string !=null && !string.isEmpty()){
//設(shè)置過期時間
                jedisClient.expire(REDIS_ITEM_PRE+":"+aid+":BASE", ITEM_CACHE_EXPIRE);
                Article tbItem = JSON.parseObject(string,new TypeReference<Article>() {});
                return tbItem;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        Article article = articleMapper.getArticleByID(aid);

        if(article != null){
            //把結(jié)果添加到緩存
            try {
                jedisClient.set(REDIS_ITEM_PRE+":"+aid+":BASE", JSON.toJSONString(article));
                //設(shè)置過期時間
                jedisClient.expire(REDIS_ITEM_PRE+":"+aid+":BASE", ITEM_CACHE_EXPIRE);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return article;
        }else{
            return null;
        }

    }
}

applicationContext-redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">

        <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
                <constructor-arg name="host" value="192.168.47.141"/>
                <constructor-arg name="port" value="6379"/>
        </bean>

        <bean class="com.neusoft.util.JedisClientPool">
                <property name="jedisPool" ref="jedisPool"/>
        </bean>


        <context:property-placeholder location="classpath:app.properties"/>

</beans>

這里使用的是String類型礼饱,寫成 前綴:d:后綴,這種形式在桌面版redis客戶端中文件目錄會有層次結(jié)構(gòu)究驴。

Redis實現(xiàn)緩存同步
考慮這么個問題镊绪,如果在后臺我們修改或刪除了文章信息,這就存在信息不同步問題了洒忧。這里解決的辦法是蝴韭,每次修改或刪除了文章,那么就需要清空redis中的信息熙侍。當(dāng)下次訪問首頁的時候會去數(shù)據(jù)庫中查詢最新的內(nèi)容信息榄鉴,存放到redis中,從而實現(xiàn)了緩存同步蛉抓,代碼如下牢硅。

jedisClient.del(REDIS_ITEM_PRE+":"+aid+":BASE");
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市芝雪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌综苔,老刑警劉巖惩系,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件位岔,死亡現(xiàn)場離奇詭異,居然都是意外死亡堡牡,警方通過查閱死者的電腦和手機抒抬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晤柄,“玉大人擦剑,你說我怎么就攤上這事〗婢保” “怎么了惠勒?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長爬坑。 經(jīng)常有香客問我纠屋,道長,這世上最難降的妖魔是什么盾计? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任售担,我火速辦了婚禮,結(jié)果婚禮上署辉,老公的妹妹穿的比我還像新娘族铆。我一直安慰自己,他們只是感情好哭尝,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布哥攘。 她就那樣靜靜地躺著,像睡著了一般刚夺。 火紅的嫁衣襯著肌膚如雪献丑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天侠姑,我揣著相機與錄音创橄,去河邊找鬼。 笑死莽红,一個胖子當(dāng)著我的面吹牛妥畏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播安吁,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼醉蚁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鬼店?” 一聲冷哼從身側(cè)響起网棍,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妇智,沒想到半個月后滥玷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體氏身,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年惑畴,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛋欣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡如贷,死狀恐怖陷虎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杠袱,我是刑警寧澤尚猿,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站霞掺,受9級特大地震影響谊路,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜菩彬,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一缠劝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骗灶,春花似錦惨恭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至免都,卻和暖如春锉罐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绕娘。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工脓规, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人险领。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓侨舆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绢陌。 傳聞我的和親對象是個殘疾皇子挨下,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

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