Mybatis基礎(chǔ) -- 相關(guān)概念及快速入門(mén)

一、Mybatis相關(guān)概念

  • 對(duì)象 / 關(guān)系數(shù)據(jù)庫(kù)映射(ORM)
    • ORM全稱 Object Relation Mapping:表示對(duì)象 - 關(guān)系映射的縮寫(xiě)
    • ORM完成?向?qū)ο蟮木幊陶Z(yǔ)?到關(guān)系數(shù)據(jù)庫(kù)的映射
      當(dāng)ORM框架完成映射后,程序員既可以利??向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)?的簡(jiǎn)單易?性剩彬,?可以利?關(guān)系數(shù)據(jù)庫(kù)的技術(shù)優(yōu)勢(shì)。
    • ORM把關(guān)系數(shù)據(jù)庫(kù)包裝成?向?qū)ο蟮哪P?br> ORM框架是?向?qū)ο笤O(shè)計(jì)語(yǔ)?與關(guān)系數(shù)據(jù)庫(kù)發(fā)展不同步時(shí)的中間解決?案。采?ORM框架后,應(yīng)?程序不再直接訪問(wèn)底層數(shù)據(jù)庫(kù)道批,?是以?向?qū)ο蟮男问絹?lái)操作持久化對(duì)象,?ORM框架則將這些?向?qū)ο蟮牟僮鬓D(zhuǎn)換成底層SQL操作
    • ORM框架實(shí)現(xiàn)的效果:把對(duì)持久化對(duì)象的保存入撒、修改隆豹、刪除等操作,轉(zhuǎn)換為對(duì)數(shù)據(jù)庫(kù)的操作
  • Mybatis簡(jiǎn)介
    • MyBatis是?款優(yōu)秀的基于ORM的半?動(dòng)輕量級(jí)持久層框架茅逮,它?持定制化SQL璃赡、存儲(chǔ)過(guò)程以及?級(jí)映射
    • MyBatis避免了?乎所有的JDBC代碼和?動(dòng)設(shè)置參數(shù)以及獲取結(jié)果集
    • MyBatis可以使?簡(jiǎn)單的XML或注解來(lái)配置和映射原?類型判哥、接?和Java的POJO (Plain Old Java Objects,普通?式Java對(duì) 象)為數(shù)據(jù)庫(kù)中的記錄。
  • Mybatis歷史
    • 原是 apache 的?個(gè)開(kāi)源項(xiàng)? iBatis
    • 2010年6?這個(gè)項(xiàng)?由apache software foundation 遷移到了google code碉考,隨著開(kāi)發(fā)團(tuán)隊(duì)轉(zhuǎn)投Google Code旗下塌计,ibatis3.x正式更名為Mybatis ,代碼于2013年11
      ?遷移到Github
    • iBATIS?詞來(lái)源于“internet”和“abatis”的組合豆励,是?個(gè)基于Java的持久層框架
    • iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAO)
  • Mybatis優(yōu)勢(shì)
    Mybatis是?個(gè)半?動(dòng)化的持久層框架夺荒,對(duì)開(kāi)發(fā)?員開(kāi)說(shuō)瞒渠,核?sql還是需要??進(jìn)?優(yōu)化良蒸,sql和java編碼進(jìn)?分離,功能邊界清晰伍玖,?個(gè)專注業(yè)務(wù)嫩痰,?個(gè)專注數(shù)據(jù)

