映射器

映射器是MyBatis最強大的工具,也是我們使用MyBatis時用得做多的工具,因此熟練掌握它是十分必要的。MyBatis是針對映射器構造的SQL構建的輕量級框架,並且通過配置生成對應的JavaBean返回給調用者,而這些配置主要便是映射器。

映射器的主要元素

select元素

select元素常用配置:
這裏寫圖片描述

舉例:

<select id="findAll" resultType="user">
        select
        <include refid="column_list" />
        from user
    </select>

其中user表示User對象的別名,這裏的id標識了這條SQL,resultType定義返回值類型

使用Map傳遞參數

<resultMap type="com.example.demo.entity.User" id="UserMap">
        <id column="id" jdbcType="BIGINT" property="id" />
        <!-- 兩種方式 使用自定義的typeHandler -->
        <!-- <result column="name" property="name" javaType="string" jdbcType="VARCHAR" 
            /> -->
        <result column="name" property="name"
            typeHandler="com.example.demo.handler.MyStringTypeHandler" />
        <result column="sex" property="sex"
            typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
        <result column="age" property="age" jdbcType="INTEGER" />
    </resultMap>
    <sql id="column_list">
        id,name,age
    </sql>
    <select id="findAll" parameterMap="map" resultMap="UserMap">
        select
        <include refid="column_list" />
        from user
        where name=#{name}
    </select>

與之對應的,我們定義了一個接口方法

List<User> findAll (Map<String,String> params);
//在調用時:
Map<String,String> paramsMap=new HashMap<>;
paramsMap.put("name","wojiushiwo");
userMapper.findAll(paramsMap);//這裏未給出userMapper的定義

這種方法雖然簡單易用,但是有一個弊端:由於Map需要鍵值對應,由於業務關聯性不強,造成代碼可讀性下降。

使用註解方法傳遞參數
我們需要使用MyBatis的參數註解@Param來實現想要的功能,如

//接口如下:
List<User> findAll (@Param("name") String name);
//查詢方式:
 <sql id="column_list">
        id,name,age
    </sql>
    <select id="findAll" resultMap="UserMap">
        select
        <include refid="column_list" />
        from user
        where name=#{name}
    </select>

當我們把參數傳遞給後臺的時候,通過@Param提供的名稱MyBatis就會知道#{name}代表name參數,參數的可讀性大大提高。但是如果參數較多的情況下,這種情況就不適用了。

使用JavaBean傳遞參數
在參數過多的情況下,Mybatis允許組織一個JavaBean,通過簡單的getter和setter方法設置參數,這樣可以提高我們的可讀性。

public class User{
    private Long id;
    private String name;
    private int age;
    ...
}
//查詢方式改爲:
<select id="findAll" parameterType="user" resultMap="UserMap">
        select
        id,age,name
        from user
        where name=#{name}
    </select>
    //這裏的user是實體類的別名,在Mybatis-conf.xml文件中配置的

使用resultMap映射結果集
其實在上面我們已經使用過了resultMap,現在我們大概瞭解一下其內部構造吧。

   <resultMap type="com.example.demo.entity.User" id="UserMap">
        <id column="id" jdbcType="BIGINT" property="id" />
        <!-- 兩種方式 使用自定義的typeHandler -->
        <!-- <result column="name" property="name" javaType="string" jdbcType="VARCHAR" 
            /> -->
        <result column="name" property="name"
            typeHandler="com.example.demo.handler.MyStringTypeHandler" />
        <result column="sex" property="sex"
            typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
        <result column="age" property="age" jdbcType="INTEGER" />
    </resultMap>
  • 定義了一個唯一標識(id)爲UserMap的resultMap,用type屬性去定義它對用的是哪個JavaBean(也可以使用別名)

  • 通過id元素定義resultResultMap,這個對象代表着使用哪個屬性作爲其主鍵,result元素定義普通列的映射關係,例如,把SQL結果返回的列name和type屬性定義的JavaBean的屬性name對應

    resultMap一般用於複雜、級聯這些關聯的配置,在簡單的情況下,我們可以使用resultType通過自動映射來完成,這樣配置的工作量就會大大減少。

    insert元素

    insert元素,將對於select元素而言要簡單許多。MyBatis會在執行插入之後返回一個整數,以表示你進行操作後插入的記錄數。
    這裏寫圖片描述

舉例:

 <insert id="insert" parameterType="user">
        insert into
        user
        (name,sex,age)
        values
        (#{name},#{sex},#{age})
    </insert>

在現實中我們插入數據後往往需要獲得這個主鍵,以便於未來的操作。同樣地,MyBatis提供了實現的方法

首先我們可以使用keyProperty屬性指定哪個是主鍵字段,同時使用useGeneratedKeys屬性告訴MyBatis這個主鍵是否使用數據庫內置策略生成

<insert id="insert" parameterType="user" useGeneratedKeys="true" keyProperty="id">
        insert into
        user
        (name,sex,age)
        values
        (#{name},#{sex},#{age})
    </insert>

這樣我們傳入的user對象就無需設置id的值,MyBatis就會用數據庫的設置進行處理。這樣做的好處是在Mybatis插入的時候,它會回填JavaBean的id值。

update元素&&delete元素

與insert一樣均爲DML語句,所以處理思路很相像。update和delete元素執行後會返回一個整數,標識執行後影響的記錄條數

    <delete id="delete" parameterType="java.lang.Long">
        delete from user
        where id=#{id}
    </delete>
    <update id="update" parameterType="user">
        update user
        set
        <if test="#{name}!=null">name=#{name},</if>
        <if test="#{age}!=null">age=#{age}</if>
        where id=#{id}
    </update>

#和$

在MyBatis中,我們產出傳遞字符串,我們設置的參數#{name}在大多數情況下MyBatis會用創建預編譯的語句,然後MyBatis爲它賦值,而有的時候我們需要的是傳遞SQL語句的本身,而不是SQL所需要的參數。例如,根據某些列進行排序等

例如,爲orderColumn=“name” 表示待排序的列爲name列,那麼在Mybatis中可以這麼寫

select * from user order by ${orderColumn}

這樣MyBatis就不會幫我們轉義orderColumn,而變爲直出,而不是作爲SQL的參數進行設置。只是這樣是對SQL而言不安全

sql元素

其實在上面我們已經用到過了,

<sql id="column_list">
        id,name,age
</sql>

sql元素的意義,在於我們可以定義一穿sql語句的組成部分,其他的語句可以通過引用來使用它。例如,你有一條sql需要select幾十個字段映射到JavaBean中去,我的第二個sql也是這幾十個字段映射到JavaBean中區,顯然這些字段寫兩遍不合適,因此我們就可以使用sql元素來完成

參考文獻:
深入淺出MyBatis技術原理與實戰

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章