欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入淺出MyBatis映射器

 更新時(shí)間:2024年04月16日 09:37:32   作者:Davieyang.D.Y  
映射器是MyBatis最復(fù)雜也最重要的組件,也是基于MyBatis應(yīng)用程序開發(fā)中,本文主要介紹了深入淺出MyBatis映射器,具有一定的參考價(jià)值,感興趣的可以了解一下

映射器是MyBatis最復(fù)雜也最重要的組件,也是基于MyBatis應(yīng)用程序開發(fā)中,占工作量比較大的工作,甚至能達(dá)到8成;映射器由Mapper接口和XML或者注解組成,在映射器中可以配置參數(shù),各類SQL語(yǔ)句,存儲(chǔ)過程、緩存、級(jí)聯(lián)等復(fù)雜處理,并通過簡(jiǎn)易的映射規(guī)則將數(shù)據(jù)映射到指定的POJO或其對(duì)象上,這也是MyBatis核心運(yùn)轉(zhuǎn)邏輯

在XML和注解之間的選擇其實(shí)很明顯,其一面對(duì)復(fù)雜SQL,尤其比較長(zhǎng)的SQL,注解會(huì)顯得很無(wú)力;其二注解的可讀性較差,尤其是對(duì)于那些需要復(fù)雜配置的SQL;其三注解沒有XML上下文相互引用的優(yōu)勢(shì)

MyBatis映射器可配置元素

MyBatis映射器配置文件中可以包含以下主要元素,這些元素用于定義與數(shù)據(jù)庫(kù)交互的各種操作和相關(guān)配置:

  • <select>:代表SQL的SELECT語(yǔ)句,用于從數(shù)據(jù)庫(kù)中查詢數(shù)據(jù),可以設(shè)置屬性如id(唯一標(biāo)識(shí)該查詢)、parameterType(傳入?yún)?shù)的全限定類名或別名)、resultTyperesultMap(指定查詢結(jié)果的映射類型或引用的結(jié)果映射)??梢酝ㄟ^fetchSizetimeout等屬性控制查詢行為,以及使用flushCacheuseCache等屬性管理緩存。
  • <insert>:用于執(zhí)行INSERT語(yǔ)句向數(shù)據(jù)庫(kù)中插入數(shù)據(jù)。配置屬性包括id、parameterType(插入數(shù)據(jù)對(duì)象的類型)??梢栽O(shè)置useGeneratedKeyskeyProperty(或keyColumn)來(lái)啟用自動(dòng)增長(zhǎng)主鍵并將其值映射到指定的Java屬性上。statementType屬性可以指定語(yǔ)句類型,如STATEMENT、PREPAREDCALLABLE。
  • <update>:定義UPDATE語(yǔ)句,用于更新數(shù)據(jù)庫(kù)中的記錄。同樣具有id、parameterType屬性,指定更新操作的唯一標(biāo)識(shí)和傳入?yún)?shù)類型。可以設(shè)置flushCache屬性決定是否刷新二級(jí)緩存。
  • <delete>:定義DELETE語(yǔ)句,刪除數(shù)據(jù)庫(kù)中的數(shù)據(jù)。包含idparameterType屬性,分別表示操作標(biāo)識(shí)和刪除條件所對(duì)應(yīng)的參數(shù)類型。通常也支持flushCache屬性以控制緩存刷新。
  • <sql>:定義可重用的SQL片段,其中的SQL語(yǔ)句可以被其他元素(如<select><insert>等)通過include屬性引用。有助于減少重復(fù)編寫相同的SQL子句,提高代碼復(fù)用性。
  • <resultMap>:定義結(jié)果集映射規(guī)則,將查詢結(jié)果與Java對(duì)象的屬性進(jìn)行關(guān)聯(lián)。包括id(唯一標(biāo)識(shí)該結(jié)果映射)、type(結(jié)果對(duì)象的全限定類名或別名)??梢酝ㄟ^<id>、<result>、<association>、<collection>等子元素詳細(xì)描述如何將查詢結(jié)果的列映射到對(duì)象的屬性、嵌套對(duì)象或集合屬性上。
  • <parameterMap>:注意: 在較新版本的MyBatis中,已不再推薦使用<parameterMap>,而是直接使用parameterType屬性。老版本中用于定義輸入?yún)?shù)的映射規(guī)則,與<resultMap>類似,但主要用于處理復(fù)雜的參數(shù)結(jié)構(gòu)。新版本中通常直接使用parameterType屬性指定參數(shù)類型。
  • <cache>:定義二級(jí)緩存配置,可以設(shè)置緩存的類型、大小、超時(shí)策略、清除策略等屬性。適用于那些查詢結(jié)果相對(duì)穩(wěn)定且希望在多次請(qǐng)求之間共享結(jié)果的場(chǎng)景。
  • <cache-ref>:引用其他命名空間中定義的緩存配置,避免重復(fù)定義。通過namespace屬性指定要引用的緩存配置所在的命名空間。這些元素構(gòu)成了MyBatis映射器的基本構(gòu)建塊,通過它們可以靈活地配置各種數(shù)據(jù)庫(kù)操作,并精確地控制SQL語(yǔ)句的執(zhí)行、參數(shù)傳遞、結(jié)果映射以及緩存策略等細(xì)節(jié)。在實(shí)際使用中,可以根據(jù)業(yè)務(wù)需求選擇合適的元素組合來(lái)實(shí)現(xiàn)高效的數(shù)據(jù)庫(kù)訪問