二、Mybatis基本應(yīng)用

  • 快速入門(mén)
    • MyBatis官?地址:http://www.mybatis.org/mybatis-3/
    • 開(kāi)發(fā)步驟
      1. 添加MyBatis的坐標(biāo)
      2. 創(chuàng)建user數(shù)據(jù)表
      3. 編寫(xiě)User實(shí)體類
      4. 編寫(xiě)映射文件 UserMapper.xml
      5. 編寫(xiě)核心文件 SqlMapConfig.xml
      6. 編寫(xiě)測(cè)試類
    • 環(huán)境搭建
      1. 導(dǎo)?MyBatis的坐標(biāo)和其他相關(guān)坐標(biāo)
      <?xml version="1.0" encoding="UTF-8"?>
      <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.wujun</groupId>
          <artifactId>mybatis_quick_start</artifactId>
          <version>1.0-SNAPSHOT</version>
      
          <properties>
              <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
              <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
              <java.version>11</java.version>
              <maven.compiler.source>11</maven.compiler.source>
              <maven.compiler.target>11</maven.compiler.target>
              <org.mybatis.mybatis>3.4.5</org.mybatis.mybatis>
              <mysql.mysql-connector-java>5.1.6</mysql.mysql-connector-java>
              <org.projectlombok.lombok.version>1.18.10</org.projectlombok.lombok.version>
              <com.alibaba.fastjson>1.2.4</com.alibaba.fastjson>
              <junit.junit>4.12</junit.junit>
              <log4j.log4j>1.2.12</log4j.log4j>
          </properties>
      
          <!--引入依賴-->
          <dependencies>
              <!--mybatis坐標(biāo)-->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>${org.mybatis.mybatis}</version>
              </dependency>
              <!--mysql驅(qū)動(dòng)坐標(biāo)-->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>${mysql.mysql-connector-java}</version>
                  <scope>runtime</scope>
              </dependency>
              <!--單元測(cè)試坐標(biāo)-->
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>${junit.junit}</version>
              </dependency>
              <!--?志坐標(biāo)-->
              <dependency>
                  <groupId>log4j</groupId>
                  <artifactId>log4j</artifactId>
                  <version>${log4j.log4j}</version>
              </dependency>
              <!--lombok-->
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <version>${org.projectlombok.lombok.version}</version>
                  <scope>provided</scope>
              </dependency>
              <!--fastjson-->
              <dependency>
                  <groupId>com.alibaba</groupId>
                  <artifactId>fastjson</artifactId>
                  <version>${com.alibaba.fastjson}</version>
              </dependency>
          </dependencies>
      
      </project>
      
      1. 創(chuàng)建user數(shù)據(jù)表
      CREATE TABLE `user` (
        `id` bigint(20) NOT NULL,
        `username` varchar(50) DEFAULT NULL,
        PRIMARY KEY (`id`)
      ) 
      
      1. 編寫(xiě)User實(shí)體
      package com.wujun.pojo;
      
      import lombok.Data;
      
      @Data
      public class User {
          private Long id;
          private String username;
      }
      
      1. 編寫(xiě)映射文件 UserMapper.xml
        mapper標(biāo)簽的加載方式有4種:
        • 使用相對(duì)于類路徑的資源引用
          例如:<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
        • 使?完全限定資源定位符(URL)
          例如:<mapper url="file:///var/mappers/AuthorMapper.xml"/>
        • 使?映射器接口實(shí)現(xiàn)類的完全限定類名
          例如:<mapper class="org.mybatis.builder.AuthorMapper"/>
        • 將包內(nèi)的映射器接?實(shí)現(xiàn)全部注冊(cè)為映射器
          例如:<package name="org.mybatis.builder"/>
      <?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">
      
      <!--namespace:名稱空間窍箍,與id組成sql的唯一標(biāo)識(shí)-->
      <mapper namespace="user">
          <select id="findAll" resultType="com.wujun.pojo.User">
              select * from User
          </select>
      </mapper>
      
      1. 編寫(xiě)核心文件 SqlMapConfig.xml
        • 事務(wù)管理器(transactionManager)類型有兩種:
          1. JDBC:這個(gè)配置就是直接使?了JDBC 的提交和回滾設(shè)置串纺,它依賴于從數(shù)據(jù)源得到的連接來(lái)管理事務(wù)作用域
          2. MANAGED:這個(gè)配置幾乎沒(méi)做什么,它從來(lái)不提交或回滾?個(gè)連接椰棘,而是讓容器來(lái)管理事務(wù)的整個(gè)生命周期(比如 JEE 應(yīng)?服務(wù)器的上下文)纺棺。 默認(rèn)情況下它會(huì)關(guān)閉連接,然而?些容器并不希望這樣邪狞,因此需要將 closeConnection 屬性設(shè)置為 false 來(lái)阻止它默認(rèn)的關(guān)閉行為
        • 數(shù)據(jù)源(dataSource)類型有三種
          1. UNPOOLED:這個(gè)數(shù)據(jù)源的實(shí)現(xiàn)只是每次被請(qǐng)求時(shí)打開(kāi)和關(guān)閉連接
          2. POOLED:這種數(shù)據(jù)源的實(shí)現(xiàn)利用“池”的概念將 JDBC 連接對(duì)象組織起來(lái)
          3. JNDI:這個(gè)數(shù)據(jù)源的實(shí)現(xiàn)是為了能在如 EJB 或應(yīng)?服務(wù)器這類容器中使用祷蝌,容器可以集中或在外部配置數(shù)據(jù)源,然后放置?個(gè) JNDI 上下文的引用
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-config.dtd">
      
      <configuration>
      
          <!-- environments:運(yùn)行環(huán)境 -->
          <environments default="dev">
              <!-- 一個(gè)environment代表一個(gè)環(huán)境帆卓,可以配置多個(gè)環(huán)境巨朦,例如[dev][test][prod]-->
              <environment id="dev">
                  <!--當(dāng)前事務(wù)交由JDBC進(jìn)行管理-->
                  <transactionManager type="JDBC"></transactionManager>
                  <!-- POOLED表示當(dāng)前使用mybatis提供的數(shù)據(jù)庫(kù)連接池
                       UNPOOLED表示不使用連接池,每次請(qǐng)求都會(huì)新建一個(gè)數(shù)據(jù)庫(kù)連接 -->
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql:///wujun_test"/>
                      <property name="username" value="wujun"/>
                      <property name="password" value="wujun@2020"/>
                  </dataSource>
              </environment>
          </environments>
      
          <!-- 引入映射配置文件 -->
          <mappers>
              <mapper resource="UserMapper.xml"></mapper>
          </mappers>
      </configuration>
      
      1. 編寫(xiě)測(cè)試類
      package com.wujun.test;
      
      import com.wujun.pojo.User;
      import org.apache.ibatis.io.Resources;
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.apache.ibatis.session.SqlSessionFactoryBuilder;
      import org.junit.Test;
      
      import java.io.IOException;
      import java.io.InputStream;
      import java.util.List;
      
      public class MybatisTest {
      
          @Test
          public void test1() throws IOException {
              InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
              SqlSession sqlSession = sqlSessionFactory.openSession();
              List<User> users = sqlSession.selectList("user.findAll");
              for (User user : users) {
                  System.out.println(user);
              }
              sqlSession.close();
          }
      }
      
      
      1. 返回結(jié)果
      User(id=1, username=吳俊1)
      User(id=2, username=吳俊2)
      User(id=3, username=吳俊3)
      

