天天看點

SSM-Mybatis-映射器-selectSSM-Mybatis-映射器-select

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

取值為布爾,預設false
resultSets 置僅适用于多結果集的情況。它将列出語句執行後傳回的結果集并賦予每個結果集一個名稱,多個名稱之間以逗号分隔。 很少使用

自動映射和駝峰命名

​ 在配置檔案中通過元素settting元素可以配置這兩種選項,autoMappingBehavior和mapUnderscoreToCamelCase,他們控制自動映射和駝峰命名的開關

​ 這兩種方式都建立在SQL列名和POJO屬性名的映射關系上。

傳遞多個參數

  1. 使用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);
               
    這種方式用的不多,原有有兩個:
    1. map是一個鍵值對應的集合,使用者需要通過閱讀它的鍵,才能明白其作用
    2. map不能限定傳遞的參數類型,業務性質差,可讀性差
  2. 使用注解傳遞多個參數

    @Param:可以通過去定義映射器的參數名稱,使用它可以得到更好的可讀性,接口定義如下:

    public List<Role> findRoleByAnnotation(@Param("roleName") String roleName,
                                           @Param("note") String note);
               
    上面代碼可讀性大大提高,能明确roleName的角色名稱,而note是備注,一幕了然,修改如下映射檔案代碼:
    <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>
               
    這種方式有一個缺點:當SQL很複雜,用于大于10個參數,那麼接口方法參數個數多,使用起來不友善
  3. 使用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);
               
  4. 混合使用

    例如查詢一個角色,可以通過角色名稱和備注進行查詢,于此同時還需要支援分頁,分頁的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

​ 該類屬性:

  1. offset:是偏移量,即從第幾行開始讀取記錄。
  2. 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分頁的運用場景,他隻能運用于一些小資料量的查詢。對大資料查詢,它的性能不佳

繼續閱讀