Select元素

<select>元素在 MyBatis 映射器配置文件中用于定義 SQL SELECT 查詢語(yǔ)句及其相關(guān)屬性。以下是<select> 元素常見的屬性及其詳細(xì)解釋:

  • id:必填屬性,它和Mapper的命名空間組合起來(lái)是唯一的,形成唯一標(biāo)識(shí)符,供MyBatis調(diào)用,比如:id="getUserById"
  • parameterType:可選屬性,用于指定傳入查詢語(yǔ)句的參數(shù)類型,可以是全限定類名或也可以是類型別名,但必須是MyBatis的內(nèi)置別名或者自定義別名,當(dāng)查詢需要接受參數(shù)時(shí),使用此屬性聲明參數(shù)類型,參數(shù)可以是簡(jiǎn)單類型(如 int、String),復(fù)雜類型(如自定義 Java Bean),或者 Map 類型。若使用類型別名,需在全局配置文件或當(dāng)前映射文件中提前定義。
  • resultType:可選屬性,用于指定查詢結(jié)果的預(yù)期類型。
    格式:全限定類名或類型別名,在允許自動(dòng)匹配的情況下,結(jié)果集將通過Java Bean的規(guī)范映射,或者定義為int、double、float、map等參數(shù);當(dāng)查詢結(jié)果是一條記錄映射到單個(gè)對(duì)象時(shí),使用此屬性指定對(duì)象類型。MyBatis 會(huì)自動(dòng)將查詢結(jié)果的每一行數(shù)據(jù)映射到指定類型的對(duì)象實(shí)例。若使用類型別名,需在全局配置文件或當(dāng)前映射文件中提前定義(不能和resultMap同時(shí)使用)
  • resultMap:可選屬性,其作用是引用已定義的 <resultMap>,用于定制更復(fù)雜的查詢結(jié)果映射規(guī)則,應(yīng)與 <resultMap> 元素的id 屬性值匹配;當(dāng)查詢結(jié)果需要進(jìn)行精細(xì)的列到屬性映射,或者涉及嵌套結(jié)果集、聯(lián)合查詢、自動(dòng)關(guān)聯(lián)等復(fù)雜情況時(shí),使用此屬性替代 resultType,指定的 必須在同一映射文件中預(yù)先定義。
  • flushCache:可選屬性,其作用是控制是否在調(diào)用SQL后要求MyBatis清空之前查詢的本地緩存和二級(jí)緩存,默認(rèn)值:false(默認(rèn)情況下,查詢不會(huì)刷新緩存)
  • useCache:可選屬性,指示是否對(duì)查詢結(jié)果啟用二級(jí)緩存。默認(rèn)值:true(默認(rèn)情況下,查詢結(jié)果會(huì)被緩存)
  • timeout:可選屬性,設(shè)置查詢語(yǔ)句的超時(shí)時(shí)間(單位:秒),默認(rèn)值由JDBC驅(qū)動(dòng)或全局配置中的 defaultStatementTimeout 決定。
  • fetchSize:可選屬性,為 JDBC Statement 設(shè)置預(yù)取結(jié)果集的大小,默認(rèn)值由JDBC 驅(qū)動(dòng)決定。
  • statementType:較少使用,用來(lái)指定執(zhí)行 SQL 語(yǔ)句的方式,默認(rèn)值:PREPARED(預(yù)編譯語(yǔ)句)有3個(gè)選項(xiàng):STATEMENT:靜態(tài) SQL(非預(yù)編譯)、PREPARED:預(yù)編譯語(yǔ)句(推薦)、CALLABLE:存儲(chǔ)過程調(diào)用
  • resultOrdered:較少使用,其作用是指示 MyBatis 是否應(yīng)該保持結(jié)果集的順序與 SQL 中 ORDER BY 子句指定的順序一致。默認(rèn)值:false(默認(rèn)情況下,MyBatis 不保證結(jié)果集順序與 ORDER BY 完全一致)
  • resultSetType:較少使用其作用是指定 ResultSet 的類型(僅在使用 STATEMENT 語(yǔ)句類型時(shí)有意義)默認(rèn)值:FORWARD_ONLY(默認(rèn)情況下,使用只進(jìn)游標(biāo)),選項(xiàng)包括:FORWARD_ONLY:只進(jìn)游標(biāo)(不可回滾)、SCROLL_SENSITIVE:敏感滾動(dòng)游標(biāo)(可回滾,但可能無(wú)法看到其他事務(wù)的最新更改)、SCROLL_INSENSITIVE:不敏感滾動(dòng)游標(biāo)(可回滾,且不受其他事務(wù)更改影響)
  • resultSets::極少使用,其作用是當(dāng)查詢語(yǔ)句返回多個(gè)結(jié)果集或光標(biāo)時(shí),使用此屬性指定結(jié)果集的名稱或索引。