三剑令、注意事項(xiàng)

執(zhí)行方法SqlSession sqlSession = sqlSessionFactory.openSession();的時(shí)候糊啡,會(huì)默認(rèn)開(kāi)啟一個(gè)事務(wù),但是不會(huì)自動(dòng)提交該事務(wù)吁津,在執(zhí)行增刪改操作的時(shí)候棚蓄,需要手動(dòng)提交事務(wù)sqlSession.commit();
如果不想手動(dòng)提交事務(wù),則可以使用SqlSession sqlSession = sqlSessionFactory.openSession(true);方法碍脏,該方法會(huì)自動(dòng)提交事務(wù)梭依。

四、Mybatis的Dao層傳統(tǒng)開(kāi)發(fā)方式

  1. 編寫(xiě)Dao層接口
package com.wujun.dao;

import com.wujun.pojo.User;

import java.io.IOException;
import java.util.List;

public interface IUserDao {

    List<User> findAll() throws IOException;
}
  1. 編寫(xiě)Dao層實(shí)現(xiàn)類
package com.wujun.dao;

import com.wujun.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UserDaoImpl implements IUserDao {

    @Override
    public List<User> findAll() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> users = sqlSession.selectList("user.findAll");
        sqlSession.close();
        return users;
    }
}

  1. 編寫(xiě)測(cè)試類
package com.wujun.test;

import com.wujun.dao.IUserDao;
import com.wujun.dao.UserDaoImpl;
import com.wujun.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MybatisTest {

    /*@Test
    public void test1() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> users = sqlSession.selectList("user.findAll");
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
    }*/

    @Test
    public void test2() throws IOException {
        IUserDao userDao = new UserDaoImpl();
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }
}

  1. 測(cè)試結(jié)果
User(id=1, username=吳俊1)
User(id=2, username=吳俊2)
User(id=3, username=吳俊3)

