MyBatis總結-2

SQL映射文件

mapper.xml

SQL映射文件頂級元素配置

  • mapper:映射文件的根元素點,只有一個屬性namespace(命名空間),其作用如下:
    • 用於區分不同的mapper,全局唯一
    • 綁定dao接口,即面向接口編程(mapper.xml的namespace必須和接口同名)
    • 在不同的mapper文件中,子元素的id可以相同(MyBatis通過namespace和子元素的id聯合區分)
  • cache:配置給定命名空間的緩存
  • cache-ref:從其他命名空間引用緩存配置
  • resultMap:用來描述數據庫結果集和對象的對應關係
  • sql:可重用的SQL塊,也可以被其他語句引用
  • insert:映射插入語句
  • update:映射更新語句
  • select:映射查詢語句
  • delete:映射刪除語句

使用select

    <!-- 根據供應商名稱查詢供應商列表(模糊查詢) -->
    <select id="getProviderListByproName" resultType="Provider"
        parameterType="string">
        SELECT * FROM smbms_provider WHERE proName LIKE CONCAT
        ('%',#{proName},'%')
    </select>
  • id
  • 命名空間中唯一的標識符
  • 接口中的方法與映射文件中的SQL語句id一一對應
  • parameterType
  • 傳入SQL語句的參數類型
  • 它支持基礎數據類型和複雜數據類型
    • 對於一個參數入參可以使用Java基礎數據類型,通過#{參數名}取值
    • 若是多參數入參,需要複雜參數數據類型來支持,包括Java實體類、Map,通過#{屬性名}或#{Map的key}來獲取傳入的參數值
  • 內建別名對大小寫不敏感
    這裏寫圖片描述
  • resultType
  • SQL語句返回值類型的完整類名或別名

使用resultMap

    <!-- 數據庫字段名與pojo的屬性名不一致時,自動映射 -->
    <resultMap type="User" id="userList">
        <result property="id" column="id" />
        <result property="userCode" column="userCode" />
        <result property="userName" column="userName" />
        <result property="phone" column="phone" />
        <result property="birthday" column="birthday" />
        <result property="gender" column="gender" />
        <result property="userRole" column="userRole" />
        <result property="userRoleName" column="roleName" />
    </resultMap>
    <!-- 查詢用戶列表(參數:對象入參) -->
    <select id="getUserList" resultMap="userList" parameterType="User">
        SELECT u.*,r.`roleName` FROM `smbms_user` u,`smbms_role` r WHERE
        u.`userName` LIKE CONCAT ('%',#{userName},'%') AND
        u.`userRole`=#{userRole} AND
        u.`userRole`=r.`id`
    </select>

resultMap元素用來描述如何將結果集映射到Java對象,此處使用resultMap對列表展示所需的必要字段來進行自由映射,特別是當數據庫的字段名和POJO中的屬性名不一致的情況下,比如角色名稱,字段名column是roleName,而User對象的屬性名則爲userRoleName,此時就要做映射。

resultMap元素的屬性值和子節點

  • id 屬性:resultMap的唯一標識 (此id值用於select元素resultMap屬性的引用)
  • type屬性:表示resultMap映射結果類型
  • result子節點:
    • id:一般對應數據庫中該行的主鍵id,設置此項可提高MyBatis性能
    • result:映射到JavaBean的某個“簡單類型”屬性
    • association:映射到JavaBean的某個“複雜類型”屬性,比如JavaBean類
    • collection:映射到JavaBean的某個“複雜類型”屬性,比如集合

resultType和resultMap的關聯和區別:

resultType :直接表示返回類型
resultMap :對外部resultMap的引用,它的應用場景:數據庫字段信息與對象屬性不一致或者複雜的聯合查詢,自由控制映射結果。
二者不能同時存在,本質上都是Map數據結構

MyBatis對resultMap自動映射的三個匹配級別

  • NONE:禁止自動匹配
  • PARTIAL(默認):自動匹配所有屬性,有內部嵌套(association,collection)的除外。
  • FULL:自動匹配所有。

association

  • 複雜的類型關聯,一對一
  • 內部嵌套
    • 映射一個嵌套JavaBean屬性
  • 屬性
    • property:映射數據庫列的實體對象的屬性
    • javaType:完整Java類名或者別名
    • resultMap:引用外部resultMap
  • 子元素
    • id(即使不指定ID,MyBatis也會工作,但是會導致嚴重的性能開銷,所以選擇儘量少的屬性來唯一表示結果,主鍵和聯合主鍵均可)
    • result
      • property:映射數據庫列的實體對象的屬性
      • column:數據庫列名或者別名(確保所有列名都是唯一無歧義的)
        column:數據庫列名或者別名
    <!-- 結果映射 -->
    <resultMap type="User" id="userRoleResult">
        <id property="id" column="id" />
        <result property="userCode" column="userCode" />
        <result property="userName" column="userName" />
        <result property="userRole" column="userRole" />
        <association property="role" javaType="Role" resultMap="roleResult" />
    </resultMap>
    <resultMap type="Role" id="roleResult">
        <id property="id" column="r_id" />
        <result property="roleCode" column="roleCode" />
        <result property="roleName" column="roleName" />
    </resultMap>
    <!-- 根據角色id查詢用戶列表 -->
    <select id="getUserListByRoleId" parameterType="Integer"
        resultMap="userRoleResult">
        SELECT u.*,r.`id` AS r_id,r.`roleCode`,r.`roleName` FROM
        smbms_user u,smbms_role r WHERE u.`userRole`=#{userRole} AND
        U.`userRole`=R.`id`
    </select>

collection

  • 複雜類型集合,一對多
  • 內部嵌套
    • 映射一個嵌套結果集到一個列表
  • 屬性
    • property:映射數據庫列的實體對象的屬性
    • ofType:完整Java類名或者別名(集合所包括的類型)
    • resultMap:引用外部resultMap
  • 子元素
    • id
    • result
      • property:映射數據庫列的實體對象的屬性
      • column:數據庫列名或者別名
    <!-- 根據供應商id查詢其相關信息和其下的所有訂單 -->
    <resultMap type="Provider" id="providerListResult">
        <id property="id" column="id"/>
        <result property="proCode" column="proCode"/>
        <result property="proName" column="proName"/>
        <result property="proContact" column="proContact"/>
        <result property="proPhone" column="proPhone"/>
        <collection property="billList" ofType="Bill">
            <result property="billCode" column="billCode"/> 
            <result property="productName" column="productName"/>       
            <result property="totalPrice" column="totalPrice"/>     
            <result property="isPayment" column="isPayment"/>           
        </collection>
    </resultMap>
    <select id="getProListAndBillByProId" resultMap="providerListResult" parameterType="Integer">
        SELECT p.*,b.`billCode`,b.`productName`,b.`totalPrice`,b.`isPayment`
        FROM `smbms_provider` p,`smbms_bill` b
        WHERE p.`id`=1
        AND p.`id`=b.`providerId`
    </select>

增刪改(insert、update、delete)

    <!-- 增加供應商信息 -->
    <insert id="addProvider" parameterType="Provider">
        INSERT INTO
        smbms_provider(proCode,proName,proDesc,proContact,proPhone,proAddress,
        proFax,createdBy,creationDate)
        VALUES(#{proCode},#{proName},#{proDesc},
        #{proContact},#{proPhone},#{proAddress},#{proFax},
        #{createdBy},#{creationDate})
    </insert>
    <!-- 根據供應商id刪除供應商信息 -->
    <delete id="deleteProvider" parameterType="Integer">
        delete from
        smbms_provider where id=#{id}
    </delete>
    <!-- 根據供應商ID修改供應商信息 -->
    <update id="updateProvider" parameterType="Provider">
        UPDATE smbms_provider
        SET
        proCode=#{proCode},proName=#{proName},proDesc=#{proDesc},proContact=#{proContact},
        proPhone=#{proPhone},proAddress=#{proAddress},proFax=#{proFax},modifyBy=#{modifyBy},
        modifyDate=#{modifyDate}
        WHERE id=#{id}
    </update>

對於增刪改這類數據庫更新操作,需要注意的兩點:

  1. 該類型的操作本身默認返回執行SQL影響的行數,所以DAO層的接口方法返回值一般設置爲int類型。最好不要是boolean類型。
  2. insert、update、delete元素中軍沒有resultType屬性,只有查詢操作需要對返回結果類型(resultType/resultMap)進行相應的指定。

使用@Param註解實現多參數入參()

如修改密碼的業務只需要傳入兩個參數(id和新密碼)
    <!-- 修改用戶當前密碼 -->
    <update id="updatePwd">
        UPDATE `smbms_user` SET
        userPassword=#{userPassword}
        WHERE id=#{id}
    </update>

    /**
     * 修改當前用戶密碼
     * @param id
     * @param pwd
     * @return
     */
    public int updatePwd(@Param("id")Integer id,@Param("userPassword")String pwd);

在MyBatis中參數入參,何時需要封裝成對象入參,何時又需要使用多參數入參?

  1. 超過4個以上的參數最好封裝成對象入參
  2. 對於參數固定的業務方法,最好使用多參數入參。原因是這種方法比較靈活,代碼可讀性高,可以清晰地看出接口方法中所需的參數是什麼。比如修改個人密碼,根據用戶id刪除用戶,根據用戶id查看用戶明細。

MyBatis 緩存

  • 一級緩存
    作用範圍爲session域內,當session flush或者close之後,該session中的所有cache就會被清空
  • 二級緩存
    二級緩存就是global caching,它超出session之外,可以被所有SqlSession共享,開啓它只需要在MyBatis的核心配置文件(mybatis-config.xml) settings中設置即可。
    一級緩存緩存的是SQL語句,二級緩存緩存的是結果對象。
  • 緩存配置
    • MyBatis的全局cache配置
    • 在Mapper XML文件中設置緩存,默認情況下是沒有開啓緩存的
    • 在Mapper XML文件配置支持cache後,如果需要對個別查詢進行調整,可以單獨設置cache
<!-- MyBatis的全局cache配置-->
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>
<!-- 在Mapper XML文件中設置緩存,默認情況下是沒有開啓緩存的-->
<cache eviction="FIFO" flushInterval="60000" 
        size="512" readOnly="true"/>
<!-- 在Mapper XML文件配置支持cache後,如果需要對個別查詢進行調整,可以單獨設置cache-->
<select id="selectAll" resultType="Emp" 
        useCache="true">
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章