MyBatis學(xué)習(xí)筆記

文章內(nèi)容來源自官方文檔喉酌,后期會加入例子說明以及使用中的細(xì)節(jié)問題孙蒙。

首先是一張大又全:


MyBatis.png

一飞蹂、Mapper映射文件說明

1、完整的Mapper映射文件結(jié)構(gòu)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.dao.×××Mapper">
<!--下面是映射文件頂級元素肃廓,
在實際使用中智厌,官方建議按照這個順序來進行定義-->
    <cache>...</cache>
    <cache-ref />
    <resultMap >...</resultMap>
    <sql >...</sql>
    <insert >...</insert>
    <update >...</update>
    <delete >...</delete>
    <select >...</select>
</mapper>

其中:

  • mapper元素中的namespace是用于綁定Dao接口的,當(dāng)通過namespace綁定接口后盲赊,就不必寫接口實現(xiàn)類铣鹏,mybatis會通過該綁定自動找到對應(yīng)要執(zhí)行的SQL語句,生成對應(yīng)的接口實現(xiàn)方法哀蘑。
  • 頂級元素說明:
    cache – 設(shè)置命名空間的緩存配置吝沫。
    cache-ref –引用其他命名空間緩存配置。
    resultMap – 是最復(fù)雜也是最強大的元素递礼,用來描述如何從數(shù)據(jù)庫結(jié)果集中來加載對象惨险。
    sql – 可被其他語句引用的可重用語句塊。
    insert – 映射插入語句
    update – 映射更新語句
    delete – 映射刪除語句
    select – 映射查詢語句

2脊髓、select元素

  • 元素屬性
<select
  id="selectPerson"
  parameterType="int"
  parameterMap="deprecated"
  resultType="hashmap"
  resultMap="personResultMap"
  flushCache="false"
  useCache="true"
  timeout="10000"
  fetchSize="256"
  statementType="PREPARED"
  resultSetType="FORWARD_ONLY">
屬性 描述
id 在命名空間中唯一的標(biāo)識符辫愉,可以被用來引用這條語句。
parameterType 將會傳入這條語句的參數(shù)類的完全限定名或別名将硝。這個屬性是可選的恭朗,因為 MyBatis 可以通過 TypeHandler 推斷出具體傳入語句的參數(shù),默認(rèn)值為 unset依疼。
parameterMap 這是引用外部 parameterMap 的已經(jīng)被廢棄的方法痰腮。使用內(nèi)聯(lián)參數(shù)映射和 parameterType 屬性。
resultType 從這條語句中返回的期望類型的類的完全限定名或別名律罢。注意如果是集合情形膀值,那應(yīng)該是集合可以包含的類型,而不能是集合本身误辑。使用 resultType 或 resultMap沧踏,但不能同時使用。
resultMap 外部 resultMap 的命名引用巾钉。結(jié)果集的映射是 MyBatis 最強大的特性翘狱,對其有一個很好的理解的話,許多復(fù)雜映射的情形都能迎刃而解砰苍。使用 resultMap 或 resultType潦匈,但不能同時使用阱高。
flushCache 將其設(shè)置為 true,任何時候只要語句被調(diào)用茬缩,都會導(dǎo)致本地緩存和二級緩存都會被清空赤惊,默認(rèn)值:false。
useCache 將其設(shè)置為 true寒屯,將會導(dǎo)致本條語句的結(jié)果被二級緩存,默認(rèn)值:對 select 元素為 true黍少。
timeout 這個設(shè)置是在拋出異常之前寡夹,驅(qū)動程序等待數(shù)據(jù)庫返回請求結(jié)果的秒數(shù)。默認(rèn)值為 unset(依賴驅(qū)動)厂置。
fetchSize 這是嘗試影響驅(qū)動程序每次批量返回的結(jié)果行數(shù)和這個設(shè)置值相等菩掏。默認(rèn)值為 unset(依賴驅(qū)動)。
statementType STATEMENT昵济,PREPARED 或 CALLABLE 的一個智绸。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement访忿,默認(rèn)值:PREPARED瞧栗。
resultSetType FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一個海铆,默認(rèn)值為 unset (依賴驅(qū)動)迹恐。
databaseId 如果配置了 databaseIdProvider,MyBatis 會加載所有的不帶 databaseId 或匹配當(dāng)前 databaseId 的語句卧斟;如果帶或者不帶的語句都有殴边,則不帶的會被忽略。
resultOrdered 這個設(shè)置僅針對嵌套結(jié)果 select 語句適用:如果為 true珍语,就是假設(shè)包含了嵌套結(jié)果集或是分組了锤岸,這樣的話當(dāng)返回一個主結(jié)果行的時候,就不會發(fā)生有對前面結(jié)果集的引用的情況板乙。這就使得在獲取嵌套的結(jié)果集的時候不至于導(dǎo)致內(nèi)存不夠用是偷。默認(rèn)值:false。
resultSets 這個設(shè)置僅對多結(jié)果集的情況適用募逞,它將列出語句執(zhí)行后返回的結(jié)果集并每個結(jié)果集給一個名稱晓猛,名稱是逗號分隔的。

