SSM學習之Mybatis

SSM-Mybatis框架學習

一盛末、框架

1.1 什么是框架

框架(Framework)是整個或部分系統(tǒng)的可重用設計丹鸿,表現(xiàn)為一組抽象構件及構件實例間交互的方法;另一種定義認為撼唾,框架是可被應用開發(fā)者定制的應用骨架梅尤。前者是從應用方面而后者是從目的方面給出的定義替劈。

簡而言之蜒滩,框架其實就是某種應用的半成品滨达,就是一組組件,供你選用完成你自己的系統(tǒng)俯艰。簡單說就是使用別人搭好的舞臺捡遍,你來做表演。而且竹握,框架一般是成熟的画株,不斷升級的軟件。

2.2 MVC設計思想

什么是MVC?

M(Model模型)V(View視圖)C(Controller控制器)開發(fā)模型

[圖片上傳失敗...(image-f94c72-1624563186741)]

二谓传、Mybatis 框架快速入門

2.1創(chuàng)建 maven 工程

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n38" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">創(chuàng)建 mybatis01 的工程蜈项,工程信息如下:

Groupid:com.itheima

ArtifactId:mybatis01

Packing:jar</pre>

2.2 添加 Mybatis3.4.5 的坐標

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n123" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><dependencies>

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis</artifactId>

<version>3.4.5</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.10</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.6</version>

<scope>runtime</scope>

</dependency>

<dependency>

<groupId>log4j</groupId>

<artifactId>log4j</artifactId>

<version>1.2.12</version>

</dependency>

</dependencies></pre>

2.3創(chuàng)建User實體類

2.4編寫持久層接口UserDao(內(nèi)部寫方法)

2.5 編寫持久層接口的映射文件 IUserDao.xml(SQL語句等配置信息)

2.6 編寫 SqlMapConfig.xml 配置文件

文件創(chuàng)建位置如圖所示:

[圖片上傳失敗...(image-25132-1624563186741)]

2.7 編寫測試類

在測試類中

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n189" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">//1.讀取配置文件

InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");

//2.創(chuàng)建 SqlSessionFactory 的構建者對象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

//3.使用構建者創(chuàng)建工廠對象 SqlSessionFactory

SqlSessionFactory factory = builder.build(in);

//4.使用 SqlSessionFactory 生產(chǎn) SqlSession 對象

SqlSession session = factory.openSession();

//5.使用 SqlSession 創(chuàng)建 dao 接口的代理對象

IUserDao userDao = session.getMapper(IUserDao.class);

//6.使用代理對象執(zhí)行查詢所有方法

List<User> users = userDao.findAll();

for(User user : users) {

System.out.println(user);

}

//7.釋放資源

session.close();

in.close();</pre>

補充:

基于注解的mybatis使用

①在持久層的方法上添加Sql語句的注解如:

@Select("select * from user")

②修改SqlMapConfig.xml

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n230" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

<mappers>

<mapper class="com.itheima.dao.IUserDao"/>

</mappers></pre>

三、自定義 Mybatis 框架

實際開發(fā)中常使用mybatis代理jdbc所以在這里就不細說了

具體實現(xiàn)代碼:

Silencoco/SSM-Mybatis: SSM 框架之Mybatis學習 (github.com)

設計說明:

[圖片上傳失敗...(image-c949c4-1624563186740)]

[圖片上傳失敗...(image-b172f5-1624563186740)]

[圖片上傳失敗...(image-146c33-1624563186740)]

[圖片上傳失敗...(image-726674-1624563186740)]

四良拼、代理DAO實現(xiàn)CRUD操作

Mybatis JDBC 編程的比較

1.數(shù)據(jù)庫鏈接創(chuàng)建战得、釋放頻繁造成系統(tǒng)資源浪費從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫鏈接池可解決此問題庸推。解決:在 SqlMapConfig.xml 中配置數(shù)據(jù)鏈接池常侦,使用連接池管理數(shù)據(jù)庫鏈接。

2.Sql 語句寫在代碼中造成代碼不易維護贬媒,實際應用 sql 變化的可能較大聋亡,sql 變動需要改變 java 代碼。

