GreenDAO 3.2.2 簡單入門(二)多表查詢和多表關(guān)聯(lián)

前言

在上一章我們已經(jīng)學(xué)習(xí)了GreenDAO的配置以及簡單的增刪查改( GreenDAO 3.2.2 簡單入門 (一)),本章的內(nèi)容是有關(guān)表之間的進階操作八匠,是對上一章內(nèi)容的擴展。

準(zhǔn)備

因為涉及到數(shù)據(jù)庫結(jié)構(gòu)發(fā)生改變魁兼,需要對數(shù)據(jù)庫版本進行升級:

    // 在HMROpenHelper類中重寫onUpgrade()方法
    @Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        DaoMaster.dropAllTables(db,true);
        onCreate(db);
    }

記得每次發(fā)生上述變化時监署,要在模塊下的build.gradle文件中對數(shù)據(jù)庫版本號進行加一:

greendao{
    schemaVersion 5 // 數(shù)據(jù)庫版本號
    daoPackage 'com.jk.greendao.gen'
    targetGenDir 'src/main/java'
}

一對一關(guān)聯(lián)

假如有兩個表杭煎,A表和B表,A表的一條記錄只對應(yīng)于B表的一條記錄背率,反之亦然话瞧,就是一對一關(guān)聯(lián)。比如學(xué)生表和身份證表寝姿,一條學(xué)生記錄只對應(yīng)于一條身份證記錄交排,一條身份證記錄只對應(yīng)一條學(xué)生記錄,學(xué)生表和身份證表就是一對一關(guān)聯(lián)饵筑。

  • @ToOne:表示實體類A和實體類B是一對一關(guān)聯(lián)
    • joinProperty:該參數(shù)表示兩個實體類的連接屬性

單向關(guān)聯(lián)

A表中持有B表的引用埃篓,而B表沒有持有A表的引用。新建Card實體類:

@Entity
public class Card {
    @Id(autoincrement = true)
    private Long id;

    @Unique
    @NotNull
    private String cardCode;
}

User類更改如下:

@Entity(
        nameInDb = "USERS",
        indexes = {
                @Index(value = "name DESC")
        }
)
public class User {
    @Id(autoincrement = true)
    private Long id;

    private Long cardId;     // 新增的根资,外鍵
    //設(shè)置一對一關(guān)聯(lián)都许,連接屬性是cardId
    @ToOne(joinProperty ="cardId") // 注意該參數(shù)的值
    private Card card;       // 新增的

    @Index(name="usercode_index",unique = true)
    private String usercode;

    @Property(nameInDb = "userName")
    @NotNull
    private String name;

    private String userAddress;

    @Transient
    private int tempUserSign;
}

更改數(shù)據(jù)庫版本號,sync now后嫂冻,make project胶征。在MainActivity中添加以下方法,然后調(diào)用即可:

    // 單向關(guān)聯(lián)插入
    private void insertOneToOne(){
        // 先生成一條Card記錄
        Card card1=new Card();
        card1.setCardCode("434377777");
        cardDao.insert(card1);

        User user1=new User();
        user1.setName("孫悟空");
        user1.setUserAddress("花果山水簾洞");
        user1.setUsercode("001");
        user1.setCard(card1);
        userDao.insert(user1);
    }

    // 單向關(guān)聯(lián)查詢
    private void queryOneToOne(){
        User user=userDao.queryBuilder().where(UserDao.Properties.Name.eq("孫悟空")).build().unique();
        Card card=user.getCard();
        if(user!=null && card!=null){
            Log.d("TAG", "一對一添加記錄桨仿,查詢后的結(jié)果是:\n" + "姓名:" + user.getName()
                    + "\n身份證號" + card.getCardCode() + "\n"
                    + "Card表的id主鍵值為:" + card.getId()+ "\n" 
                    + "User表的外鍵cardId的值為:" + user.getCardId());
        }
    }

雙向關(guān)聯(lián)

Card類更改如下睛低,然后更改數(shù)據(jù)庫版本號和make projectUser類保持不變:

@Entity
public class Card {
    @Id(autoincrement = true)
    private Long id;

    @Unique
    @NotNull
    private String cardCode;

    private Long userId;     // 新增的服傍,外鍵
    //設(shè)置一對一關(guān)聯(lián)
    @ToOne(joinProperty = "userId") // 注意該參數(shù)的值
    private User user;       // 新增的
}

雙向關(guān)聯(lián)的插入稍微不同钱雷,但查詢的思想時一樣的。在MainActivity中添加如下方法:

    private void insertCardOneTOne(){
        User user1=new User();
        user1.setName("孫悟空");
        user1.setUserAddress("花果山水簾洞");
        user1.setUsercode("001");

        Card card1=new Card();
        card1.setCardCode("434377777");

        /* 注意以下代碼的順序 */
        userDao.insert(user1);
        card1.setUser(user1);

        cardDao.insert(card1);
        //補上之前沒有設(shè)置的user1的外鍵值
        user1.setCard(card1);
        //更新user1對象
        userDao.update(user1);

    }

    private void queryCardOneToOne(){
        Card card1=cardDao.queryBuilder().where(CardDao.Properties.CardCode.eq("434377777")).build().unique();
        User user1=card1.getUser();
        if(user1!=null && card1!=null){
            L.d("TAG", "姓名:"+user1.getName()+"\n"
                        +"Card表的id主鍵值:"+card1.getId()+"\n"
                        +"User表的外鍵cardId的值為:"+user1.getCardId());
        }
    }

來個小結(jié)吹零,先來看單向關(guān)聯(lián)罩抗,可以通過一個User對象得到一個Card對象與之對應(yīng),反之不能灿椅。但是套蒂,雙向關(guān)聯(lián)可以做到,這就是它們之間最主要的區(qū)別茫蛹。

一對多關(guān)聯(lián)

兩個表操刀,A表和B表,A表的一條記錄可對應(yīng)B表的多條記錄婴洼,而B表的一條記錄只能對應(yīng)A表的一條記錄骨坑,則B表對A表就是多對一關(guān)聯(lián),而A表對B表就是一對多關(guān)聯(lián)柬采。舉個例子欢唾,班級表的一個班級可對應(yīng)于學(xué)生表的多個學(xué)生且警,而一個學(xué)生只能屬于一個班級,學(xué)生表對班級表就是多對一關(guān)聯(lián)礁遣,班級表對學(xué)生表就是一對多關(guān)聯(lián)振湾。因此,一對多和多對一是相互關(guān)系亡脸。

  • @ToOne:代表“一”
    • joinProperty
  • @ToMany:代表“多”
    • referencedJoinProperty

示例的場景是押搪,一個用戶可以購買多個商品。新建Orders類浅碾,代碼如下:

@Entity
public class Orders {
    @Id(autoincrement = true)
    private Long id;

    private String goodsName;

    private Long userId;//外鍵大州,對于User類的主鍵

    @ToOne(joinProperty = "userId") // 注意該參數(shù)的值
    private User user;
}

User類的更改如下:

@Entity(
        nameInDb = "USERS",
        indexes = {
                @Index(value = "name DESC")
        }
)
public class User {
    @Id(autoincrement = true)
    private Long id;

    private Long cardId;

    //設(shè)置一對一關(guān)聯(lián),連接屬性是cardId
    @ToOne(joinProperty ="cardId")   //注意參數(shù)的值
    private Card card;

    //設(shè)置一對多關(guān)聯(lián)垂谢,連接屬性是Orders類的外鍵userId
    @ToMany(referencedJoinProperty = "userId")   // 注意參數(shù)的值
    private List<Orders> orders;

    @Index(name="usercode_index",unique = true)
    private String usercode;

    @Property(nameInDb = "userName")
    @NotNull
    private String name;

    private String userAddress;

    @Transient
    private int tempUserSign;
}