3凡辱、insert, update 和 delete

數(shù)據(jù)變更語句 insert戒职,update 和 delete 的實現(xiàn)非常接近:

<insert
  id="insertAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  keyProperty=""
  keyColumn=""
  useGeneratedKeys=""
  timeout="20">

<update
  id="updateAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  timeout="20">

<delete
  id="deleteAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  timeout="20">
屬性 描述
id 命名空間中的唯一標(biāo)識符,可被用來代表這條語句透乾。
parameterType 將要傳入語句的參數(shù)的完全限定類名或別名洪燥。這個屬性是可選的磕秤,因為 MyBatis 可以通過 TypeHandler 推斷出具體傳入語句的參數(shù),默認(rèn)值為 unset捧韵。
flushCache 將其設(shè)置為 true市咆,任何時候只要語句被調(diào)用,都會導(dǎo)致本地緩存和二級緩存都會被清空再来,默認(rèn)值:true(對應(yīng)插入蒙兰、更新和刪除語句)。
timeout 這個設(shè)置是在拋出異常之前芒篷,驅(qū)動程序等待數(shù)據(jù)庫返回請求結(jié)果的秒數(shù)搜变。默認(rèn)值為 unset(依賴驅(qū)動)。
statementType STATEMENT针炉,PREPARED 或 CALLABLE 的一個挠他。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement篡帕,默認(rèn)值:PREPARED殖侵。
useGeneratedKeys (僅對 insert 和 update 有用)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數(shù)據(jù)庫內(nèi)部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關(guān)系數(shù)據(jù)庫管理系統(tǒng)的自動遞增字段),默認(rèn)值:false镰烧。
keyProperty (僅對 insert 和 update 有用)唯一標(biāo)記一個屬性拢军,MyBatis 會通過 getGeneratedKeys 的返回值或者通過 insert 語句的 selectKey 子元素設(shè)置它的鍵值,默認(rèn):unset怔鳖。如果希望得到多個生成的列朴沿,也可以是逗號分隔的屬性名稱列表。
keyColumn (僅對 insert 和 update 有用)通過生成的鍵值設(shè)置表中的列名败砂,這個設(shè)置僅在某些數(shù)據(jù)庫(像 PostgreSQL)是必須的赌渣,當(dāng)主鍵列不是表中的第一列的時候需要設(shè)置。如果希望得到多個生成的列昌犹,也可以是逗號分隔的屬性名稱列表坚芜。
databaseId 如果配置了 databaseIdProvider,MyBatis 會加載所有的不帶 databaseId 或匹配當(dāng)前 databaseId 的語句斜姥;如果帶或者不帶的語句都有鸿竖,則不帶的會被忽略。
  • 下面是 insert铸敏,update 和 delete 語句的一些示例:
<insert id="insertAuthor">
  insert into Author (id,username,password,email,bio)
  values (#{id},#{username},#{password},#{email},#{bio})
</insert>
<update id="updateAuthor">
  update Author set
    username = #{username},
    password = #{password},
    email = #{email},
    bio = #{bio}
  where id = #{id}
</update>
<delete id="deleteAuthor">
  delete from Author where id = #{id}
</delete>
  • 插入時處理主鍵的生成
    首先缚忧,如果你的數(shù)據(jù)庫支持自動生成主鍵的字段(比如 MySQL 和 SQL Server),那么你可以設(shè)置 useGeneratedKeys=”true”杈笔,然后再把 keyProperty 設(shè)置到目標(biāo)屬性上就OK了闪水。例如,如果上面的 Author 表已經(jīng)對 id 使用了自動生成的列類型蒙具,那么語句可以修改為:
<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username,password,email,bio)
  values (#{username},#{password},#{email},#{bio})
</insert>

如果你的數(shù)據(jù)庫還支持多行插入, 你也可以傳入一個Authors數(shù)組或集合球榆,并返回自動生成的主鍵朽肥。

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username, password, email, bio) values
  <foreach item="item" collection="list" separator=",">
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
  </foreach>
</insert>

對于不支持自動生成類型的數(shù)據(jù)庫或可能不支持自動生成主鍵 JDBC 驅(qū)動來說,MyBatis 有另外一種方法來生成主鍵持钉。
這里有一個簡單(甚至很傻)的示例衡招,它可以生成一個隨機 ID(你最好不要這么做,但這里展示了 MyBatis 處理問題的靈活性及其所關(guān)心的廣度):

