Realm使用文檔

前提

Android Studio >= 1.5.1
A recent version of the Android SDK.
JDK version >=7.
支持Api>9的Android版本

環(huán)境配置

Step 1: Add the following class path dependency to the project level build.gradle file.

buildscript { 
    repositories {
     jcenter()
 }
     dependencies 
    { 
    classpath "io.realm:realm-gradle-plugin:2.3.1" 
    }
}

The project level build.gradle
file is located here:

Project level build.gradle file
Project level build.gradle file

Step 2: Apply the realm-android
plugin to the top of application level build.gradle
file.
apply plugin: 'realm-android'

The application level build.gradle

is located here:
Application level build.gradle file
Application level build.gradle file

Models

Realm model classes are created by extending the RealmObject
base class.

public class User extends RealmObject { 
   private String name; 
   private int age;
   @Ignore 
   private int sessionId; // Standard getters & setters generated by your IDE…          
   public String getName() {
       return name; 
   }
   public void setName(String name) { 
       this.name = name; 
   } 
   public int getAge() { 
       return age; 
   } 
   public void setAge(int age) { 
       this.age = age; 
   } 
   public int getSessionId() { 
       return sessionId; 
   } 
   public void setSessionId(int sessionId) { 
       this.sessionId = sessionId; 
   }
}

一個Realm的類支持 public,protected 和 private和自定義方法

public class User extends RealmObject { 
    public String name; 
    public boolean hasLongName() { 
        return name.length() > 7; 
    } 
    @Override 
    public boolean equals(Object o) {
     // Custom equals comparison 
    }
  }

Relationships

任意兩個 RealmObjects 可以一起使用

  public class Email extends RealmObject { 
    private String address; 
    private boolean active; // ... setters and getters left out
  }
  public class Contact extends RealmObject { 
    private String name;
    private Email email; // ... setters and getters left out
  }

多對一
簡單地聲明一個屬性的類型是 RealmObject的子類 :

public class Contact extends RealmObject {
   private Email email; // Other fields…
}

每一個contact對象只有0或者1email的實例幌衣,如果設置RealmObject的字段為空稻扬,會把兩個表的關聯(lián)取消会前,但不會刪除相應表的數據

多對多

你可以建立幾個對象和一個對象的關系通過使用RealmList<T> 的字段兵迅。
如下:

public class Contact extends RealmObject { 
   public String name; 
   public RealmList<Email> emails;
}
public class Email extends RealmObject { 
    public String address; 
    public boolean active;
}

RealmList 基本上是RealmObject的容器蝴光,RealmList就像Java中的List一樣滑蚯【⌒ǎ可以無限制的使用同一個對象兩次或多次在不同的RealmList中繁涂,并且你可以使用這個去建立一對多或者多對多的關系盹靴。
你可以創(chuàng)建對象炸茧,然后使用RealmList.add()去把Email對象添加到Contact對象中:

 realm.executeTransaction(new Realm.Transaction() { 
    @Override 
    public void execute(Realm realm) { 
      Contact contact = realm.createObject(Contact.class); 
      contact.name = "John Doe"; 
      Email email1 = realm.createObject(Email.class); 
      email1.address = "john@example.com"; 
      email1.active = true; 
      contact.emails.add(email1); 
      Email email2 = realm.createObject(Email.class); 
      email2.address = "jd@example.com"; 
      email2.active = false; 
      contact.emails.add(email2); 
  }
});

把RealmList的字段設置為null會清空list,list會變?yōu)榭?長度為0)瑞妇,但對象并不會被刪除。
RealmList的getter方法永遠都不會返回為空梭冠,但返回的對象會一直是長度為0的list辕狰。

鏈式查詢

可以查詢鏈接或關系。
Consider the model below:

public class Person extends RealmObject { 
  private String id; 
  private String name; 
  private RealmList<Dog> dogs; // getters and setters
}
public class Dog extends RealmObject { 
  private String id; 
  private String name; 
  private String color; // getters and setters
}

每個Person的對象有不同dog的關系像如下表中:


Table Diagram
Table Diagram

我們查找某個Person通過鏈式查詢
// persons => [U1,U2]

RealmResults<Person> persons = realm.where(Person.class) .equalTo("dogs.color", "Brown") .findAll();