總結(jié)起來(lái),<select>元素的主要屬性用于定義查詢語(yǔ)句的身份標(biāo)識(shí)、輸入?yún)?shù)類型、輸出結(jié)果映射方式、緩存策略、查詢超時(shí)、預(yù)取大小等執(zhí)行特性。這些屬性幫助開發(fā)者精細(xì)控制查詢行為,確保與數(shù)據(jù)庫(kù)交互的高效性和靈活性。在實(shí)際應(yīng)用中,最常用的屬性通常是idparameterType、resultType或 resultMapflushCache和 useCache其他屬性在特定場(chǎng)景下可能會(huì)發(fā)揮作用,但并不常用。

Select元素實(shí)例 單個(gè)參數(shù)

    <select id="countUserByFirstName" parameterType="string" resultType="int">
        select count(*) total from t_user where user_name like concat ('%',#{firstName, jdbcType=VARCHAR, javaType=String},'%')
    </select>

SQL很容易懂,里邊的元素可以參考對(duì)應(yīng)上邊每一項(xiàng)的解釋理解,有了SQL,就需要對(duì)應(yīng)的Mapper接口和方法(也就是Dao Data Access Object)public Integer countUserByFirstName(String firstName)

在MyBatis的配置文件的settings元素中,有autoMappingBehavior和mapUnderscoreToCamelCase兩個(gè)可配置的選項(xiàng),他們是控制自動(dòng)映射和駝峰映射的開關(guān),一般來(lái)說自動(dòng)映射會(huì)用的多一些,這樣可以使用SQL的別名機(jī)制,更加靈活,而駝峰映射要求比較嚴(yán)格;autoMappingBehavior配置項(xiàng)有3個(gè)選擇,NONE表示不自動(dòng)映射,PARTIAL是默認(rèn)值,表示只對(duì)沒有嵌套的結(jié)果集自動(dòng)映射,F(xiàn)ULL表示對(duì)所有的結(jié)果集自動(dòng)映射包括嵌套結(jié)果集,通常默認(rèn)即可

假設(shè)我們有如下這么一個(gè)POJO

package com.ssm.pojo;
import org.apache.ibatis.type.Alias;
@Alias("role")
public class Role{
	private int id;
	private String roleName;
	private String note;
	/**  setters and getters */
}

在這個(gè)POJO里有三個(gè)屬性id、roleName、note,如果在Mapper里編寫SQL列名和屬性名保持一致,它就會(huì)形成自動(dòng)映射,例如

    <select id="getRole" parameterType="int" resultType="role">
        select id, role_name as roleName, note from t_role where id = #{id}
    </select>

列名role_name被別名roleName代替了,和POJO上的屬性名保持一致,如此MyBatis就能將查詢結(jié)果集和POJO的屬性一一對(duì)應(yīng),自動(dòng)完成映射無(wú)需再進(jìn)行任何配置

如果嚴(yán)格按照駝峰命名法,比如數(shù)據(jù)庫(kù)字段為role_name,POJO屬性名為roleName,數(shù)據(jù)庫(kù)字段名為user_name,POJO屬性名為userName,那么只要在配置項(xiàng)把mapUnderscoreToCamelCase設(shè)置為true即可,如果這樣,那么SQL就可以寫成

select id, role_name, note from t_role where id = #{id}

MyBatis會(huì)嚴(yán)格按照駝峰命名的方式自動(dòng)映射,只是這樣要求數(shù)據(jù)字段和POJO的屬性名嚴(yán)格對(duì)應(yīng)

自動(dòng)映射和駝峰映射都建立在SQL列名和POJO屬性名的映射關(guān)系上,在實(shí)際使用中會(huì)更復(fù)雜,比如可能有些字段有主表和從表關(guān)聯(lián)的級(jí)聯(lián)關(guān)系,又比如typeHandler的轉(zhuǎn)換規(guī)則復(fù)雜,此時(shí)resultType元素?zé)o法滿足這些需求需要更強(qiáng)大的映射規(guī)則需要考慮使用resultMap等等

