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.url}"/>
<property name="username" 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.url}"/>
<property name="username" 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 注解争拐。