更改數(shù)據(jù)庫版本號厦画,然后make project,接著在MainActivity中添加如下代碼滥朱,然后直接調(diào)用即可:

    private void insertOneToMany(){
        List<Orders> orderList=new ArrayList<Orders>();
        // 這些數(shù)據(jù)的來源請參考上一章所講的內(nèi)容根暑,因為在上一章中有方法為測試提供數(shù)據(jù)源
        User user1=userDao.queryBuilder().where(UserDao.Properties.Name.eq("孫悟空")).build().unique();
        User user2=userDao.queryBuilder().where(UserDao.Properties.Name.eq("豬八戒")).build().unique();

        Orders order1=new Orders();
        order1.setGoodsName("金箍棒");
        order1.setUser(user1); //設(shè)置外鍵值時,要用setUser()方法徙邻,以確保外鍵值不會出錯

        Orders order2=new Orders();
        order2.setGoodsName("黃金甲");
        order2.setUser(user1);

        Orders order3=new Orders();
        order3.setGoodsName("紫金冠");
        order3.setUser(user1);

        Orders order4=new Orders();
        order4.setGoodsName("紫金冠");
        order4.setUser(user2);

        orderList.add(order1);
        orderList.add(order2);
        orderList.add(order3);
        orderList.add(order4);

        ordersDao.insertInTx(orderList);
    }

     private void queryToManyUserToOrder() {
        List<Orders> ordersList;
        User user1 = userDao.queryBuilder().where(UserDao.Properties.Name.eq("豬八戒")).build().unique();
        
        //直接通過User對象的getOrders()方法獲得此用戶的所有訂單
        ordersList = user1.getOrders();
        Log.d("TAG", user1.getName() + "的訂單內(nèi)容為:");
        
        int i = 0;
        if (ordersList != null) {
            for (Orders order : ordersList) {
                i = i + 1;
                Log.d("TAG", "第" + i + "條訂單的結(jié)果:" + ",id:" + order.getId()
                        + ",商品名:" + order.getGoodsName()
                        + ",用戶名:" + user1.getName());
            }
        }
    }

多對多關(guān)聯(lián)

兩個表排嫌,A表和B表,A表的一條記錄可對應(yīng)于B表的多條記錄缰犁,而B表的一條記錄也對應(yīng)A表的多條記錄淳地,則A表和B表之間就是多對多關(guān)聯(lián)。比如作者表和書表帅容,作者表的一個作者可以寫多本書颇象,而一本書也可以是多個作者,作者表和書表之間就是多對多關(guān)聯(lián)并徘。

  • @ToMany:設(shè)置多對多
  • @JoinEntity:設(shè)置連接中間類
    • entity:中間類遣钳,需要創(chuàng)建
    • sourceProperty:源屬性,就是本類麦乞,而參數(shù)的值就是中間類中代表該類的屬性
    • targetProperty:目標(biāo)屬性蕴茴,就是要關(guān)聯(lián)的類,而參數(shù)的值就是中間類中代表該類的屬性

示例的場景是路幸,一個老師可以教多門課程荐开,一個課程可以也可以由多個老師任教付翁。

新建中間類JoinTeacherWithCourse简肴,代碼如下:

@Entity
public class JoinTeacherWithCourse {
    @Id(autoincrement = true)
    private Long id;

    // 代表老師的id
    private Long tId;

    // 代表課程的id
    private Long cId;
}

新建Teacher類和Course類,代碼如下:

@Entity
public class Teacher {
    @Id(autoincrement = true)
    private Long id;

    private String name;

    // 多對多
    @ToMany
    // 連接兩個多對多實體類的中間類
    @JoinEntity(
            // 中間類類名
            entity = JoinTeacherWithCourse.class,
            // 源屬性百侧,中間類的外鍵砰识,對應(yīng)Teacher類的主鍵
            sourceProperty = "tId",
            // 目標(biāo)屬性能扒,中間類的外鍵,對應(yīng)Course類的主鍵
            targetProperty = "cId"
    )
    private List<Course> courses;
}

@Entity
public class Course {
    @Id(autoincrement = true)
    private Long id;