五潮酒、Mybatis的Dao層代理開(kāi)發(fā)方式

  • 代理開(kāi)發(fā)方式介紹
    • 采用 Mybatis 的代理開(kāi)發(fā)方式實(shí)現(xiàn) DAO 層的開(kāi)發(fā)睛挚,這種方式是主流。
    • Mapper 接口開(kāi)發(fā)方法只需要程序員編寫(xiě)Mapper 接口(相當(dāng)于Dao 接口)急黎,由Mybatis 框架根據(jù)接口定義創(chuàng)建接口的動(dòng)態(tài)代理對(duì)象扎狱,代理對(duì)象的方法體同上邊Dao接口實(shí)現(xiàn)類方法
    • Mapper 接?開(kāi)發(fā)需要遵循以下規(guī)范
      1. Mapper.xml文件中的namespace與mapper接口的全限定名相同
      2. Mapper接口方法名和Mapper.xml中定義的每個(gè)statement的id相同
      3. Mapper接口方法的輸入?yún)?shù)類型和mapper.xml中定義的每個(gè)sql的parameterType的類型相同
      4. Mapper接口方法的輸出參數(shù)類型和mapper.xml中定義的每個(gè)sql的resultType的類型相同
  • 編寫(xiě) UserMapper 接?
public interface UserMapper {

    List<User> findAll();

    User findById(Long id);
}
  • 重寫(xiě) UserMapper.xml
<?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">

<!--namespace:名稱空間侧到,與id組成sql的唯一標(biāo)識(shí)-->
<mapper namespace="com.wujun.mapper.UserMapper">
    <select id="findAll" resultType="com.wujun.pojo.User">
        select * from User
    </select>

    <select id="findById" parameterType="java.lang.Long" resultType="com.wujun.pojo.User">
        select * from User where id = #{id}
    </select>
</mapper>
  • 編寫(xiě)測(cè)試類
package com.wujun.test;

import com.wujun.dao.IUserDao;
import com.wujun.dao.UserDaoImpl;
import com.wujun.mapper.UserMapper;
import com.wujun.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MybatisTest {

    /*@Test
    public void test1() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> users = sqlSession.selectList("user.findAll");
        for (User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
    }*/

    /*@Test
    public void test2() throws IOException {
        IUserDao userDao = new UserDaoImpl();
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }*/

    @Test
    public void test3() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> all = mapper.findAll();
        for (User user : all) {
            System.out.println(user);
        }
        System.out.println("===============================");
        User byId = mapper.findById(1L);
        System.out.println(byId);
    }
}

  • 測(cè)試結(jié)果
User(id=1, username=吳俊1)
User(id=2, username=吳俊2)
User(id=3, username=吳俊3)
===============================
User(id=1, username=吳俊1)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市淤击,隨后出現(xiàn)的幾起案子匠抗,更是在濱河造成了極大的恐慌,老刑警劉巖污抬,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汞贸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡印机,警方通過(guò)查閱死者的電腦和手機(jī)矢腻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)射赛,“玉大人多柑,你說(shuō)我怎么就攤上這事¢乖穑” “怎么了竣灌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)秆麸。 經(jīng)常有香客問(wèn)我初嘹,道長(zhǎng),這世上最難降的妖魔是什么沮趣? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任屯烦,我火速辦了婚禮,結(jié)果婚禮上兔毒,老公的妹妹穿的比我還像新娘漫贞。我一直安慰自己,他們只是感情好育叁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布迅脐。 她就那樣靜靜地躺著,像睡著了一般豪嗽。 火紅的嫁衣襯著肌膚如雪谴蔑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天龟梦,我揣著相機(jī)與錄音隐锭,去河邊找鬼。 笑死计贰,一個(gè)胖子當(dāng)著我的面吹牛钦睡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播躁倒,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼荞怒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼洒琢!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起褐桌,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤衰抑,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后荧嵌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體呛踊,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年啦撮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谭网。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逻族,死狀恐怖蜻底,靈堂內(nèi)的尸體忽然破棺而出骄崩,到底是詐尸還是另有隱情聘鳞,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布要拂,位于F島的核電站抠璃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏脱惰。R本人自食惡果不足惜搏嗡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拉一。 院中可真熱鬧采盒,春花似錦、人聲如沸蔚润。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嫡纠。三九已至烦租,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徊都,已是汗流浹背噩凹。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工产雹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窃祝。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像踱侣,于是被迫代替她去往敵國(guó)和親粪小。 傳聞我的和親對(duì)象是個(gè)殘疾皇子甩栈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

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