這個查詢會獲得所有Persons的dogs的color屬性為Brown的

或者通過persons的對象查詢中含有的Dog

persons.get(0).getDogs(); // => [A,B]
persons.get(1).getDogs(); // => [B,C,D]

這可以通過以下兩個查詢進一步檢查控漠。

// r1 => [U1,U2] 
RealmResults<Person> r1 = realm.where(Person.class) .equalTo("dogs.name", "Fluffy") .findAll();

// r2 => [U1,U2]
RealmResults<Person> r2 = r1.where().equalTo("dogs.color", "Brown") .findAll();

Notice how the first query returned both Person
objects because the condition matched both persons. Each Person
in the query result contains a list of Dog
objects - all of their dog objects (even ones that do not fulfill the original query condition). Remember, we’re searching for people who have particular kinds of dogs (names and colors), not the actual dogs themselves. Therefore, the second query will be evaluated against the first Person
query result (r1
) and each of the Person
s dogs. The second query also matches both persons as well, but this time it’s because of the color of the dog.
Let’s dig a little deeper to help solidify this concept. Please review the following example:

// r1 => [U1,U2]
RealmResults<Person> r1 = realm.where(Person.class) .equalTo("dogs.name", "Fluffy") .equalTo("dogs.color", "Brown") .findAll();

// r2 => [U2]
RealmResults<Person> r2 = realm.where(Person.class) .equalTo("dogs.name", "Fluffy").findAll()
                               .where() .equalTo("dogs.color", "Brown").findAll()
                               .where() .equalTo("dogs.color", "Yellow").findAll();

第一句的查詢?yōu)槁叮檎宜蠵erson中dogs的“name”為“Fluffy”并且dogs的"color"為”Brown“的Person數據,第二句查詢?yōu)椴樵僤ogs的“name”為“Fluffy”盐捷,dogs的color為"Brown"和dogs的color為"Yellow"的Person集合

寫(Writes)

所有寫的操作(添加偶翅,修改,和移除對象)必須使用事務(transaction)碉渡。一個transaction可以被提交或者被取消聚谁,如果提交了,所有的改變都會更新到磁盤上滞诺。如果取消transaction形导,所有的改變都會取消。transaction的使用是線程安全的习霹。

// Obtain a Realm instance
Realm realm = Realm.getDefaultInstance()
realm.beginTransaction();//... add or update objects here ...
realm.commitTransaction();

當你開啟了事務后朵耕,你可以使用cancelTransaction來丟棄之前的更改

realm.beginTransaction();
User user = realm.createObject(User.class);// ...
realm.cancelTransaction();

請記住transactions是堵塞線程的,這會很容易導致ANR的錯誤淋叶,如果你在UI線程中和子線程中都創(chuàng)建transction了阎曹。為了避免ANR,請使用異步的transaction煞檩,當在UI線程中創(chuàng)建transanction時处嫌。

創(chuàng)建對象

創(chuàng)建對象請使用以下方法:

realm.beginTransaction();
User user = realm.createObject(User.class); // Create a new object
user.setName("John");
user.setEmail("john@corporation.com");
realm.commitTransaction();

或者使用realm.copyToRealm():

User user = new User("John");
user.setEmail("john@corporation.com");// Copy the object to Realm. Any further     changes must happen on realmUser
realm.beginTransaction();
User realmUser = realm.copyToRealm(user);
realm.commitTransaction();

事務堵塞(Transaction blocks)

除了 realm.beginTransaction(), realm.commitTransaction(), and realm.cancelTransaction(),你還可以使用realm.executeTransaction(),這個方法會自動調用begin/commit,然后發(fā)生錯誤時形娇,會調用cancel

realm.executeTransaction(new Realm.Transaction() { 
  @Override 
  public void execute(Realm realm) { 
  User user = realm.createObject(User.class); 
  user.setName("John"); 
  user.setEmail("john@corporation.com"); 
  }
});

異步的事務(Asynchronous Transactions)

As transactions are blocked by other transactions it can be an advantage to do all writes on a background thread in order to avoid blocking the UI thread. By using an asynchronous transaction, Realm will run that transaction on a background thread and report back when the transaction is done.