<insert id="insertAuthor">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
  </selectKey>
  insert into Author
    (id, username, password, email,bio, favourite_section)
  values
    (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>

在上面的示例中每强,selectKey 元素將會首先運行始腾,Author 的 id 會被設(shè)置,然后插入語句會被調(diào)用空执。這給你了一個和數(shù)據(jù)庫中來處理自動生成的主鍵類似的行為浪箭,避免了使 Java 代碼變得復(fù)雜。
</br>selectKey 元素描述如下:

<selectKey
  keyProperty="id"
  resultType="int"
  order="BEFORE"
  statementType="PREPARED">
</selectKey>
屬性 描述
keyProperty selectKey 語句結(jié)果應(yīng)該被設(shè)置的目標(biāo)屬性脆烟。如果希望得到多個生成的列山林,也可以是逗號分隔的屬性名稱列表房待。
keyColumn 匹配屬性的返回結(jié)果集中的列名稱邢羔。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表桑孩。
resultType 結(jié)果的類型拜鹤。MyBatis 通常可以推算出來流椒,但是為了更加確定寫上也不會有什么問題敏簿。MyBatis 允許任何簡單類型用作主鍵的類型,包括字符串宣虾。如果希望作用于多個生成的列惯裕,則可以使用一個包含期望屬性的 Object 或一個 Map。
order 這可以被設(shè)置為 BEFORE 或 AFTER绣硝。如果設(shè)置為 BEFORE蜻势,那么它會首先選擇主鍵,設(shè)置 keyProperty 然后執(zhí)行插入語句鹉胖。如果設(shè)置為 AFTER握玛,那么先執(zhí)行插入語句,然后是 selectKey 元素 - 這和像 Oracle 的數(shù)據(jù)庫相似甫菠,在插入語句內(nèi)部可能有嵌入索引調(diào)用挠铲。
statementType 與前面相同,MyBatis 支持 STATEMENT寂诱,PREPARED 和 CALLABLE 語句的映射類型拂苹,分別代表 PreparedStatement 和 CallableStatement 類型。

4痰洒、sql元素

這個元素可以被用來定義可重用的 SQL 代碼段醋寝,可以包含在其他語句中搞挣。它可以被靜態(tài)地(在加載參數(shù)) 參數(shù)化. 不同的屬性值通過包含的實例變化. 比如:

<sql id="userColumns"> 
    ${alias}.id,${alias}.username,${alias}.password
</sql>

這個 SQL 片段可以被包含在其他語句中,例如:

<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>,
    <include refid="userColumns"><property name="alias" value="t2"/></include>
  from some_table t1
    cross join some_table t2
</select>

屬性值可以用于包含的refid屬性或者包含的字句里面的屬性值音羞,例如:

<sql id="sometable">
  ${prefix}Table
</sql>

<sql id="someinclude">
  from
    <include refid="${include_target}"/>
</sql>

<select id="select" resultType="map">
  select
    field1, field2, field3
  <include refid="someinclude">
    <property name="prefix" value="Some"/>
    <property name="include_target" value="sometable"/>
  </include>
</select>

5囱桨、Result Maps

resultMap 元素是 MyBatis 中最重要最強大的元素。它就是讓你遠(yuǎn)離 90%的需要從結(jié)果 集中取出數(shù)據(jù)的 JDBC 代碼的那個東西, 而且在一些情形下允許你做一些 JDBC 不支持的事 情嗅绰。 事實上, 編寫相似于對復(fù)雜語句聯(lián)合映射這些等同的代碼, 也許可以跨過上千行的代碼舍肠。 ResultMap 的設(shè)計就是簡單語句不需要明確的結(jié)果映射,而很多復(fù)雜語句確實需要描述它們 的關(guān)系。

對于下面這個 JavaBean:

package com.someapp.model;
public class User {
  private int id;
  private String username;
  private String hashedPassword;
  
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getUsername() {
    return username;
  }
  public void setUsername(String username) {
    this.username = username;
  }
  public String getHashedPassword() {
    return hashedPassword;
  }
  public void setHashedPassword(String hashedPassword) {
    this.hashedPassword = hashedPassword;
  }
}

那么窘面,可以這樣來使用resultMap翠语。

<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>

6、一個非常復(fù)雜的映射例子

如何映射下面這個語句?
描述:查詢一個作者寫的博客财边,博客里包含很多博文肌括,每篇博文有零條或多條的評論和標(biāo)簽。

<!-- Very Complex Statement -->
<select id="selectBlogDetails" resultMap="detailedBlogResultMap">
  select
       B.id as blog_id,
       B.title as blog_title,
       B.author_id as blog_author_id,
       A.id as author_id,
       A.username as author_username,
       A.password as author_password,
       A.email as author_email,
       A.bio as author_bio,
       A.favourite_section as author_favourite_section,
       P.id as post_id,
       P.blog_id as post_blog_id,
       P.author_id as post_author_id,
       P.created_on as post_created_on,
       P.section as post_section,
       P.subject as post_subject,
       P.draft as draft,
       P.body as post_body,
       C.id as comment_id,
       C.post_id as comment_post_id,
       C.name as comment_name,
       C.comment as comment_text,
       T.id as tag_id,
       T.name as tag_name
  from Blog B
       left outer join Author A on B.author_id = A.id
       left outer join Post P on B.id = P.blog_id
       left outer join Comment C on P.id = C.post_id
       left outer join Post_Tag PT on PT.post_id = P.id
       left outer join Tag T on PT.tag_id = T.id
  where B.id = #{id}
</select>

那么酣难,可以這么來寫 (假設(shè)作者, 博客, 博文, 評論和標(biāo)簽都是類型的別名) :

<!-- Very Complex Result Map -->
<resultMap id="detailedBlogResultMap" type="Blog">
  <constructor>
    <idArg column="blog_id" javaType="int"/>
  </constructor>
  <result property="title" column="blog_title"/>
  <association property="author" javaType="Author">
    <id property="id" column="author_id"/>
    <result property="username" column="author_username"/>
    <result property="password" column="author_password"/>
    <result property="email" column="author_email"/>
    <result property="bio" column="author_bio"/>
    <result property="favouriteSection" column="author_favourite_section"/>
  </association>
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <association property="author" javaType="Author"/>
    <collection property="comments" ofType="Comment">
      <id property="id" column="comment_id"/>
    </collection>
    <collection property="tags" ofType="Tag" >
      <id property="id" column="tag_id"/>
    </collection>
    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>
  </collection>
</resultMap>

(待補充)

6谍夭、緩存

MyBatis 包含一個非常強大的查詢緩存特性,它可以非常方便地配置和定制。MyBatis 3 中的緩存實現(xiàn)的很多改進都已經(jīng)實現(xiàn)了,使得它更加強大而且易于配置憨募。
默認(rèn)情況下是沒有開啟緩存的,除了局部的 session 緩存,可以增強變現(xiàn)而且處理循環(huán) 依賴也是必須的紧索。要開啟二級緩存,你需要在你的 SQL 映射文件中添加一行:

<cache/>

字面上看就是這樣。這個簡單語句的效果如下:

映射語句文件中的所有 select 語句將會被緩存菜谣。
映射語句文件中的所有 insert,update 和 delete 語句會刷新緩存珠漂。
緩存會使用 Least Recently Used(LRU,最近最少使用的)算法來收回。
根據(jù)時間表(比如 no Flush Interval,沒有刷新間隔), 緩存不會以任何時間順序 來刷新尾膊。
緩存會存儲列表集合或?qū)ο?無論查詢方法返回什么)的 1024 個引用媳危。
緩存會被視為是 read/write(可讀/可寫)的緩存,意味著對象檢索不是共享的,而 且可以安全地被調(diào)用者修改,而不干擾其他調(diào)用者或線程所做的潛在修改。