解決:將 Sql 語句配置在 XXXXmapper.xml 文件中與 java 代碼分離际乘。

3.向 sql 語句傳參數(shù)麻煩坡倔,因為 sql 語句的 where 條件不一定,可能多也可能少脖含,占位符需要和參數(shù)對應罪塔。

解決:Mybatis 自動將 java 對象映射至 sql 語句,通過 statement 中的 parameterType 定義輸入?yún)?shù)的類型养葵。

4.對結果集解析麻煩征堪,sql 變化導致解析代碼變化,且解析前需要遍歷关拒,如果能將數(shù)據(jù)庫記錄封裝成 pojo 對象解析比較方便佃蚜。

解決:Mybatis 自動將 sql 執(zhí)行結果映射至 java 對象,通過 statement 中的 resultType 定義輸出結果的類型

五着绊、 Mybatis 的輸出結果封裝

resultType 屬性:

可以指定結果集的類型谐算,它支持基本類型實體類類型

同時,當是實體類名稱是归露,還有一個要求洲脂,實體類中的屬性名稱必須和查詢語句中的列名保持一致,否則無法實現(xiàn)封裝剧包。

resultMap 結果類型:

resultMap 標簽可以建立查詢的列名和實體類的屬性名稱不一致時建立對應關系腮考。從而實現(xiàn)封裝。

在 select 標簽中使用 resultMap 屬性指定引用即可玄捕。同時 resultMap 可以實現(xiàn)將查詢結果映射為復雜類型的 pojo踩蔚,比如在查詢結果映射對象中包括 pojo 和 list 實現(xiàn)一對一查詢和一對多查詢

六枚粘、SqlMapConfig.xml配置文件

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n325" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">-properties****(屬性)**

--property

-settings(全局配置參數(shù))

--setting

-typeAliases****(類型別名)

--typeAliase

--package

-typeHandlers(類型處理器)

-objectFactory(對象工廠)

-plugins(插件)

-environments(環(huán)境集合屬性對象)

--environment(環(huán)境子屬性對象)

---transactionManager(事務管理)

---dataSource(數(shù)據(jù)源)

-mappers****(映射器)

--mapper

--package</pre>

properties****(屬性)的兩種配置方式

一馅闽、

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n351" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/eesy"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="1234"/>
</properties></pre>

二、在 classpath 下定義 db.properties 文件

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="properties" cid="n360" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/eesy

jdbc.username=root

jdbc.password=1234</pre>

dataSource 標簽就變成了引用下面的配置

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n375" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><dataSource type="POOLED">
<property name="driver" value="{jdbc.driver}"/> <property name="url" value="{jdbc.url}"/>
<property name="username" value="{jdbc.username}"/> <property name="password" value="{jdbc.password}"/>
</dataSource></pre>

6.1 typeAliases(類型別名)

在 SqlMapConfig.xml 中配置:

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n396" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><typeAliases>
<typeAlias alias="user" type="com.itheima.domain.User"/>
<package name="com.itheima.domain"/>
<package name="其它包"/>
</typeAliases></pre>

6.2 mappers(映射器)

6.2.1 <mapper resource=" " />

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n409" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">使用相對于類路徑的資源
如:<mapper resource="com/itheima/dao/IUserDao.xml" /></pre>

6.2.2 <mapper class=" " />

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n416" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">使用 mapper 接口類路徑
如:<mapper class="com.itheima.dao.UserDao"/>
注意:此種方法要求 mapper 接口名稱和 mapper 映射文件名稱相同,且放在同一個目錄中福也。 </pre>

6.2.3 <package name=""/>

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" cid="n420" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">注冊指定包下的所有 mapper 接口
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此種方法要求 mapper 接口名稱和 mapper 映射文件名稱相同局骤,且放在同一個目錄中。</pre>

七暴凑、Mybatis 連接池與事務深入

在 Mybatis 的 SqlMapConfig.xml 配置文件中峦甩,通過<dataSource type="pooled">來實現(xiàn) Mybatis 中連接池的配置

我們的數(shù)據(jù)源配置就是在 SqlMapConfig.xml 文件中,具體配置如下:

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n437" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<dataSource type="POOLED"> <property name="driver" value="{jdbc.driver}"/> <property name="url" value="{jdbc.url}"/>
<property name="username" value="{jdbc.username}"/> <property name="password" value="{jdbc.password}"/>
</dataSource></pre>