realm.executeTransactionAsync(new Realm.Transaction() { 
    @Override 
    public void execute(Realm bgRealm) { 
    User user = bgRealm.createObject(User.class); 
    user.setName("John"); 
    user.setEmail("john@corporation.com"); 
    }},
    new Realm.Transaction.OnSuccess() { 
    @Override 
    public void onSuccess() {
     // Transaction was a success. 
    } }, 
    new Realm.Transaction.OnError() { 
    @Override 
    public void onError(Throwable error) { 
    // Transaction failed and was automatically canceled. 
    } 
  });

OnSuccess和OnError的回調是可選的锰霜,但是必須使用在創(chuàng)建了Looper的線程中

RealmAsyncTask transaction = realm.executeTransactionAsync(new  Realm.Transaction() { 
    @Override 
    public void execute(Realm bgRealm) { 
     User user = bgRealm.createObject(User.class); 
     user.setName("John");
     user.setEmail("john@corporation.com"); 
     } }, null);

異步事務由RealmAsyncTask的對象表示,在退出Activity/Fragment 時桐早,而transaction操作未完成癣缅,就可以使用這個對象進行取消事務操作,避免頁面崩潰

public void onStop () { 
   if (transaction != null && !transaction.isCancelled()) {  
       transaction.cancel();
    }
}

查詢

Using the User class -

public class User extends RealmObject { 
  @PrimaryKey 
  private String name; 
  private int age; 
  @Ignore 
  private int sessionId; // Standard getters & setters generated by your IDE… 
  public String getName() {     
     return name; 
  }
  public void setName(String name) { 
    this.name = name; 
  }
  public int getAge() { 
    return age; 
  }
  public void setAge(int age) {
   this.age = age; 
  }
  public int getSessionId() {
   return sessionId; 
  }
  public void setSessionId(int sessionId) {
   this.sessionId = sessionId; 
  }
}  

為了查找所有的users中name為“John”或“Peter”:

// Build the query looking at all users:    
RealmQuery<User> query = realm.where(User.class);
// Add query conditions:
query.equalTo("name", "John");
query.or().equalTo("name", "Peter");
// Execute the query:
RealmResults<User> result1 = query.findAll();

// 或者鏈式調用
RealmResults<User> result2 = realm.where(User.class) 
                                  .equalTo("name", "John")    
                                  .or() 
                                  .equalTo("name", "Peter")
                                  .findAll();

這會返回一個RealmResults的對象哄酝,這包含了姓名為John或Peter的user友存。

RealmResults繼承自AbstractList,跟普通的List有相同的特性,例如陶衅,你可以通過索引來查詢某個對象屡立,如果沒有匹配的,RealmResults不會為null搀军,但size()為0膨俐。
如果你想進行更改或者刪除對象在RealmResults中勇皇,你必須使用transaction。

條件查詢
以下的條件操作符是支持的:

 between(), greaterThan(), lessThan(), greaterThanOrEqualTo() & lessThanOrEqualTo()
 equalTo() & notEqualTo()
 contains(), beginsWith()& endsWith()
 isNull() & isNotNull()
 isEmpty() & isNotEmpty()

不是所有的數據的類型都支持以上條件操作焚刺,請查詢相關RealmQueryAPI.

邏輯運算符

每個條件符的都是默認為一同使用敛摘,如果要使用or的邏輯,必須顯示調用or()操作符

Using the User class -

public class User extends RealmObject { 
    @PrimaryKey 
    private String name; 
    private int age; 
    @Ignore 
    private int sessionId; // Standard getters & setters generated by your IDE… 
    public String getName() { 
        return name; 
    }
    public void setName(String name) { 
        this.name = name; 
    }
    public int getAge() { 
        return age; 
    }
    public void setAge(int age) {
         this.age = age; 
    } 
    public int getSessionId() {
         return sessionId;
    } 
    public void setSessionId(int sessionId) {
         this.sessionId = sessionId; 
    }
}

You can also group conditions with “parentheses” to specify order of evaluation: beginGroup()
is your “l(fā)eft parenthesis” and endGroup()
your “right parenthesis”:

RealmResults<User> r = realm.where(User.class) 
.greaterThan("age", 10) //implicit AND
.beginGroup()
  .equalTo("name", "Peter") 
  .or()
  .contains("name", "Jo")
