SSM-Mybatis-映射器-select
select元素代表select語句,用于查詢。元素配置如下:
元素 | 說明 | 備注 |
---|---|---|
id | 它和Mapper的命名空間組合起來是唯一的,供Mybatis調用 | 如果命名空間和id結合起來不唯一,則Mybatis會抛出異常 |
parameter Type | 可以給出類的全命名,也可以給出别名,但是别名必須是Mybatis内部定義或者自定義 | 可選擇java Bean,Map等簡單的參數類型傳遞給SQL |
parameterMap | 即将廢棄 | — |
resultType | 定義類的全路徑,在允許自動比對的情況下,結果集通過javaBean的規範映射;或定義int double float map等參數;也可以使用别名,但要符合别名規範,且不能和resultMap同時使用 | 常見的參數之一,比如統計總條數時可以把它的值設定為int |
resultMap | 他是映射集的引用,将執行強大的映射功能,不能與resultType同時使用,且resultMap提供自定義規則的機會 | Mybatis最複雜的元素,可以配置映射規則,聯機,typeHandler等 |
flushCache | 調用SQL以後,是否要求Mybatis清除之前查詢的本地緩存和二級緩存 | 取值為布爾,預設false |
useCache | 啟動二級緩存的開關,是否要求Mybatis将此次結果存儲 | 取值為布爾,預設true |
timeout | 設定逾時參數,逾時時将抛出異常,機關為秒 | 預設值是資料庫廠商提供的JDBC驅動所設定的秒數 |
fetchSize | 擷取記錄的總條數設定 | 預設值是資料庫廠商提供的JDBC驅動所設定的條數 |
statementType | 告訴Mybatis使用哪個JDBC的Statement工作,可選 STATEMENT,PREPARED 或 CALLABLE。這會讓 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement | 預設值:PREPARED |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等價于 unset) 中的一個,預設值為 unset (依賴資料庫驅動)。 | 預設值是資料庫廠商提供的JDBC驅動所設定 |
databaseId | 如果配置了資料庫廠商辨別(databaseIdProvider),MyBatis 會加載所有不帶 databaseId 或比對目前 databaseId 的語句;如果帶和不帶的語句都有,則不帶的會被忽略。 | 提供多種資料庫的支援 |
resultOrdered | 這個設定僅針對嵌套結果 select 語句:如果為 true,将會假設包含了嵌套結果集或是分組,當傳回一個主結果行時,就不會産生對前面結果集的引用。 這就使得在擷取嵌套結果集的時候不至于記憶體不夠用。預設值: 。 | 取值為布爾,預設false |
resultSets | 置僅适用于多結果集的情況。它将列出語句執行後傳回的結果集并賦予每個結果集一個名稱,多個名稱之間以逗号分隔。 | 很少使用 |
自動映射和駝峰命名
在配置檔案中通過元素settting元素可以配置這兩種選項,autoMappingBehavior和mapUnderscoreToCamelCase,他們控制自動映射和駝峰命名的開關
這兩種方式都建立在SQL列名和POJO屬性名的映射關系上。
傳遞多個參數
-
使用map接口傳遞參數
Mybatis中允許map接口通過鍵值對傳遞多個值,把接口方法定義為:
傳遞給映射器是一個map對象,使用他在SQL中的映射關系
測試:<select id="finRoleByMap" parameterType="map" resultType="role"> select id,roleName as roleName,note from t_role where role_name like contcat('%',#{roleName},'%') and note like concat('%',#{roleName},'%') </select>
這種方式用的不多,原有有兩個:RoleMapperroleMapper=SqlSession.getMapper(RoleMapper.class); Map<String,Object> parameterMap=new HashMap<String,Object>(); parameterMap.put("roleName","1"); parameterMap.put("note","1"); List<Role> roles=roleMapper.finRoleByMap(parameterMap);
- map是一個鍵值對應的集合,使用者需要通過閱讀它的鍵,才能明白其作用
- map不能限定傳遞的參數類型,業務性質差,可讀性差
-
使用注解傳遞多個參數
@Param:可以通過去定義映射器的參數名稱,使用它可以得到更好的可讀性,接口定義如下:
上面代碼可讀性大大提高,能明确roleName的角色名稱,而note是備注,一幕了然,修改如下映射檔案代碼:public List<Role> findRoleByAnnotation(@Param("roleName") String roleName, @Param("note") String note);
這種方式有一個缺點:當SQL很複雜,用于大于10個參數,那麼接口方法參數個數多,使用起來不友善<select id="findRoleByAnnotation" resultType="role"> select id,roleName as roleName,note from t_role where role_name like contcat('%',#{roleName},'%') and note like concat('%',#{roleName},'%') </select>
-
使用Java Bean傳遞多個參數
這種方式需要定義一個參數POJO
package com.ssm; public class RoleParams{ private String roleName; private String note; //getter and setter //...s }
把接口定義為
Java Bean的roleName屬性代表角色名稱,note代表備注,映射檔案如下:
測試:<select id="findRolesByBean" parameterType="com.ssm.RoleParams" resultType="role"> select id,roleName as roleName,note from t_role where role_name like contcat('%',#{roleName},'%') and note like concat('%',#{roleName},'%') </select>
RoleMapper roleMapper=SqlSession.getMapper(RoleMapper.class); RoleParams roleParams=new RoleParams(); roleParams.setRoleName("1"); roleParams.setNote("1"); List<Role> roles= roleMapper.findRolesByBean(roleParams);
-
混合使用
例如查詢一個角色,可以通過角色名稱和備注進行查詢,于此同時還需要支援分頁,分頁的POJO代碼如下:
接口設計:public class PageParams{ private int start; private int limit; //getter and setter... }
映射檔案://混合使用了注解和Java Bean方式 public List<Role> findByMix(@Param("params") RoleParams roleParams, @Param("page") PageParam pageParam);
總結:<select id="findByMix" resultType="role"> select id,roleName as roleName,note from t_role where role_name like contcat('%',#{params.roleName},'%') and note like concat('%',#{params.note},'%') limti #{page.start},#{page.limit} </select>
- Map方式不推薦使用,可讀性差,擴充維護困難
- 注解方式,參數小于等于5個左右的推薦使用
- Java Bean方式,當參數大于等于5個的時候,推薦使用
- 混合方式,要明确參數的合理性
使用resultMap映射結構集
為了支援複雜的映射,select提供了resultMap屬性,定義例子如下:
<mapper namespace="com.ssm.RoleMapper">
<!-- id為resultMap的唯一辨別,type辨別用哪個類作為其映射的類(可以使用别名和全限定類名) -->
<resultMap id= "roleMap" type="role">
<!--id代表resultMap的主鍵,result代表屬性-->
<!--property代表POJO的屬性名稱,column代表SQL的列名-->
<id property="id" column="id"/>
<result property="roleName" column="role_name"/>
<result property="note" column="note"/>
</resultMap>
<!--resultMap制定了采用哪個resultMap作為其映射-->
<select id="getRoleUseResultMap" parameterType="long" resultMap="roleMap">
select id,role_name,note from t_role where id=#{id}
</select>
</mapper>
分頁參數RowBounds
Mybatis内置一個專門處理分頁的類:RowBounds
該類屬性:
- offset:是偏移量,即從第幾行開始讀取記錄。
- limit:是限制條數
例子:
//給接口添加一個RowBounds參數
public List<Role> findByRowBounds(@Param("roleName") String rolename,
@Param("note") String note,
RowBuounds rowBounds);
映射檔案:
<select id="findByRowBounds" resultType="role">
select id ,role_name as roleName from t_role
where role_name like
concat('%',#{roleName},'%')
and note like concat('%',#{note},'%')
</select>
由于RowBounds是Mybatis的一個附加參數,Mybatis會自動識别它,進行分頁功能,是以上面代碼沒有寫入任何相關RowBounds的内容
使用:
SqlSession sqlSession=null;
try{
sqlSession=SqlSessionFactoryUtils.openSqlSession();
RoleMapper roleMapper=new RoleMapper();
RowBounds rowBounds=new RowBounds(0,20);
List<Role> roleList=roleMapper.findByRowBounds("role_name","note",rowBounds);
}catch(Exception ex){
ex.printStackTrace();
}finally{
if(SqlSession !=null){
sqlSession.close();
}
}
總結:RowBounds分頁的運用場景,他隻能運用于一些小資料量的查詢。對大資料查詢,它的性能不佳