使用MyBatis實(shí)現(xiàn)條件查詢
1.SQL映射文件:
MyBatis真正的強(qiáng)大之處就在于SQL映射語(yǔ)句,MyBatis專(zhuān)注于SQL,對(duì)于開(kāi)發(fā)人員來(lái)說(shuō)也是極大限度的進(jìn)行SQL調(diào)優(yōu),以保證性能。下面是SQL映射文件的幾個(gè)頂級(jí)元素的配置:
1.mapper:映射文件的根節(jié)點(diǎn),只有一個(gè)屬性namespace(命名空間),作用如下:
????(1)用于區(qū)分不同的mapper,全局唯一。
????(2)綁定DAO接口,即面向接口編程,當(dāng)綁定一個(gè)接口,就不用寫(xiě)此接口的實(shí)現(xiàn)類(lèi),會(huì)通過(guò)接口的完全限定名找到對(duì)應(yīng)的mapper配置來(lái)執(zhí)行SQL語(yǔ)句,所以,namespace的命名必須要寫(xiě)接口的完全限定名。
????2.cache:配置給定命名空間的緩存。
????3.cache-ref:從其他命名空間引用緩存配置。
????4.resultMap:用來(lái)描述數(shù)據(jù)庫(kù)結(jié)果集和對(duì)象的對(duì)應(yīng)關(guān)系。
????5.sql:可以重用的SQL塊,也可以被其他語(yǔ)句引用。
????6.insert:映射插入語(yǔ)句。
????7.update:更新映射語(yǔ)句。
????8.delete:刪除映射語(yǔ)句。
????9.select:映射查詢語(yǔ)句。
2.使用select完成單條件查詢
<select id = "GetUserByName" resultType = "User" parameterType = "string">
select * from user where name like concat('%',#{name},'%')? ? //按照姓名模糊查詢。
</select>
????這是一個(gè)id為GetUserByName的映射語(yǔ)句,參數(shù)類(lèi)型為string,返回類(lèi)型為User。
#{參數(shù)名}:告訴MyBatis生成的PreparedStatement參數(shù),相對(duì)于JDBC,改參數(shù)被標(biāo)識(shí)為‘?’。
id:命名空間的唯一標(biāo)識(shí)符,可以被用來(lái)引用這條語(yǔ)句。
parameterType:表示查詢語(yǔ)句傳入?yún)?shù)的類(lèi)型和完全限定名或別名。支持基礎(chǔ)數(shù)據(jù)類(lèi)型和復(fù)雜數(shù)據(jù)類(lèi)型。上述實(shí)例中傳入的參數(shù)是一個(gè)別名,代表String。
? ? ? 別名與Java類(lèi)型映射
| 別名 | 映射的類(lèi)型 | 別名 | 映射的類(lèi)型 |
| string | String | double | Double |
| byte | Byte | float | Float |
| long | Long | boolean | Boolean |
| short | Short | date | Date |
| int | Integer | map | Map |
| integer | Integer | hashmap | HashMap |
| arraylist | ArrayList | list | List |
resultType:查詢語(yǔ)句返回結(jié)果類(lèi)型的完全限定名或別名。別名使用方式和parameterType是一樣的。
2.使用select完成多條件查詢
使用復(fù)雜數(shù)據(jù)類(lèi)型,把條件參數(shù)封裝為對(duì)象、Map進(jìn)行入?yún)ⅰ?/p>
不管什么類(lèi)型的參數(shù),或者多少個(gè)參數(shù),都可以封裝為一個(gè)Map進(jìn)行入?yún)?,通過(guò)Map的key進(jìn)行獲取傳入的值。
1<select id="GetUserByNameAndRoleId" resultType="User"
2 ? ?parameterType="map">
3??? ?select * from smbms_user where userName like
4 ? ?CONCAT('%',#{userName},'%')
5 ? ?and userRole = #{userRole}
6</select>3.使用resultMap完成查詢結(jié)果的展現(xiàn)
????resultMap:做自定義映射,實(shí)體類(lèi)屬性名和數(shù)據(jù)庫(kù)列名不一致的情況下,并且可以指定要顯示的列,使用靈活 應(yīng)用廣泛。
1<resultMap type="User" id="userMap">
2????<id column="id" property="id"/>
3?? ?<result column="userName" property="Name"/> //字段名和屬性名不一致的情況下。
4</resultMap>屬性和子節(jié)點(diǎn):
????id:唯一標(biāo)識(shí),此id值用于select元素resultMap屬性的引用。
????type:標(biāo)識(shí)該resultMap的映射結(jié)果類(lèi)型。
????result子節(jié)點(diǎn):標(biāo)識(shí)一些簡(jiǎn)單屬性,其中column屬性代表數(shù)據(jù)庫(kù)的字段名,property代表查詢出來(lái)的字段名映射到pojo類(lèi)的某個(gè)屬性。
????id子節(jié)點(diǎn):與result子節(jié)點(diǎn)作用一樣,一般表示數(shù)據(jù)庫(kù)的主鍵列。
-------------------------------------------------------------------------------------------------------
resultType和resultMap的對(duì)比如下 :
1.resultType:直接表示返回類(lèi)型, 包括基本數(shù)據(jù)類(lèi)型和復(fù)雜數(shù)據(jù)類(lèi)型。
2.resultMap:外部resultMap定義的引用,通過(guò)對(duì)應(yīng)的外部resultMap的id,表示結(jié)果映射到哪個(gè)resultMap上,一般用于字段名和屬性名不一致的情況,或者需要做復(fù)雜的聯(lián)合查詢以便自由控制映射結(jié)果。
3.兩者的關(guān)聯(lián)
????當(dāng)進(jìn)行查詢時(shí),查詢出來(lái)的每個(gè)字段都會(huì)放在一個(gè)Map里,當(dāng)查詢?cè)胤祷貙傩允莚esultType的時(shí)候,會(huì)將鍵值對(duì)取出賦所指定的屬性。其實(shí)MyBatis的每個(gè)查詢映射的返回類(lèi)型都是resultMap,只是當(dāng)我們使用resultType的時(shí)候,會(huì)自動(dòng)把對(duì)應(yīng)的值賦給所指定的對(duì)象屬性,當(dāng)使用resultMap時(shí)候,因?yàn)閙ap不是很好的表示領(lǐng)域,我們就進(jìn)一步的轉(zhuǎn)化為對(duì)應(yīng)的實(shí)體對(duì)象。resultMap主要作用于復(fù)雜的聯(lián)合查詢上。
注意:resultType和resultMap本質(zhì)是一樣的,都是Map數(shù)據(jù)結(jié)構(gòu),但是二者不能同時(shí)存在。
4.resultMap的自動(dòng)映射級(jí)別:默認(rèn)級(jí)別為PARTIAL,也可以在settings更改值。
1<settings>
2????????<!-- 設(shè)置resultMap的自動(dòng)映射級(jí)別為NONE(禁止自動(dòng)匹配) -->
3??????<setting name = "autoMappingBehavior" value = "NONE">
4</settings>4.使用MyBatis實(shí)現(xiàn)增刪改操作
1.使用insert完成增加操作
<insert id="add" parameterType="User">
? INSERT INTO user(userName,userCode) VALUES(#{userName},#{userCode})</insert>2.使用update完成修改操作
<update id="update" parameterType="User">
? ????? UPDATE user SET userName= #{userName},userCode= #{userCode} WHERE id = #{id}? ??
</update>
3.使用delete完成刪除操作
<delete id="User" parameterType="integer"> ? ? ? ?delete from user ? ? ? ?where id = #{id}
</delete>
元素中的屬性:
????id:與select元素id一樣,命名空間的唯一標(biāo)識(shí)符。
????parameterType:傳入?yún)?shù)的類(lèi)型的完全限定名或者別名。
對(duì)于增刪改操作的注意事項(xiàng):
????(1)該類(lèi)型的操作本身默認(rèn)返回執(zhí)行SQL影響的行數(shù),所以DAO層的接口方法返回值一般為int類(lèi)型,最好不要boolean類(lèi)型。
????(2)insert、update、delete元素中均沒(méi)有resultType屬性,只有查詢操作需要對(duì)返回結(jié)果類(lèi)型(resultType/resultMap)進(jìn)行相應(yīng)的指定。
?5.使用@param注解實(shí)現(xiàn)多參數(shù)入?yún)?/strong>
????使用注解用來(lái)傳入多個(gè)參數(shù),相當(dāng)于給該參數(shù)重命名,在SQL映射文件中需要使用#{注解名稱(chēng)}來(lái)傳入?yún)?shù)?!?/p>
public user GetUserByIdAndName(@Param("id") Integer id,@Param("Name") String Name);????當(dāng)參數(shù)為基礎(chǔ)類(lèi)型時(shí),無(wú)論是多參數(shù)還是單參數(shù),都使用@param注解進(jìn)行參數(shù)的傳遞為好!
使用resultMap實(shí)現(xiàn)高級(jí)結(jié)果映射
1.association:
????映射到JavaBean的某個(gè)復(fù)雜的”數(shù)據(jù)類(lèi)型”屬性,僅處理一對(duì)一的關(guān)聯(lián)關(guān)系。