Select元素實(shí)例 使用Map傳遞多個(gè)參數(shù)

假設(shè)有這樣一個(gè)Mapper接口定義,它通過鍵值對(duì)傳遞多個(gè)參數(shù)

public List<Role> findRolesByMap(Map<String, Object>parameterMap);

此時(shí)傳遞給映射器的一個(gè)Map對(duì)象,使用它在SQL中設(shè)置對(duì)應(yīng)的參數(shù),如下所示

    <select id="findRoleByMap" parameterType="map" resultType="role">
        select id, role_name as roleName, note from t_role 
        where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note},'%')
    </select>

這里使用兩個(gè)數(shù)據(jù)庫(kù)字段進(jìn)行了一個(gè)模糊查詢,傳參方式是使用map,執(zhí)行代碼如下所示

RoleDao roleDao = sqlSession.getMapper(RoleDao.class);
Map<String, Object>parameterMap = new HashMap<>();
parameterMap.put("roleName", "1");
parameterMap.put("note","1");
List<Role> roleList = roleDao.findRolesByMap(parameterMap);

嚴(yán)格來(lái)說Map幾乎適用于所有場(chǎng)景,但其可讀性比較差,且不能限定其傳遞的數(shù)據(jù)類型

Select元素實(shí)例 使用注解傳遞多個(gè)參數(shù)

MyBatis提供了@Param(org.apache.ibatis.annotations.Param),可以通過它定義映射器的參數(shù)名稱,如下代碼所示

public List<Role> findRolesByAnnotation(@Param("roleName") String roleName, @Param("note") String note);

Mapper文件如下所示

    <select id="findRolesByAnnotation" "resultType="role">
        select id, role_name as roleName, note from t_role 
        where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note},'%')
    </select>

Select元素實(shí)例 使用JavaBean傳遞多個(gè)參數(shù)

先定義一個(gè)POJO

package com.ssm.pojo.parameter;

public class RoleParams{
	private String roleName;
	private String note;
	/** setter and getter */
}

把Mapper接口定義為

public List<Role> findRolesByBean(RoleParams roleParam);

Mapper文件如下所示

    <select id="findRolesByBean" "resultType="role" parameterType="com.ssm.pojo.parameter.RoleParams">
        select id, role_name as roleName, note from t_role 
        where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note},'%')
    </select>

執(zhí)行代碼如下

sqlSession = SqlSessionFactoryUtils.openSqlSession();
RoleDao roleDao = sqlSession.getMapper(RoleDao.class);
RoleParams roleParams = new RoleParams();
roleParams.setNote("1");
roleParams.setRoleName("1");
List<Role>roleList = roleDao.findRolesByBean(roleParams);

在某些場(chǎng)景下也會(huì)混合使用,例如通過角色名稱和備注查詢角色,同時(shí)需要支持分頁(yè)

分頁(yè)的POJO如下定義

package com.ssm.pojo.parameter;
public class PageParams{
	private int start;
	private int limit;
	/** setters and getters */
}

Mapper接口如下

public List<Role> findByMix(@Param("params") RoleParams roleParams, @Param("page") PageParams PageParam);