.endGroup() 
.findAll();

Furthermore, it is possible to negate a condition with not(). The not() operator can be used with beginGroup()/endGroup() to negate sub-conditions only.

排序

Once you have done your query, you can sort the results like this:

RealmResults<User> result = realm.where(User.class).findAll();
result = result.sort("age"); // Sort ascending
result = result.sort("age", Sort.DESCENDING);

鏈式查詢

你可以高效地使用鏈式操作去查詢你的數據:

RealmResults<Person> teenagers = realm.where(Person.class).between("age", 13,20).findAll();
Person firstJohn = teenagers.where().equalTo("name", "John").findFirst();

You can also perform chained queries on child objects as well. Assume the above Person object has a list of Dog objects.

public class Dog extends RealmObject { 
    private int age; // getters & setters ...
}
public class Person extends RealmObject { 
    private int age; 
    private RealmList<Dog> dogs; // getters & setters ...
}

You can query for all people who are between the age of 13 and 20 who have at least one dog which is 1 year old:

RealmResults<Person> teensWithPups = realm.where(Person.class)
                                          .between("age",   13, 20)
                                          .equalTo("dogs.age", 1)
                                          .findAll();

Note that query chains are built on RealmResults, not RealmQuery. If you add more conditions to an existing RealmQuery, then you are modifying the query, not the chains. Read more about link queries.

自動更新 結果(Auto-Updating Results)

RealmResults 是會自己進行更新的乳愉,這意味著不需要重新進行查詢操作兄淫,修改對象的操作會直接影響到之前查詢的結果

  final RealmResults<Dog> puppies = realm.where(Dog.class).lessThan("age", 2).findAll();
  puppies.size(); // => 0
  realm.executeTransaction(new Realm.Transaction() { 
    @Override  
    public void execute(Realm realm) { 
       Dog dog = realm.createObject(Dog.class);
       dog.setName("Fido");
       dog.setAge(1); 
    }
  });
  puppies.addChangeListener(new RealmChangeListener() { 
    @Override 
    public void onChange(RealmResults<Dog> results) { 
    // results and puppies point are both up to date 
     results.size(); // => 1
     puppies.size(); // => 1   
    }
  });

這適用于所有RealmResults:所有對象、過濾和鏈接蔓姚。
這個特性不單止可以使Realm快和高效率捕虽,也可以使代碼更簡潔更有效。
你可以去 Realm notifications了解什么時候你的UI數據會進行更新坡脐。

聚合(Aggregation)[]

RealmResults 有以下方法:

RealmResults<User> results = realm.where(User.class).findAll();
long sum = results.sum("age").longValue();
long min = results.min("age").longValue();
long max= results.max("age").longValue();
double average = results.average("age");
long matches = results.size();

迭代(Iterations)

遍歷RealmResults里面的所有對象
你可以利用Iterable的特性:

RealmResults<User> results = realm.where(User.class).findAll();
for (User u : results) {
 // ... do something with the object ...
}

或者使用常規(guī)的循環(huán)

RealmResults<User> results = realm.where(User.class).findAll();
for (int i = 0; i < results.size(); i++) { 
  User u = results.get(i); // ... do something with the object ...
}

RealmResults會自動地進行更新泄私,但是還會有很小的幾率在獲取對象后,不能匹配查詢或者刪除后的結果

final RealmResults<User> users = getUsers();
realm.executeTransaction(new Realm.Transaction() { 
@Override 
  public void execute(Realm realm) { 
    users.get(0).deleteFromRealm(); // 非指向性刪除對象
  }
});
for (User user : users) { 
  showUser(user); // 會導致crash
}

不要使用 deleteFromRealm()在RealmResults:

final RealmResults<User> users = getUsers();
realm.executeTransaction(new Realm.Transaction() {
  @Override 
  public void execute(Realm realm) { 
    users.deleteFromRealm(0); // Delete and remove object directly 
  }
});
for (User user : users) { 
  showUser(user); // Deleted user will not be shown
}

刪除(Deletion)

你可以在進行查詢后進行刪除:

// obtain the results of a query 
final RealmResults<Dog> results = realm.where(Dog.class).findAll();
// All changes to data must happen in a transaction
realm.executeTransaction(new Realm.Transaction() { 
  @Override 
  public void execute(Realm realm) {
   // remove single match 
  results.deleteFirstFromRealm();    
  results.deleteLastFromRealm(); 
  // remove a single object 
  Dog dog = results.get(5); 
  dog.deleteFromRealm(); 
  // Delete all matches 
  results.deleteAllFromRealm(); 
  }
});

異步地查詢(Asynchronous Queries)

查詢可以使用子線程

大部分地Realm的同步查詢操作是非嘲ご耄快的挖滤,即使是在UI線程中崩溪。但是對于很復雜的查詢或者很大數據的查詢浅役,在子線程中進行查詢會更好

Example: finding users with name “John” or “Peter”

Create the query
RealmResults<User> result = realm.where(User.class) 
                                 .equalTo("name", "John")
                                 .or() 
                                 .equalTo("name", "Peter") 
                                 .findAllAsync();

這個查詢會在子線程中進行,并且查詢完畢后伶唯,會立刻返回RealmResults的對象
如果你想響應查詢完成后的對象觉既,你可以注冊一個RealmChangeListener

注冊一個回調

private RealmChangeListener callback = new RealmChangeListener() {
    @Override
    public void onChange(RealmResults<User> results) {
        // called once the query complete and on every update
    }
 };

public void onStart() {
    RealmResults<User> result = realm.where(User.class).findAllAsync();
    result.addChangeListener(callback);
}

請記得要注銷任何一個listener在Acitvity或Fragment中,以避免內存泄漏

public void onStop () {
    result.removeChangeListener(callback); // remove a particular listener
    // or
    result.removeChangeListeners(); // remove all registered listeners
}

檢測查詢是否完成

 RealmResults<User> result = realm.where(User.class).findAllAsync();
    if (result.isLoaded()) {
   // Results are now available
 }
同步地調用isLoaded()會一直返回true

使用異步檢測查詢(Force load an asynchronous query)

你可以直接等待查詢的結果乳幸。這會堵塞你當前的線程瞪讼,再次調用同步查詢即可

RealmResults<User> result = realm.where(User.class).findAllAsync();
result.load() // be careful, this will block the current thread until it returns

Realms

請在Application的子類中進行初始化:

public class MyApplication extends Application { 
  @Override 
  public void onCreate() { 
     super.onCreate(); 
     Realm.init(this);
   }
}

Realm的配置(Configuring a Realm)

最簡單地配置:

RealmConfiguration config = new RealmConfiguration.Builder().build();

一般我們會進行這樣的配置:

// The RealmConfiguration is created using the builder pattern.
// The Realm file will be located in Context.getFilesDir() with name "myrealm.realm"
RealmConfiguration config = new RealmConfiguration.Builder()
  .name("myrealm.realm")
  .encryptionKey(getKey())
  .schemaVersion(42)
  .modules(new MySchemaModule())
  .migration(new MyMigration())
  .build();
// Use the config
Realm realm = Realm.getInstance(config);

你也可以擁有不同的RealmConfigurations。以這種方式粹断,你可以獨立地控制每個Realm版本符欠,schema和位置

RealmConfiguration myConfig = new RealmConfiguration.Builder()
  .name("myrealm.realm")
  .schemaVersion(2)
  .modules(new MyCustomSchema())
  .build();

RealmConfiguration otherConfig = new RealmConfiguration.Builder()
  .name("otherrealm.realm")
  .schemaVersion(5)
  .modules(new MyOtherSchema())
  .build();

Realm myRealm = Realm.getInstance(myConfig);
Realm otherRealm = Realm.getInstance(otherConfig);

通過調用Realm.getPath()可以獲得Realm的絕對路徑

默認地配置(The Default RealmConfiguration)

RealmConfiguration會被設置為默認的configuration,設置一個默認的configuration在你自己的Application中

public class MyApplication extends Application { 
  @Override 
  public void onCreate() {
     super.onCreate(); 
    // The Realm file will be located in Context.getFilesDir() with name "default.realm"                 
    Realm.init(this); 
    RealmConfiguration config = new RealmConfiguration.Builder().build();          
    Realm.setDefaultConfiguration(config); 
  }
}