MyBatis 在初始化時现喳,根據(jù)<dataSource>的 type 屬性來創(chuàng)建相應類型的的數(shù)據(jù)源 DataSource凯傲,即:

type=”POOLED”:MyBatis 會創(chuàng)建 PooledDataSource 實例

type=”UNPOOLED” : MyBatis 會創(chuàng)建 UnpooledDataSource 實例

type=”JNDI”:MyBatis 會從 JNDI 服務上查找 DataSource 實例,然后返回使用

7.1 Mybatis 的事務控制

在 JDBC 中我們可以通過手動方式將事務的提交改為手動方式嗦篱,通過 setAutoCommit()方法就可以調(diào)整冰单。 那么我們的 Mybatis 框架因為是對 JDBC 的封裝,所以 Mybatis 框架的事務控制方式灸促,本身也是用 JDBC 的setAutoCommit()方法來設置事務提交方式的诫欠。

session.commit();

7.1.1 Mybatis 自動提交事務的設置

通過上面的研究和分析,現(xiàn)在我們一起思考浴栽,為什么 CUD 過程中必須使用 sqlSession.commit()提交事務荒叼?主要原因就是在連接池中取出的連接,都會將調(diào)用 connection.setAutoCommit(false)方法典鸡,這樣我們就必須使用 sqlSession.commit()方法被廓,相當于使用了 JDBC 中的 connection.commit()方法實現(xiàn)事務提交.

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n477" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">//1.讀取配置文件

in = Resources.getResourceAsStream("SqlMapConfig.xml");

//2.創(chuàng)建構建者對象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

//3.創(chuàng)建 SqlSession 工廠對象

factory = builder.build(in);

//4.創(chuàng)建 SqlSession 對象

session = factory.openSession(true);

//5.創(chuàng)建 Dao 的代理對象

userDao = session.getMapper(IUserDao.class);</pre>

8. Mybatis 的動態(tài) SQL 語句

持久層:

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n505" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><select id="findByUser" resultType="user" parameterType="user">

select * from user where 1=1

<if test="username!=null and username != '' ">

and username like #{username}

</if>

<if test="address != null">

and address like #{address}

</if>

</select></pre>

測試類

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n531" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">@Test
public void testFindByUser() {
User u = new User();
u.setUsername("%王%");
u.setAddress("%順義%");
//6.執(zhí)行操作
List < User > users = userDao.findByUser(u);
for (User user: users) {
System.out.println(user);
}
}</pre>

9. Mybatis 中簡化編寫的 SQL 片段

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n547" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<sql id="defaultSql">
select * from user
</sql></pre>

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n551" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<select id="findAll" resultType="user"> <include refid="defaultSql"></include></select>

<select id="findById" resultType="UsEr" parameterType="int"><include refid="defaultSql"></include>
where id = #{uid}
</select></pre>

八、Mybatis 多表查詢之一對多椿每、多對多

一對多:

需求:

查詢所有用戶信息及用戶關聯(lián)的賬戶信息。

分析:

用戶信息和他的賬戶信息為一對多關系英遭,并且查詢過程中如果用戶沒有賬戶信息间护,此時也要將用戶信息查詢出來,我們想到了左外連接查詢比較合適挖诸。

多對多

通過前面的學習汁尺,我們使用 Mybatis 實現(xiàn)一對多關系的維護。多對多關系其實我們看成是雙向的一對多關系

九多律、 Mybatis 延遲加載策略

9.1 什么是延遲加載

延遲加載:

就是在需要用到數(shù)據(jù)時才進行加載痴突,不需要用到數(shù)據(jù)時就不加載數(shù)據(jù)。延遲加載也稱懶加載.

好處

先從單表查詢狼荞,需要時再從關聯(lián)表去關聯(lián)查詢辽装,大大提高數(shù)據(jù)庫性能,因為查詢單表要比關聯(lián)查詢多張表速度要快相味。

壞處