    private String name;

    //多對多
    @ToMany
    // 連接兩個多對多實體類的中間類
    @JoinEntity(
            // 中間類類名
            entity = JoinTeacherWithCourse.class,
            // 源屬性辫狼,中間類的外鍵初斑,對應(yīng)Course類的主鍵
            sourceProperty = "cId",
            // 目標(biāo)屬性,中間類的外鍵膨处,對應(yīng)Teacher類的主鍵
            targetProperty = "tId"
    )
    private List<Teacher> teachers;
}

更改數(shù)據(jù)庫版本號见秤,然后make project,接著在MainActivity中添加如下代碼:

    // 多對多插入
    private void insertManyToMany() {
        List<Course> courses = new ArrayList<>();
        Course course1 = new Course();
        course1.setName("英語");

        Course course2 = new Course();
        course2.setName("語文");

        Course course3 = new Course();
        course3.setName("數(shù)學(xué)");

        courses.add(course1);
        courses.add(course2);
        courses.add(course3);
        courseDao.insertInTx(courses);

        List<Teacher> teacherList = new ArrayList<>();
        Teacher teacher1 = new Teacher();
        teacher1.setName("孫悟空");

        Teacher teacher2 = new Teacher();
        teacher2.setName("豬八戒");

        Teacher teacher3 = new Teacher();
        teacher3.setName("沙和尚");

        teacherList.add(teacher1);
        teacherList.add(teacher2);
        teacherList.add(teacher3);
        teacherDao.insertInTx(teacherList);

        List<JoinTeacherWithCourse> teacherWithCourses = new ArrayList<>();
        // 悟空教英語
        JoinTeacherWithCourse teacherWithCourse1 = new JoinTeacherWithCourse();
        teacherWithCourse1.setTId(teacher1.getId());
        teacherWithCourse1.setCId(course1.getId());

        // 悟空叫語文
        JoinTeacherWithCourse teacherWithCourse2 = new JoinTeacherWithCourse();
        teacherWithCourse2.setTId(teacher1.getId());
        teacherWithCourse2.setCId(course2.getId());

        // 悟空叫數(shù)學(xué)
        JoinTeacherWithCourse teacherWithCourse3 = new JoinTeacherWithCourse();
        teacherWithCourse3.setTId(teacher1.getId());
        teacherWithCourse3.setCId(course3.getId());

        // 沙和尚教語文
        JoinTeacherWithCourse teacherWithCourse4 = new JoinTeacherWithCourse();
        teacherWithCourse4.setTId(teacher2.getId());
        teacherWithCourse4.setCId(course2.getId());

        teacherWithCourses.add(teacherWithCourse1);
        teacherWithCourses.add(teacherWithCourse2);
        teacherWithCourses.add(teacherWithCourse3);
        teacherWithCourses.add(teacherWithCourse4);
        teacherWithCourseDao.insertInTx(teacherWithCourses);
    }

    // 多對多查詢,通過”教師“找到課程
    private void queryManyToManyT() {
        Teacher teacher = teacherDao.queryBuilder().where(TeacherDao.Properties.Name.eq("孫悟空"))
                .build().unique();
        List<Course> courses = teacher.getCourses();

        if (courses != null) {
            Log.d("TAG", "孫悟空所教的課程:");
            for (Course course : courses) {
                Log.d("TAG", "課程名:" + course.getName());
            }
        }
    }

    // 多對多查詢,通過”課程“找到課程
    private void queryManyToManyC() {
        Course course = courseDao.queryBuilder().where(CourseDao.Properties.Name.eq("語文"))
                .build().unique();
        List<Teacher> teachers = course.getTeachers();

        if (teachers != null) {
            Log.d("TAG", "教語文的老師有:");
            for (Teacher teacher : teachers) {
                Log.d("TAG", "教師名:" + teacher.getName());
            }
        }
    }

注意:要先插入Teacher和Course的記錄真椿,然后才能插入JoinTeacherWithCourse的記錄鹃答。

多表查詢