Mapper文件如下寫法

    <select id="findByMix" "resultType="role">
        select id, role_name as roleName, note from t_role 
        where role_name like concat('%', #{params.roleName}, '%') and note like concat('%', #{params.note},'%')
        limit #{page.start}, #{page.limit}
    </select>

MyBatis對(duì)params和page這類JavaBean參數(shù)提供EL(中間語(yǔ)言)支持,為編程帶來(lái)了很多便利

結(jié)果集映射resultMap

自動(dòng)映射和駝峰映射規(guī)則比較簡(jiǎn)單,無(wú)法定義更多的屬性和滿足復(fù)雜的場(chǎng)景,例如枚舉需要typeHandler,還有數(shù)據(jù)級(jí)聯(lián)等等,因此select元素提供了resultMap屬性,用于指定具體的resultMap作為映射規(guī)則,如下定義所示

<result Map id="roleMap" type="role">
	<id property="id" column="id"/>
	<result property="roleName" column="role_name"/>
	<result property="note" column="ntoe"/>
</resultMap>
<select id="getRoleUserResultMap" parameterType="int" resultMap="roleMap">
	select id, role_name, note from t_role where id = #{id}
</select>
    <!-- 定義結(jié)果映射,用于將數(shù)據(jù)庫(kù)中的數(shù)據(jù)映射成Role對(duì)象 -->
    <resultMap id="userMap" type="com.ssm.pojo.User">
        <id property="userid" column="userid"/> <!-- 主鍵映射 -->
        <result property="username" column="username"/> <!-- 角色名映射 -->
        <result property="password" column="password"/> <!-- 備注映射 -->
        <result property="sex" column="sex"/>
        <result property="phone" column="phone"/>
        <result property="email" column="email"/>
        <result property="phonenumber" column="phonenumber"/>
        <result property="comment" column="comment"/>
    </resultMap>
    <!-- 定義結(jié)果映射,用于將數(shù)據(jù)庫(kù)中的數(shù)據(jù)映射成Role對(duì)象 -->
    <resultMap id="roleMap" type="com.ssm.pojo.Role">
        <id property="id" column="id"/> <!-- 主鍵映射 -->
        <result property="roleName" column="roleName"/> <!-- 角色名映射 -->
        <result property="note" column="note" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/> <!-- 備注映射 -->
    </resultMap>

分頁(yè)參數(shù)RowBounds

MyBatis不僅支持分頁(yè),還內(nèi)置了一個(gè)專門處理分頁(yè)的類RowBounds,如下代碼所示

/**
 * RowBounds類用于設(shè)置SQL查詢的偏移量和限制結(jié)果集的大小。
 */
package org.apache.ibatis.session;

public class RowBounds {
    // 無(wú)偏移量,無(wú)限制的行數(shù)
    public static final int NO_ROW_OFFSET = 0;
    // 最大整數(shù)2147483647
    public static final int NO_ROW_LIMIT = Integer.MAX_VALUE;
    // 默認(rèn)的RowBounds實(shí)例,無(wú)偏移,無(wú)限制
    public static final RowBounds DEFAULT = new RowBounds();
    private final int offset; // 偏移量,從第幾行開始
    private final int limit; // 限制返回的行數(shù)

    /**
     * 構(gòu)造函數(shù),默認(rèn)偏移量為0,限制的行數(shù)為最大整數(shù)值。
     */
    public RowBounds() {
        this.offset = 0;
        this.limit = Integer.MAX_VALUE;
    }

    /**
     * 構(gòu)造函數(shù),設(shè)置自定義的偏移量和限制的行數(shù)。
     * 
     * @param offset 查詢結(jié)果的偏移量,即從第幾行開始。
     * @param limit 返回結(jié)果集的最大行數(shù)。
     */
    public RowBounds(int offset, int limit) {
        this.offset = offset;
        this.limit = limit;
    }

    /**
     * 獲取偏移量。
     * 
     * @return 偏移量,從第幾行開始。
     */
    public int getOffset() {
        return this.offset;
    }

    /**
     * 獲取限制的行數(shù)。
     * 
     * @return 返回結(jié)果集的最大行數(shù)。
     */
    public int getLimit() {
        return this.limit;
    }
}

Mapper接口定義如下

public List<Role> findByRowBounds(@Param("roleName") String rolename, @Param("note") String note, RowBounds rowBounds);

Mapper映射文件如下

<select id="findByRowBounds" resultType="role">
	select id, role_name as roleName, note from t_role 
	where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note}, '%')
</select>

映射代碼中沒有任何關(guān)于RowBounds參數(shù)的信息,MyBatis自身會(huì)自動(dòng)識(shí)別和啟用它

執(zhí)行代碼如下

Logger log = Logger.getLogger(Main.class);
SqlSession sqlsession = null;
try{
	sqlsession = SqlSessionFacotryUtils.openSqlSession();
	RoleDao roleDao = sqlSession.getMapper(RoleDao.class);
	List<Role> roleList = roleDao.findByRowBounds("role", "note", new RownBounds(0,20));
	log.info(roleList.size());
}finally{
	if(sqlSession!=null){
		sqlSession.close();
	}
}	

RowBounds分頁(yè)一般來(lái)說只適合做少量數(shù)據(jù)的分頁(yè),其原理是在執(zhí)行SQL的查詢后,根據(jù)偏移量和限制條數(shù)返回結(jié)果,因此大量的數(shù)據(jù)查詢性能會(huì)比較差

insert元素