因為只有當需要用到數(shù)據(jù)時拾积,才會進行數(shù)據(jù)庫查詢,這樣在大批量數(shù)據(jù)查詢時,因為查詢工作也要消耗時間拓巧,所以可能造成用戶等待時間變長斯碌,造成用戶體驗下降。

9.2 實現(xiàn)需求

需求:

查詢賬戶(Account)信息并且關聯(lián)查詢用戶(User)信息肛度。如果先查詢賬戶(Account)信息即可滿足要求傻唾,當我們需要查詢用戶(User)信息時再查詢用戶(User)信息。把對用戶(User)信息的按需去查詢就是延遲加載承耿。mybatis第三天實現(xiàn)多表操作時冠骄,我們使用了resultMap來實現(xiàn)一對一,一對多瘩绒,多對多關系的操作猴抹。主要是通過 association、collection 實現(xiàn)一對一及一對多映射锁荔。association蟀给、collection 具備延遲加載功能。

9.3 使用 assocation 實現(xiàn)延遲加載

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n657" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="com.itheima.dao.IAccountDao">

<resultMap type="account" id="accountMap">
<id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>

<association property="user" javaType="user"
select="com.itheima.dao.IUserDao.findById"
column="uid">
</association>
</resultMap>
<select id="findAll" resultMap="accountMap">
select * from account
</select>
</mapper></pre>

select: 填寫我們要調(diào)用的 select 映射的 id column : 填寫我們要傳遞給 select 映射的參數(shù)

持久層接口及映射文件

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n731" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public interface** IUserDao {

/**

* 根據(jù) id 查詢

* @param userId

* @return

*/

User findById(Integer userId);

}</pre>

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n743" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><?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.itheima.dao.IUserDao">

<select id="findById" resultType="user" parameterType="int" >

select * from user where id = #{uid}

</select>

</mapper></pre>

9.4 開啟延遲加載

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n771" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings></pre>

9.5 使用 Collection 實現(xiàn)延遲加載

同樣我們也可以在一對多關系配置的<collection>結點中配置延遲加載策略阳堕。 <collection>結點中也有 select 屬性跋理,column 屬性。 需求: 完成加載用戶對象時恬总,查詢該用戶所擁有的賬戶信息.

User 實體類中加入 List<Account>****屬性

編寫用戶和賬戶持久層接口的方法

編寫用戶持久層映射配置

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n792" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><resultMap type="user" id="userMap">
<id column="id" property="id"></id>
<result column="username" property="username"/>
<result column="address" property="address"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>

<collection property="accounts" ofType="account"
select="com.itheima.dao.IAccountDao.findByUid"
column="id">
</collection>
</resultMap>

<select id="findAll" resultMap="userMap">
select * from user
</select></pre>

<collection>標簽: 主要用于加載關聯(lián)的集合對象 select 屬性: 用于指定查詢 account 列表的 sql 語句前普,所以填寫的是該 sql 映射的 id column 屬性: 用于指定 select 屬性的 sql 語句的參數(shù)來源,上面的參數(shù)來自于 user 的 id 列壹堰,所以就寫成 id 這一 個字段名了

十拭卿、Mybatis 一級緩存

一級緩存是 SqlSession 級別的緩存,只要 SqlSession 沒有 flush 或 close贱纠,它就存在峻厚。

一級緩存是 SqlSession 范圍的緩存,當調(diào)用 SqlSession 的修改谆焊,添加惠桃,刪除,commit()辖试,close()等方法時辜王,就會清空一級緩存。

第一次發(fā)起查詢用戶 id 為 1 的用戶信息罐孝,先去找緩存中是否有 id 為 1 的用戶信息呐馆,如果沒有,從數(shù)據(jù)庫查詢用戶信息莲兢。得到用戶信息摹恰,將用戶信息存儲到一級緩存中辫继。

如果 sqlSession 去執(zhí)行 commit 操作(執(zhí)行插入、更新俗慈、刪除)姑宽,清空 SqlSession 中的一級緩存,這樣做的目的為了讓緩存中存儲的是最新的信息闺阱,避免臟讀炮车。

第二次發(fā)起查詢用戶 id 為 1 的用戶信息,先去找緩存中是否有 id 為 1 的用戶信息酣溃,緩存中有瘦穆,直接從緩存中獲取用戶信息。