根據(jù)需求,查詢兩個或兩個以上的表的記錄突硝,要求這些表有關(guān)聯(lián)测摔,也就是本章節(jié)前面所講的內(nèi)容。它的思想和MySQL里的內(nèi)連接解恰,左/右連接一樣锋八。

示例代碼需要用到User、Card和Orders三個類护盈,在前面已經(jīng)創(chuàng)建好了挟纱。測試所用到的數(shù)據(jù)可以直接調(diào)用前面定義好的方法。

先看兩表查詢腐宋,代碼如下:

    // 兩表查詢樊销,購買紫金冠的用戶有
    private void multiQueryTwoTb() {
        QueryBuilder<User> qb = userDao.queryBuilder();
        qb.join(Orders.class, OrdersDao.Properties.UserId)
                .where(OrdersDao.Properties.GoodsName.eq("紫金冠"));
        List<User> users = qb.list();

        if (users != null) {
            for (User u : users) {
                Log.d("TAG", "購買紫金冠的用戶有:" + u.getName());
            }
        }
    }

    // 兩表查詢,用戶是孫悟空所購買的商品有
    private void multiQueryTwoOrders() {
        QueryBuilder<Orders> qb = ordersDao.queryBuilder();
        qb.join(OrdersDao.Properties.UserId, User.class)
                .where(UserDao.Properties.Name.eq("孫悟空"));
        List<Orders> ordersList = qb.list();

        if (ordersList != null) {
            for (Orders o : ordersList) {
                Log.d("TAG", o.getUser().getName() + "購買的商品有:" + o.getGoodsName());
            }
        }
    }

multiQueryTwoTb()方法中join()的源碼:

    /**
     * Expands the query to another entity type by using a JOIN. The primary key property of the primary entity for
     * this QueryBuilder is used to match the given destinationProperty.
     */
    public <J> Join<T, J> join(Class<J> destinationEntityClass, Property destinationProperty) {
        return join(dao.getPkProperty(), destinationEntityClass, destinationProperty);
    }

在這里T表示User類脏款,J表示Orders類围苫,daoUserDao的對象,翻譯過來就是使用USER表(User類)的主鍵屬性去匹配Orders類(destinationEntityClass)的屬性destinationProperty撤师,那為什么不能像multiQueryTwoOrders()方法中join()那樣寫呢剂府?第一,USER表中沒有外鍵剃盾,ORDERS 表有外鍵腺占;第二,是USER表去連接ORDERS表的痒谴,傳遞的值應(yīng)該是Orders類中的屬性衰伯。

multiQueryTwoOrders()方法中join()的源碼:

    /**
     * Expands the query to another entity type by using a JOIN. The given sourceProperty is used to match the primary
     * key property of the given destinationEntity.
     */
    public <J> Join<T, J> join(Property sourceProperty, Class<J> destinationEntityClass) {
        AbstractDao<J, ?> destinationDao = (AbstractDao<J, ?>) dao.getSession().getDao(destinationEntityClass);
        Property destinationProperty = destinationDao.getPkProperty();
        return addJoin(tablePrefix, sourceProperty, destinationDao, destinationProperty);
    }

在這里T表示Orders類,J表示User類积蔚,翻譯過來就是使用ORDERS表的外鍵屬性sourceProperty去匹配USER表的主鍵意鲸,也就是destinationEntityClass
三表查詢的代碼如下:

    // 查詢買了紫金冠的客戶的身份證號
    private void queryThreeTb() {
        QueryBuilder<Card> qb = cardDao.queryBuilder()
                .where(CardDao.Properties.CardCode.like("1987%"));
        Join user = qb.join(CardDao.Properties.UserId, User.class);
        Join order = qb.join(user, UserDao.Properties.Id, Orders.class, OrdersDao.Properties.UserId);
        order.where(OrdersDao.Properties.GoodsName.eq("紫金冠"));
        List<Card> cardList = qb.list();

        if (cardList != null) {
            Log.d("TAG", "買了紫金冠的身份證前四位是1987的用戶:");
            for (Card card : cardList) {
                Log.d("TAG", "身份證:" + card.getCardCode() + "名字:" + card.getUser().getName());
            }
        }
    }