在MyBatis框架中,<insert>標(biāo)簽用于定義SQL插入語(yǔ)句。以下是其常用的屬性及其說明:

  • id:作為命名空間內(nèi)的唯一標(biāo)識(shí)符,與Mapper接口中的方法名相對(duì)應(yīng),用于MyBatis在執(zhí)行時(shí)找到對(duì)應(yīng)的SQL語(yǔ)句。<insert id="insertUser" ...>,在同一個(gè)Mapper的XML文件中,id屬性值必須唯一,否則MyBatis在解析時(shí)會(huì)拋出異常。
  • parameterType:指定傳入SQL語(yǔ)句的參數(shù)類型,通常是一個(gè)Java類的全限定名(如包名加類名)或別名。支持基本數(shù)據(jù)類型、JavaBean對(duì)象、Map等復(fù)雜數(shù)據(jù)類型。<insert parameterType="com.example.User" ...>,MyBatis可以根據(jù)參數(shù)對(duì)象的屬性名自動(dòng)映射到SQL語(yǔ)句中的占位符(如${}或#{}),無(wú)需手動(dòng)指定每一個(gè)參數(shù)。
  • useGeneratedKeys:表示是否啟用JDBC的getGeneratedKeys方法來(lái)獲取數(shù)據(jù)庫(kù)自動(dòng)生成的主鍵。默認(rèn)值為false。<insert useGeneratedKeys="true" ...>,當(dāng)數(shù)據(jù)庫(kù)表有自增主鍵或其他自動(dòng)生成的主鍵時(shí),設(shè)置為true可以讓MyBatis自動(dòng)獲取并返回生成的主鍵值。這需要數(shù)據(jù)庫(kù)驅(qū)動(dòng)和數(shù)據(jù)庫(kù)本身支持該功能。
  • keyProperty:當(dāng)useGeneratedKeys="true"時(shí),此屬性指定插入后生成的主鍵值應(yīng)該賦給傳入?yún)?shù)對(duì)象(parameterType指定的對(duì)象)的哪個(gè)屬性。如果主鍵是復(fù)合主鍵,可以使用逗號(hào)分隔多個(gè)屬性名。<insert keyProperty="id" ...> 或 <insert keyProperty="primaryKey1, primaryKey2" ...>,只有當(dāng)useGeneratedKeys="true"且數(shù)據(jù)庫(kù)支持時(shí),keyProperty才生效。否則,即使指定了該屬性,也不會(huì)有任何效果。
  • statementType:指定語(yǔ)句的執(zhí)行類型??蛇x值包括STATEMENT、PREPARED(默認(rèn))和CALLABLE。分別對(duì)應(yīng)使用JDBC的Statement、PreparedStatement和CallableStatement。<insert statementType="PREPARED" ...>,通常情況下,保持默認(rèn)的PREPARED即可,因?yàn)樗芊乐筍QL注入攻擊,并允許預(yù)編譯SQL語(yǔ)句提高性能。除非有特定需求,否則不需要更改此屬性。
  • flushCache:控制是否在執(zhí)行插入操作后刷新MyBatis的一級(jí)緩存(本地Session緩存)。默認(rèn)值為true,即每次插入后清空緩存。<insert flushCache="false" ...>,若希望在插入后保留緩存以優(yōu)化后續(xù)查詢,可以設(shè)置為false。但請(qǐng)注意,這可能會(huì)影響數(shù)據(jù)的一致性,特別是多事務(wù)并發(fā)環(huán)境下,需要謹(jǐn)慎使用。
  • timeout:設(shè)置執(zhí)行語(yǔ)句的超時(shí)時(shí)間(單位:秒)。超過這個(gè)時(shí)間仍未得到數(shù)據(jù)庫(kù)響應(yīng)時(shí),MyBatis將拋出異常。<insert timeout="30" ...>注意: 根據(jù)數(shù)據(jù)庫(kù)操作的實(shí)際耗時(shí)和系統(tǒng)對(duì)響應(yīng)時(shí)間的要求來(lái)合理設(shè)置。過短可能導(dǎo)致正常操作因超時(shí)而失敗,過長(zhǎng)則可能導(dǎo)致應(yīng)用響應(yīng)緩慢。
  • keyColumn:僅對(duì)于insert和update有用,通過生成的鍵值設(shè)置表中的列名,這些設(shè)置僅在某些數(shù)據(jù)庫(kù)如PG中是必須的,當(dāng)主鍵列不是表中的第一列時(shí)需要設(shè)置,如果是復(fù)合主鍵,則需要再把沒一個(gè)名稱用逗號(hào)隔開
  • 其他:parameterMap、databaseId