association的屬性節(jié)點(diǎn):
????property:映射數(shù)據(jù)庫(kù)列的實(shí)體對(duì)象屬性名。
????javaType:完整的java類(lèi)名和限定名。propert所映射的屬性的類(lèi)型。
????子元素:id:一般為映射主鍵,可以提高性能。
????result:
????????column:映射的數(shù)據(jù)庫(kù)的字段名。
????????property:映射的數(shù)據(jù)列對(duì)應(yīng)的實(shí)體對(duì)象屬性。
2.collection:
? 映射到JavaBean的某個(gè)復(fù)雜的”數(shù)據(jù)類(lèi)型”屬性,這個(gè)屬性是一個(gè)集合列表,處理一對(duì)多的關(guān)聯(lián)關(guān)系。

????ofType:完整的java類(lèi)名和限定名。propert所映射的屬性的類(lèi)型。
????其余和association基本一致。
MyBatis緩存
????1.一級(jí)緩存:基于PerpetualCache(MyBatis自帶)的HashMap本地緩存。作用域在Session域內(nèi),當(dāng)session flush或者close之后,該緩存被清空。
????2.二級(jí)緩存:global Cache,超出session范圍之外,可以被所有SqlSession共享。開(kāi)啟它只需在MyBatis的核心配置文件 settings 設(shè)置即可。
????補(bǔ)充:一級(jí)緩存緩存的是SQL語(yǔ)句,二級(jí)緩存緩存的是結(jié)果對(duì)象。
????3.二級(jí)緩存配置:
????(1)開(kāi)啟二級(jí)緩存;
<settings>
<setting name="cacheEnabled" value = "true"/>
<settings>????(2)mapper文件中設(shè)置緩存,默認(rèn)是沒(méi)有開(kāi)啟緩存的。作用域是針對(duì)namespace而言的,只在namespace內(nèi)的查詢才能共享這個(gè)cache。
????(3)對(duì)個(gè)別查詢進(jìn)行緩存,單獨(dú)設(shè)置cache:
<select id = "getUser" resultType = "User" useCache = "true">
? ?...........
</select>????補(bǔ)充:對(duì)MyBatis的緩存了解就可以了,對(duì)結(jié)果集做緩存并不是MyBatis所擅長(zhǎng)的,而且性能也不是很好,它專(zhuān)心做的應(yīng)該是SQL映射。
-----------------------------------------------------------------------------------------------------------------------
動(dòng)態(tài)SQL
一、使用動(dòng)態(tài)SQL完成多條件查詢。
????動(dòng)態(tài)SQL基于OGNL的表達(dá)式,我們可以方便的在SQL語(yǔ)句中實(shí)現(xiàn)某些邏輯,用于實(shí)現(xiàn)動(dòng)態(tài)SQL元素如下:
if:利用if實(shí)現(xiàn)簡(jiǎn)單的條件選擇。
choose(when,otherwise):相當(dāng)于java中的switch語(yǔ)句,通常與when和otherwise搭配。
set:解決動(dòng)態(tài)更新語(yǔ)句。
trim:靈活的去除多余的關(guān)鍵字。
foreach:迭代一個(gè)集合,通常用于in條件。
二、if+where實(shí)現(xiàn)多條件查詢