先通過CARD表連接USER表,再通過USER表連接ORDERS表怎顾,這樣三表就連接起來了读慎。那為什么CARD表不能直接和ORDERS表連接起來呢?那是因為它們之間并沒有關(guān)聯(lián)槐雾,或者說能使它們連接起來的屬性夭委。

join()方法的重載方式很多,在這就不一一列出來了募强,讀者可以直接查看源碼株灸,需要根據(jù)場景選擇。對于更多的表之間的連接擎值,以此類推蚂且,多寫幾個join就可以了。

總結(jié)

至此幅恋,多表關(guān)聯(lián)和多表查詢就講完了杏死。

最終源碼
GreenDAO 3.2.2 簡單入門(一)增刪改查
GreenDAO 3.2.2 簡單入門(三)數(shù)據(jù)庫升級

內(nèi)容補充

補充的內(nèi)容是關(guān)于MySQL的多表連接的,對于GreenDAO的多表關(guān)聯(lián)的理解有一定的幫助。下圖是所用到三張表的結(jié)構(gòu):


user表.png
res_path表.png

res_user表.png

其場景是記錄用戶訪問了哪些路徑下的資源捆交,類似打卡淑翼,而res_user表是中間表。其語法如下所示:

select column(需指明那個表的列) from table1(使用左連接還是右連接是相對這個表而言的) left/right outer join table2(需連接的表) on condition [可以繼續(xù)接where品追、group by等語句對table1而不是table2表進一步約束玄括,是查詢結(jié)果更準(zhǔn)確]

現(xiàn)在有一個需求:查詢用戶是13077581222和日期是2019-06-16的資源路徑,也就是res_path表的path肉瓦。

// 左連接遭京,改成右連接,內(nèi)連接也可以查詢成功
select `enword`.`res_path`.path from `enword`.`res_user` left outer join `enword`.`res_path` on `enword`.`res_user`.resId = `enword`.`res_path`.id where `enword`.`res_user`.date = '2019-06-16'and `enword`.`res_user`.userId = (select id from `enword`.`user` where name = '13077581227')
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泞莉,一起剝皮案震驚了整個濱河市哪雕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鲫趁,老刑警劉巖斯嚎,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挨厚,居然都是意外死亡堡僻,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門疫剃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钉疫,“玉大人,你說我怎么就攤上這事巢价∩螅” “怎么了固阁?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵咨油,是天一觀的道長您炉。 經(jīng)常有香客問我柒爵,道長役电,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任棉胀,我火速辦了婚禮法瑟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘唁奢。我一直安慰自己霎挟,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布麻掸。 她就那樣靜靜地躺著酥夭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脊奋。 梳的紋絲不亂的頭發(fā)上熬北,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音诚隙,去河邊找鬼讶隐。 笑死,一個胖子當(dāng)著我的面吹牛久又,可吹牛的內(nèi)容都是我干的巫延。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼地消,長吁一口氣:“原來是場噩夢啊……” “哼炉峰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脉执,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤讲冠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后适瓦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竿开,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年玻熙,在試婚紗的時候發(fā)現(xiàn)自己被綠了否彩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡嗦随,死狀恐怖列荔,靈堂內(nèi)的尸體忽然破棺而出敬尺,到底是詐尸還是另有隱情,我是刑警寧澤贴浙,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布砂吞,位于F島的核電站,受9級特大地震影響崎溃,放射性物質(zhì)發(fā)生泄漏蜻直。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一袁串、第九天 我趴在偏房一處隱蔽的房頂上張望概而。 院中可真熱鬧,春花似錦囱修、人聲如沸赎瑰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽餐曼。三九已至,卻和暖如春鲜漩,著一層夾襖步出監(jiān)牢的瞬間源譬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工宇整, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓶佳,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓鳞青,卻偏偏與公主長得像霸饲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子臂拓,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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