public class MyActivity extends Activity { 
     @Override 
     protected void onCreate(Bundle savedInstanceState) {                                       
       super.onCreate(savedInstanceState);
       Realm realm = Realm.getDefaultInstance(); 
       try { 
            // ... Do something ...
       }finally { 
           realm.close(); 
       }
     }
}

In-Memory Realm

定義一個不需要持久化的Realm:

RealmConfiguration myConfig = new RealmConfiguration.Builder().name("myrealm.realm") 
                                                              .inMemory() 
                                                              .build();

這會創(chuàng)建一個保存在內存中而不保存在磁盤中的Realm對象,In-memory Realms會使用磁盤內存如果內存過低時瓶埋,但Realm關閉時希柿,會刪除所有數據

數據庫遷移(Migrations)

如果數據庫要進行升級,
This can be avoided by setting the schema version and migration code in RealmConfiguration
.

RealmConfiguration config = new RealmConfiguration.Builder()
    .schemaVersion(2) // Must be bumped when the schema changes
    .migration(new MyMigration()) // Migration to run instead of throwing an exception
    .build()

使用自定義的Migration,可以方便進行舊版本數據的操作养筒,如下:

// Example migration adding a new class
RealmMigration migration = new RealmMigration() {
  @Override
  public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {

     // DynamicRealm exposes an editable schema
     RealmSchema schema = realm.getSchema();

     // Migrate to version 1: Add a new class.
     // Example:
     // public Person extends RealmObject {
     //     private String name;
     //     private int age;
     //     // getters and setters left out for brevity
     // }
     if (oldVersion == 0) {
        schema.create("Person")
            .addField("name", String.class)
            .addField("age", int.class);
        oldVersion++;
     }

     // Migrate to version 2: Add a primary key + object references
     // Example:
     // public Person extends RealmObject {
     //     private String name;
     //     @PrimaryKey
     //     private int age;
     //     private Dog favoriteDog;
     //     private RealmList<Dog> dogs;
     //     // getters and setters left out for brevity
     // }
     if (oldVersion == 1) {
        schema.get("Person")
            .addField("id", long.class, FieldAttribute.PRIMARY_KEY)
            .addRealmObjectField("favoriteDog", schema.get("Dog"))
            .addRealmListField("dogs", schema.get("Dog"));
         oldVersion++;
     }
  }
}

如果是測試階段,使用以下的配置進行測試:

RealmConfiguration config = new RealmConfiguration.Builder() 
                                  .deleteRealmIfMigrationNeeded()
                                  .build();

author lxw
date 2017.2.15

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末曾撤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子晕粪,更是在濱河造成了極大的恐慌挤悉,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巫湘,死亡現(xiàn)場離奇詭異装悲,居然都是意外死亡昏鹃,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門诀诊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盆顾,“玉大人,你說我怎么就攤上這事畏梆∧埽” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵奠涌,是天一觀的道長宪巨。 經常有香客問我,道長溜畅,這世上最難降的妖魔是什么捏卓? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮慈格,結果婚禮上怠晴,老公的妹妹穿的比我還像新娘。我一直安慰自己浴捆,他們只是感情好蒜田,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著选泻,像睡著了一般冲粤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上页眯,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天梯捕,我揣著相機與錄音,去河邊找鬼窝撵。 笑死傀顾,一個胖子當著我的面吹牛,可吹牛的內容都是我干的碌奉。 我是一名探鬼主播短曾,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼道批!你這毒婦竟也來了错英?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤隆豹,失蹤者是張志新(化名)和其女友劉穎椭岩,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡判哥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年献雅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塌计。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡挺身,死狀恐怖,靈堂內的尸體忽然破棺而出锌仅,到底是詐尸還是另有隱情章钾,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布热芹,位于F島的核電站贱傀,受9級特大地震影響,放射性物質發(fā)生泄漏伊脓。R本人自食惡果不足惜府寒,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望报腔。 院中可真熱鬧株搔,春花似錦、人聲如沸纯蛾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茅撞。三九已至帆卓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間米丘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工糊啡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拄查,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓棚蓄,卻偏偏與公主長得像堕扶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子梭依,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內容