十一赊豌、二級緩存的開啟與關閉

第一步:在 SqlMapConfig.xml 文件開啟二級緩存

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n834" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><settings>

<setting name="cacheEnabled" value="true"/>

</settings></pre>

因為 cacheEnabled 的取值默認就為 true扛或,所以這一步可以省略不配置。為 true 代表開啟二級緩存碘饼;為false 代表不開啟二級緩存熙兔。

第二步:配置相關的 Mapper 映射文件

<cache>標簽表示當前這個 mapper 映射將使用二級緩存,區(qū)分的標準就看 mapper 的 namespace 值艾恼。

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n881" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="com.itheima.dao.IUserDao">

<cache></cache>
</mapper></pre>

配置 statement 上面的 useCache 屬性

<pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="xml" cid="n897" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
<select id="findById" resultType="user" parameterType="int" useCache="true">
select * from user where id = #{uid}
</select></pre>

將 UserDao.xml 映射文件中的<select>標簽中設置 useCache=”true”代表當前這個 statement 要使用

二級緩存住涉,如果不使用二級緩存可以設置為 false。

注意:針對每次查詢都需要最新的數(shù)據(jù) sql钠绍,要設置成 useCache=false舆声,禁用二級緩存。

十二柳爽、 Mybatis 注解開發(fā)

12.1 mybatis 的常用注解說明

@Insert:實現(xiàn)新增

@Update:實現(xiàn)更新

@Delete:實現(xiàn)刪除

@Select:實現(xiàn)查詢

@Result:實現(xiàn)結果集封裝

@Results:可以與@Result 一起使用媳握,封裝多個結果集

@ResultMap:實現(xiàn)引用@Results 定義的封裝

@One:實現(xiàn)一對一結果集封裝

@Many:實現(xiàn)一對多結果集封裝

@SelectProvider: 實現(xiàn)動態(tài) SQL 映射

@CacheNamespace:實現(xiàn)注解二級緩存的使用

12.2 使用注解實現(xiàn)復雜關系映射開發(fā)

實現(xiàn)復雜關系映射之前我們可以在映射文件中通過配置<resultMap>來實現(xiàn),在使用注解開發(fā)時我們需要借

助@Results 注解磷脯,@Result 注解蛾找,@One 注解,@Many 注解争拐。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腋粥,一起剝皮案震驚了整個濱河市晦雨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖挎挖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罗珍,死亡現(xiàn)場離奇詭異覆旱,居然都是意外死亡团南,警方通過查閱死者的電腦和手機拷橘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門穷绵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵佛纫,是天一觀的道長。 經(jīng)常有香客問我,道長灼芭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任椿争,我火速辦了婚禮邦危,結果婚禮上洋侨,老公的妹妹穿的比我還像新娘希坚。我一直安慰自己获洲,他們只是感情好,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布烤送。 她就那樣靜靜地躺著牢裳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叶沛。 梳的紋絲不亂的頭發(fā)上蒲讯,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機與錄音灰署,去河邊找鬼判帮。 笑死,一個胖子當著我的面吹牛溉箕,可吹牛的內(nèi)容都是我干的晦墙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肴茄,長吁一口氣:“原來是場噩夢啊……” “哼晌畅!你這毒婦竟也來了?” 一聲冷哼從身側響起寡痰,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤抗楔,失蹤者是張志新(化名)和其女友劉穎棋凳,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體连躏,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡剩岳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了入热。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拍棕。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖勺良,靈堂內(nèi)的尸體忽然破棺而出绰播,到底是詐尸還是另有隱情,我是刑警寧澤尚困,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布幅垮,位于F島的核電站,受9級特大地震影響尾组,放射性物質(zhì)發(fā)生泄漏忙芒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一讳侨、第九天 我趴在偏房一處隱蔽的房頂上張望呵萨。 院中可真熱鬧,春花似錦跨跨、人聲如沸潮峦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忱嘹。三九已至,卻和暖如春耕渴,著一層夾襖步出監(jiān)牢的瞬間拘悦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工橱脸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留础米,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓添诉,卻偏偏與公主長得像屁桑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子栏赴,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

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