insert元素實(shí)例自增主鍵場(chǎng)景

    <!-- 插入一個(gè)新的Role記錄 -->
    <insert id="insertRole" parameterType="com.ssm.pojo.Role" databaseId="mysql" >
        INSERT INTO t_role(roleName, note) VALUES (#{roleName}, #{note})
    </insert>

這個(gè)語(yǔ)句非常簡(jiǎn)單,因?yàn)楸淼膇d只自增主鍵,因此在插入數(shù)據(jù)的時(shí)候并沒有為該字段做任何事,數(shù)據(jù)庫(kù)會(huì)自動(dòng)完成,但實(shí)際開發(fā)過程中往往插入一條記錄,需要根據(jù)當(dāng)前表的主鍵值處理關(guān)聯(lián)表,MyBatis中可以通過getGeneratedKeys方法獲得數(shù)據(jù)庫(kù)生成的主鍵,默認(rèn)它是false狀態(tài),也就是不會(huì)返回主鍵值,當(dāng)打開了這個(gè)開關(guān)后,還需要配置其屬性keyPropertykeyColumn,從而告訴系統(tǒng)把生成的主鍵放入POJO的對(duì)應(yīng)屬性中,如果存在多個(gè)主鍵,就要用逗號(hào)將他們分隔

    <!-- 
    插入一個(gè)新的Role記錄
    
    參數(shù):
    - parameterType: 指定插入操作時(shí)使用的參數(shù)類型,這里是 com.ssm.pojo.Role,表示插入的角色對(duì)象。
    - databaseId: 指定該SQL語(yǔ)句適用于哪個(gè)數(shù)據(jù)庫(kù),這里是 mysql。
    - useGeneratedKeys: 指定是否使用數(shù)據(jù)庫(kù)自動(dòng)生成的鍵值。如果為 true,則表示使用自動(dòng)生成的鍵值。
    - keyProperty: 指定生成的鍵值應(yīng)該被設(shè)置到對(duì)象的哪個(gè)屬性上,這里是 id。
    
    返回值: 無(wú)返回值,僅執(zhí)行插入操作。
     -->
    <insert id="insertRole" parameterType="com.ssm.pojo.Role" databaseId="mysql" useGeneratedKeys="true" keyProperty="id" >
        INSERT INTO t_role(roleName, note) VALUES (#{roleName}, #{note})
    </insert>

如此,將useGeneratedKeys配置為true表示采用JDBC的Statement對(duì)象的getGeneratedKeys方法返回主鍵,而keyProperty代表用哪個(gè)POJO的屬性匹配這個(gè)主鍵,這個(gè)例子里是id,說明它會(huì)用數(shù)據(jù)生成的主鍵賦值給這個(gè)POJO的屬性id

insert元素實(shí)例自定義主鍵場(chǎng)景

有時(shí)候主鍵未必是自增的,而是依賴于某些規(guī)則,例如取消角色表的id自增規(guī)則,將其規(guī)則改為當(dāng)角色表記錄為空時(shí)id設(shè)置為1,當(dāng)角色表記錄不為空時(shí),id設(shè)置為當(dāng)前id加3,對(duì)于這樣的特殊規(guī)則主鍵的場(chǎng)景,MyBatis也提供了支持,它主要依賴selectKey元素,允許自定義鍵值生成規(guī)則

    <!-- 
     插入一個(gè)新的Role記錄
     參數(shù):
     - parameterType: 指定插入操作時(shí)使用的參數(shù)類型,這里是com.ssm.pojo.Role,代表插入的角色對(duì)象。
     - databaseId: 指定此SQL適用于哪個(gè)數(shù)據(jù)庫(kù),這里是mysql。
     - useGeneratedKeys: 指定是否使用數(shù)據(jù)庫(kù)生成的主鍵值。如果為true,MyBatis會(huì)自動(dòng)獲取生成的主鍵值并設(shè)置到對(duì)象中。
     - keyProperty: 指定哪個(gè)屬性會(huì)接收生成的主鍵值,這里是id。
     返回值: 插入操作成功后,返回值為插入的記錄的主鍵ID。
    -->
    <insert id="insertRole" parameterType="com.ssm.pojo.Role" databaseId="mysql" useGeneratedKeys="true" keyProperty="id" >
        <!-- 
         使用selectKey標(biāo)簽來(lái)動(dòng)態(tài)生成主鍵ID。在插入新記錄之前執(zhí)行,通過查詢當(dāng)前角色表中最大ID值,若不存在則默認(rèn)為1,若存在則在最大ID上加3,以保證ID的唯一性。
        -->
        <selectKey keyProperty="id" resultType="int" order="BEFORE">
            select if (max(id) = null, 1, max(id) + 3) from t_role
        </selectKey>
        <!-- 插入新的Role記錄,#{id}, #{roleName}, #{note}分別代表角色的ID,角色名和備注信息。這些值會(huì)從傳入的Role對(duì)象中獲取。 -->
        INSERT INTO t_role(id, roleName, note) VALUES (#{id}, #{roleName}, #{note})
    </insert>

其他的很容易看明白,唯獨(dú)這個(gè)order,設(shè)置為BEFORE,說明它將于當(dāng)前定義的SQL前執(zhí)行,也就是它會(huì)在插入數(shù)據(jù)前生成主鍵的SQL,如果還有一些需要在SQL執(zhí)行后的動(dòng)作,例如插入語(yǔ)句內(nèi)部可能有嵌入索引調(diào)用,這樣可以把它設(shè)置為AFTER,就會(huì)在執(zhí)行插入后再完成任務(wù)

update元素和delete元素

   <!-- 更新Role的信息 -->
    <!-- 
    函數(shù)級(jí)別注釋:該標(biāo)簽用于更新Role表中的信息。
    參數(shù):
    - roleName: 角色名,類型為String,用于更新角色的名稱。
    - note: 備注信息,類型為String,用于更新角色的備注。
    - id: 角色I(xiàn)D,類型為Integer,用于指定要更新的角色。
    返回值:無(wú)返回值。
     -->
    <update id="updateRole" parameterType="com.ssm.pojo.Role">
        UPDATE t_role SET roleName = #{roleName}, note = #{note} WHERE id = #{id}
    </update>

    <!-- 
    函數(shù)級(jí)別塊注釋:
    根據(jù)提供的ID刪除數(shù)據(jù)庫(kù)中特定的Role記錄。
    
    參數(shù):
    id - 需要?jiǎng)h除的Role記錄的ID,類型為int。
    
    返回值:
    無(wú)返回值。
     -->
    <delete id="deleteRole" parameterType="int">
        DELETE FROM t_role WHERE id = #{id}
    </delete>

sql元素

在實(shí)際開發(fā)過程中,往往很多表的列都非常多,在編寫代碼的時(shí)候,重復(fù)寫列名是個(gè)很枯燥的事情,即便編譯器提供了很多方法,但還是很麻煩,MyBatis提供了sql元素,簡(jiǎn)化了該場(chǎng)景下的編碼工作

    <!-- 定義查詢角色信息時(shí)需要返回的列名 -->
    <sql id = "roleCols">
        id, roleName, note
    </sql>


    <!-- 根據(jù)ID查詢Role信息,返回Role對(duì)象。該查詢針對(duì)Oracle數(shù)據(jù)庫(kù)。 -->
    <select id="getRoleById" parameterType="int" resultMap="roleMap" databaseId="oracle">
        SELECT <include refid="roleCols"/>FROM t_role WHERE id = #{id}
    </select>

    <!-- 插入新的Role信息。在插入前,通過selectKey為新Role生成一個(gè)唯一的ID。 -->
    <insert id="insertRole" parameterType="com.ssm.pojo.Role">
        <selectKey keyProperty="id" resultType="int" order="BEFORE" statementType="PREPARED">
            select if (max(id) = null, 1, max(id)+3) from t_role
        </selectKey>
        insert into t_role(<include refid="roleCols"/>) values(#{id}, #{roleName}, #{note})
    </insert>

sql元素還支持變量傳遞

    <!-- 定義一個(gè)SQL片段,用于查詢角色表中的id、roleName和note列 -->
    <!-- 通過傳入的別名(alias)動(dòng)態(tài)拼接SQL語(yǔ)句中的表名前綴 -->
    <sql id ="roleCols2">
        ${alias}.id, ${alias}.roleName, ${alias}.note}
    </sql>


    <!-- 根據(jù)ID查詢Role信息,返回Role對(duì)象。該查詢針對(duì)Oracle數(shù)據(jù)庫(kù)。 -->
    <select id="getRoleById" parameterType="int" resultMap="roleMap" databaseId="oracle">
        SELECT <include refid="roleCols">
        <property name="alias" value="r"/>
    </include>
        FROM t_role r WHERE id = #{id}
    </select>

include元素中定義了一個(gè)“alias”的變量,其值是SQL中表t_role的別名“r”,sql元素可以通過EL引用這個(gè)變量

到此這篇關(guān)于深入淺出MyBatis映射器的文章就介紹到這了,更多相關(guān)MyBatis映射器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

最新評(píng)論