????where元素可以智能的處理and 和 or 的多余問(wèn)題, 不需擔(dān)心多余關(guān)鍵字導(dǎo)致語(yǔ)法錯(cuò)誤。
if元素的test用于判斷表達(dá)式是否符合,符合則繼續(xù)拼接SQL語(yǔ)句。
三、if+trim+foreach實(shí)現(xiàn)多條件查詢

(1)trim的屬性:
????prefix:前綴: 作用是通過(guò)自動(dòng)識(shí)別是否有返回值后,在trim包含的內(nèi)容上加上前綴,如上述示例的where。
????suffix:后綴: 作用是在trim包含的內(nèi)容上加上后綴。
????prefixOverrides: 對(duì)于trim包含內(nèi)容的首部進(jìn)行指定內(nèi)容,(如上述示例的 and | or) 的忽略(去余);
????suffixOverrides: 對(duì)于trim包含內(nèi)容的首位部進(jìn)行指定內(nèi)容的忽略。
(2)foreach的屬性:
????item:表示集合中每一個(gè)元素進(jìn)行迭代時(shí)的別名。
????index: 指定一個(gè)名稱(chēng),表示在迭代的過(guò)程中,每次迭代到的位置。
????open:表示該語(yǔ)句以什么開(kāi)始(既然是in條件語(yǔ)句,必然是 ' ( ' 開(kāi)始)
????separator: 表示每次進(jìn)行迭代的時(shí)候以什么符號(hào)作為分隔符(既然是in條件語(yǔ)句,必然是 ' , ' 分隔)
????close:?表示該語(yǔ)句以什么結(jié)束(既然是in條件語(yǔ)句,必然是 ' ) ' 結(jié)束)
????collection:最關(guān)鍵,并且最容易出錯(cuò)的屬性。需注意,該屬性必須指定,不同情況下,該屬性值是不同的,主要有三種情況:
????若傳入的參數(shù)是單參數(shù)且類(lèi)型為一個(gè)List的時(shí)候,屬性值為list;
????若傳入的參數(shù)是單參數(shù)且類(lèi)型為一個(gè)數(shù)組的時(shí)候,屬性值為array;
????若傳入的參數(shù)為多參數(shù)時(shí),就需要封裝為一個(gè)map集合進(jìn)行處理。屬性值為Map的key;
?
使用set更新操作,類(lèi)似于上述示例使用方法:

三、choose(when、otherwise)

????when元素:當(dāng)test屬性中的條件滿足時(shí),就會(huì)輸出when元素中的內(nèi)容,并且當(dāng)when中一旦有條件滿足時(shí),就會(huì)跳出choose,所以只有一個(gè)條件會(huì)被輸出。
????otherwise元素:當(dāng)when中的所有條件都不滿足時(shí),則會(huì)輸出此元素的內(nèi)容。
四、MyBatis實(shí)現(xiàn)分頁(yè)功能
????1.使用聚合函數(shù)獲得總記錄數(shù)-
????2.實(shí)現(xiàn)分頁(yè)通過(guò)limit(起始位置,頁(yè)面顯示量)
補(bǔ)充:起始位置的下標(biāo)? = (當(dāng)前頁(yè)碼 - 1 ) * 頁(yè)面顯示量
