MyBatis框架真正強(qiáng)大之處就在于SQL映射語(yǔ)句砰奕,mybatis專注于SQL脯丝,對(duì)開(kāi)發(fā)人員來(lái)說(shuō)可以極大限度地進(jìn)行SQL調(diào)優(yōu),以保證性能饶囚。方便使用mybatis框架帕翻,現(xiàn)在就來(lái)談?wù)凷QL映射文件。
<mapper>標(biāo)簽是根元素節(jié)點(diǎn)萝风,只有一個(gè)屬性namespace(命名空間)嘀掸,作用:
- 用于區(qū)分不同的mapper,全局唯一规惰。
- 綁定DAO接口睬塌,即面向接口編程。當(dāng)namespace綁定了某個(gè)接口后歇万,可不用寫該接口的實(shí)現(xiàn)類揩晴,mybatis會(huì)根據(jù)接口的完整限定名查找到對(duì)應(yīng)的mapper配置來(lái)執(zhí)行SQL語(yǔ)句,因此namespace的命名必須跟接口同名贪磺。
注意:接口中的方法與映射文件中的SQL語(yǔ)句id應(yīng)對(duì)應(yīng)硫兰。如下代碼中的id=“selectUserById”,則DAO接口中就有selectUserById()與之對(duì)應(yīng)寒锚。
<select id="selectUserById" resultType="xiaojiang.mybatisdemo.entity.User">
select id,name,sex from user where id = #{id}
</select>
關(guān)于#{...}和${...}的符號(hào)作用:“#”一般是用做參數(shù)傳遞劫映,告訴mybatis生成PreparedStatement參數(shù)违孝,而“{}”一般是作為占位符。
<resultMap>標(biāo)簽泳赋,用來(lái)描述數(shù)據(jù)庫(kù)結(jié)果集和對(duì)象的對(duì)應(yīng)關(guān)系雌桑,即如何將結(jié)果集映射到j(luò)ava對(duì)象中。
還有<select>祖今,<delete>校坑,<update>,<insert>標(biāo)簽 對(duì)應(yīng)增刪改查映射操作千诬。
<resultMap id="唯一標(biāo)識(shí)耍目,供外部引用" type="映射結(jié)果類型,如:基本類型和pojo類">
<result property="實(shí)體對(duì)象屬性" column="數(shù)據(jù)表中的字段名" /> //表示把查詢出來(lái)的字段對(duì)應(yīng)的值賦給實(shí)體對(duì)象的屬性
......
</resultMap>
增刪改查標(biāo)簽內(nèi)的parameterType屬性:表示查詢語(yǔ)句傳入?yún)?shù)的類型的完全限定名或別名大渤,支持復(fù)雜數(shù)據(jù)類型,用來(lái)指定輸入?yún)?shù)的類型掸绞。resultType屬性:查詢語(yǔ)句返回結(jié)果類型的完全限定名或別名泵三。用來(lái)指定輸出結(jié)果的類型。
總結(jié):對(duì)于一個(gè)參數(shù)的情況下衔掸,mybatis傳入?yún)?shù)類型可以是基本類型烫幕,通過(guò)#{參數(shù)名}即可獲取傳入的值,若是多參數(shù)的情況下敞映,即多條件查詢我們?nèi)绾螌?shí)現(xiàn)呢较曼?我們可以考慮將查詢對(duì)象封裝成對(duì)象進(jìn)行入?yún)ⅰP枰獜?fù)雜數(shù)據(jù)類型來(lái)支持振愿,包括Javabean實(shí)體類和Map類型捷犹,通過(guò)#{屬性名}或#{Map的key}來(lái)獲取傳入的值。
剖析一下resultMap和resultType的區(qū)別冕末、關(guān)聯(lián)萍歉、應(yīng)用場(chǎng)景
- 區(qū)別:mybatis使用resultType做自動(dòng)映射時(shí),必須保證字段名和POJO類的屬性名一致档桃。resultType表示直接返回類型枪孩,resultMap是對(duì)外部resultMap定義的引用,表示返回結(jié)果映射到哪一個(gè)<resultMap>上藻肄。
- 關(guān)聯(lián):進(jìn)行查詢映射時(shí)蔑舞,查詢出來(lái)的每個(gè)字段都對(duì)應(yīng)一個(gè)Map,包含著字段名和對(duì)應(yīng)的值嘹屯。resultType和resultMap本質(zhì)上是一樣的攻询,都是Map數(shù)據(jù)結(jié)構(gòu)。
- resultMap的應(yīng)用場(chǎng)景是:用于數(shù)據(jù)庫(kù)字段名與對(duì)象屬性不一致或者需要做復(fù)雜的聯(lián)合查詢州弟,以便自由控制映射結(jié)果蜕窿,即查詢出來(lái)顯示想要顯示的幾列數(shù)據(jù)而不是全部谋逻。
注:resultType和resultMap這兩個(gè)屬性絕對(duì)不能同時(shí)存在。
resultMap默認(rèn)的自動(dòng)映射級(jí)別是PARTIAL桐经,即自動(dòng)匹配所有屬性毁兆,有內(nèi)部嵌套(association、collection)的除外阴挣∑椋可通過(guò)mybatis-cfg.xml配置文件修改,如下:
<settings>
<setting name="autoMappingBehavior" value="NONE"> //NONE表示禁止自動(dòng)匹配畔咧,//FULL表示自動(dòng)匹配所有屬性茎芭。
</settings>
注意:對(duì)應(yīng)增刪改操作,一般執(zhí)行完都是返回SQL語(yǔ)句影響的行數(shù)誓沸,所以DAO層接口的返回值設(shè)置為int類型梅桩,還有這類操作是沒(méi)有resultType屬性的,只有查詢操作才需要對(duì)返回結(jié)果的類型進(jìn)行指定拜隧。
傳遞多參數(shù)查詢的幾種方法
- 1宿百、封裝成對(duì)象進(jìn)行參數(shù)傳遞
- 2、直接多參數(shù)入?yún)⒑樘恚褂聾Param注解垦页,如下:
//修改接口方法
public int updatePwd(@Param("uid")Integer id,@Param("upwd")String pwd);
//修改mapper.xml映射文件
<update id="updatePwd">
update user set pwd=#{upwd} where id=#{uid}
</update>
實(shí)現(xiàn)resultMap高級(jí)結(jié)果映射
- association處理一對(duì)一關(guān)聯(lián)關(guān)系
場(chǎng)景:即POJO對(duì)象中內(nèi)嵌其他Javabean對(duì)象。
對(duì)應(yīng)映射文件代碼
<resultMap id="唯一標(biāo)識(shí)干奢,供外部引用" type="映射結(jié)果類型痊焊,如:基本類型和pojo類">
<id property="id" column="數(shù)據(jù)表字段名id" /> //非必須子標(biāo)簽,不過(guò)一般都要加入忿峻,否則mybatis雖能正常工作薄啥,但是性能開(kāi)銷嚴(yán)重
<result property="實(shí)體對(duì)象屬性" column="數(shù)據(jù)表中的字段名" /> //表示把查詢出來(lái)的字段對(duì)應(yīng)的值賦給實(shí)體對(duì)象的屬性
......
<association property="其他Javabean對(duì)象" javaType="其他Javabean類">
<id property="id" column="數(shù)據(jù)表字段名id">
<result property="屬性" column="字段名" />
......
</association>
</resultMap>
- collection處理一對(duì)多關(guān)聯(lián)關(guān)系
場(chǎng)景:即POJO對(duì)象中內(nèi)嵌一個(gè)集合列表。
對(duì)應(yīng)映射文件代碼
<resultMap id="唯一標(biāo)識(shí)逛尚,供外部引用" type="映射結(jié)果類型罪佳,如:基本類型和pojo類">
<id property="id" column="數(shù)據(jù)表字段名id" /> //非必須子標(biāo)簽,不過(guò)一般都要加入黑低,否則mybatis雖能正常工作赘艳,但是性能開(kāi)銷嚴(yán)重
<result property="實(shí)體對(duì)象屬性" column="數(shù)據(jù)表中的字段名" /> //表示把查詢出來(lái)的字段對(duì)應(yīng)的值賦給實(shí)體對(duì)象的屬性
......
<collection property="其他集合對(duì)象,如:List<User> userList" javaType="對(duì)應(yīng)的泛型類克握,如:User">
<id property="id" column="數(shù)據(jù)表字段名id">
<result property="屬性" column="字段名" />
......
</collection>
</resultMap>
MyBatis緩存
一級(jí)緩存存的是SQL語(yǔ)句蕾管,二級(jí)緩存存的是結(jié)果對(duì)象。默認(rèn)情況下mybatis是未開(kāi)啟緩存的
- 一級(jí)緩存:是基于PerpetualCache的HashMap本地緩存菩暗,作用域是session掰曾,當(dāng)session被flush或者close后,cache就被清空停团。
- 二級(jí)緩存:是global caching旷坦,可被所有SqlSession共享掏熬。
//開(kāi)啟mybatis緩存
<settings>
<setting name="cacheEnabled" value="true" />
</settings>
也可單獨(dú)在mapper.xml文件中對(duì)指定查詢開(kāi)啟緩存
<select id="getUserList" resultType="User" useCache="true">
......
</select>