所有的這些屬性都可以通過緩存元素的屬性來修改冈敛。比如:

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>

這個更高級的配置創(chuàng)建了一個 FIFO 緩存,并每隔 60 秒刷新,存數(shù)結(jié)果對象或列表的 512 個引用,而且返回的對象被認(rèn)為是只讀的,因此在不同線程中的調(diào)用者之間修改它們會 導(dǎo)致沖突待笑。

可用的收回策略有:
LRU – 最近最少使用的:移除最長時間不被使用的對象。
FIFO – 先進先出:按對象進入緩存的順序來移除它們莺债。
SOFT – 軟引用:移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對象滋觉。
WEAK – 弱引用:更積極地移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對象。
默認(rèn)的是 LRU齐邦。

flushInterval(刷新間隔)可以被設(shè)置為任意的正整數(shù),而且它們代表一個合理的毫秒 形式的時間段椎侠。默認(rèn)情況是不設(shè)置,也就是沒有刷新間隔,緩存僅僅調(diào)用語句時刷新。

size(引用數(shù)目)可以被設(shè)置為任意正整數(shù),要記住你緩存的對象數(shù)目和你運行環(huán)境的 可用內(nèi)存資源數(shù)目措拇。默認(rèn)值是 1024我纪。

readOnly(只讀)屬性可以被設(shè)置為 true 或 false。只讀的緩存會給所有調(diào)用者返回緩 存對象的相同實例。因此這些對象不能被修改浅悉。這提供了很重要的性能優(yōu)勢趟据。可讀寫的緩存 會返回緩存對象的拷貝(通過序列化) 术健。這會慢一些,但是安全,因此默認(rèn)是 false汹碱。

二、實例(待補充)

三荞估、使用細(xì)節(jié)(待補充)

最后編輯于
?著作權(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)容