MyBatis?SQL映射文件的作用和結(jié)構(gòu)詳解
MyBatis SQL 映射文件定義了 SQL 語(yǔ)句以及如何將 SQL 語(yǔ)句的參數(shù)和結(jié)果映射到 Java 對(duì)象。
一、 作用 (Purpose)
MyBatis SQL 映射文件(通常命名為 XXXMapper.xml
)的主要作用是:
- 定義 SQL 語(yǔ)句: 在 XML 映射文件中編寫 SQL 語(yǔ)句,包括 SELECT, INSERT, UPDATE, DELETE 等各種類型的 SQL 語(yǔ)句。
- 參數(shù)映射 (Parameter Mapping): 定義如何將 Java 方法的參數(shù)映射到 SQL 語(yǔ)句中的參數(shù)。 可以使用
#
和$
占位符,并指定參數(shù)類型、jdbcType 等信息。 - 結(jié)果映射 (Result Mapping): 定義如何將 SQL 語(yǔ)句的查詢結(jié)果映射到 Java 對(duì)象。 可以使用
resultType
或resultMap
,并定義一對(duì)一、一對(duì)多等關(guān)系映射。 - 動(dòng)態(tài) SQL (Dynamic SQL): 使用 MyBatis 提供的動(dòng)態(tài) SQL 元素 (例如
<if>
,<choose>
,<when>
,<otherwise>
,<where>
,<set>
,<foreach>
),根據(jù)不同的條件動(dòng)態(tài)生成 SQL 語(yǔ)句。 - 緩存配置 (Cache Configuration): 配置 SQL 語(yǔ)句的緩存行為,提高查詢性能。
- 與 Mapper 接口關(guān)聯(lián): 將 SQL 映射文件與 Java Mapper 接口關(guān)聯(lián)起來(lái),使得可以通過(guò)調(diào)用 Mapper 接口的方法來(lái)執(zhí)行 SQL 語(yǔ)句。
總而言之,SQL 映射文件是 MyBatis 將 SQL 語(yǔ)句與 Java 代碼解耦的關(guān)鍵,它允許開(kāi)發(fā)者專注于 SQL 語(yǔ)句的編寫和優(yōu)化,而無(wú)需關(guān)心 JDBC 的細(xì)節(jié)。
二、 結(jié)構(gòu) (Structure)
MyBatis SQL 映射文件的根元素是 <mapper>
,它包含多個(gè)子元素,用于定義 SQL 語(yǔ)句、參數(shù)映射、結(jié)果映射等信息。
以下是一個(gè)典型的 SQL 映射文件結(jié)構(gòu):
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.UserMapper"> <!-- 1. cache (緩存) --> <cache eviction="LRU" flushInterval="60000" readOnly="true" size="512"/> <!-- 2. resultMap (結(jié)果映射) --> <resultMap id="UserResultMap" type="com.example.model.User"> <id property="id" column="id"/> <result property="username" column="username"/> <result property="email" column="email"/> <!-- association (一對(duì)一) --> <association property="address" column="address_id" javaType="com.example.model.Address" select="com.example.mapper.AddressMapper.selectAddressById"/> <!-- collection (一對(duì)多) --> <collection property="orders" column="id" ofType="com.example.model.Order" select="com.example.mapper.OrderMapper.selectOrdersByUserId"/> </resultMap> <!-- 3. select (查詢) --> <select id="selectUserById" parameterType="int" resultMap="UserResultMap" useCache="true"> SELECT * FROM user WHERE id = #{id} </select> <!-- 4. insert (插入) --> <insert id="insertUser" parameterType="com.example.model.User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user (username, email) VALUES (#{username}, #{email}) </insert> <!-- 5. update (更新) --> <update id="updateUser" parameterType="com.example.model.User"> UPDATE user SET username = #{username}, email = #{email} WHERE id = #{id} </update> <!-- 6. delete (刪除) --> <delete id="deleteUserById" parameterType="int"> DELETE FROM user WHERE id = #{id} </delete> <!-- 7. sql (SQL 片段) --> <sql id="userColumns"> id, username, email </sql> </mapper>
三、各個(gè)元素詳解
<mapper>
(根元素):
namespace
屬性:指定 Mapper 接口的完全限定名。 MyBatis 會(huì)根據(jù)這個(gè)命名空間來(lái)查找 SQL 映射文件,并將 SQL 語(yǔ)句與 Mapper 接口的方法關(guān)聯(lián)起來(lái)。 這是將 SQL 映射文件與 Java 代碼關(guān)聯(lián)的關(guān)鍵。- 例如:
<mapper namespace="com.example.mapper.UserMapper">
對(duì)應(yīng)著UserMapper.java
接口文件
<cache>
(緩存):
- 配置該 Mapper 對(duì)應(yīng)的二級(jí)緩存。
eviction
屬性:指定緩存的淘汰策略 (LRU, FIFO, SOFT, WEAK)。flushInterval
屬性:指定緩存的刷新間隔 (毫秒)。size
屬性:指定緩存的最大容量。readOnly
屬性:指定緩存是否只讀 (true
或false
)。<cache type="org.mybatis.cache.impl.PerpetualCache"/>
使用自定義緩存
<cache-ref>
(緩存引用):
- 引用其他 Mapper 的緩存配置。
namespace
屬性:指定要引用的 Mapper 的命名空間。
<resultMap>
(結(jié)果映射):
作用: 定義如何將 SQL 語(yǔ)句的查詢結(jié)果映射到 Java 對(duì)象。
id
屬性:指定resultMap
的唯一標(biāo)識(shí)。type
屬性:指定要映射的 Java 類型。
子元素:
<id>
:定義主鍵映射。property
屬性:指定 Java 對(duì)象的屬性名。column
屬性:指定數(shù)據(jù)庫(kù)表中的列名。
<result>
:定義普通屬性映射。property
屬性:指定 Java 對(duì)象的屬性名。column
屬性:指定數(shù)據(jù)庫(kù)表中的列名。
<association>
:定義一對(duì)一關(guān)系映射。property
屬性:指定 Java 對(duì)象的屬性名。column
屬性:指定數(shù)據(jù)庫(kù)表中的列名。javaType
屬性:指定關(guān)聯(lián)對(duì)象的 Java 類型。select
屬性:指定用于查詢關(guān)聯(lián)對(duì)象的 SQL 語(yǔ)句的 ID。
<collection>
:定義一對(duì)多關(guān)系映射。property
屬性:指定 Java 對(duì)象的屬性名。column
屬性:指定數(shù)據(jù)庫(kù)表中的列名。ofType
屬性:指定集合中元素的 Java 類型。select
屬性:指定用于查詢集合元素的 SQL 語(yǔ)句的 ID。
<discriminator>
:定義鑒別器,根據(jù)不同的條件選擇不同的映射規(guī)則。column
屬性:指定用于鑒別的列名。<case>
元素:定義不同的映射規(guī)則。value
屬性:指定鑒別值。resultMap
屬性:指定要使用的resultMap
。
示例:
<resultMap id="UserResultMap" type="com.example.model.User"> <id property="id" column="id"/> <result property="username" column="username"/> <result property="email" column="email"/> <association property="address" column="address_id" javaType="com.example.model.Address" select="com.example.mapper.AddressMapper.selectAddressById"/> <collection property="orders" column="id" ofType="com.example.model.Order" select="com.example.mapper.OrderMapper.selectOrdersByUserId"/> </resultMap>
<select>
(查詢):
- 作用: 定義 SELECT 語(yǔ)句,用于查詢數(shù)據(jù)。
id
屬性:指定 SQL 語(yǔ)句的唯一標(biāo)識(shí)。 與 Mapper 接口中的方法名對(duì)應(yīng)。parameterType
屬性:指定參數(shù)類型。resultType
屬性:指定結(jié)果類型(如果使用簡(jiǎn)單類型映射)。resultMap
屬性:指定結(jié)果映射 (如果使用<resultMap>
元素)。parameterMap
屬性: (已經(jīng)過(guò)時(shí), 不建議使用)flushCache
屬性: 如果設(shè)置為true
,則每次執(zhí)行該語(yǔ)句都會(huì)刷新緩存。useCache
屬性:如果設(shè)置為true
,則該語(yǔ)句的結(jié)果會(huì)被緩存。timeout
屬性:設(shè)置超時(shí)時(shí)間(秒)。fetchSize
屬性:設(shè)置每次從數(shù)據(jù)庫(kù)獲取的記錄數(shù)量。statementType
屬性: 指Statement類型, 可選值為 STATEMENT、PREPARED 和 CALLABLE。- STATEMENT, 默認(rèn)值, 使用Statement
- PREPARED, 使用PreparedStatement, 可以防止SQL注入, 性能更好。
- CALLABLE, 主要用于執(zhí)行存儲(chǔ)過(guò)程
示例:
<select id="selectUserById" parameterType="int" resultMap="UserResultMap" useCache="true"> SELECT * FROM user WHERE id = #{id} </select>
<insert>
(插入):
- 作用: 定義 INSERT 語(yǔ)句,用于插入數(shù)據(jù)。
id
屬性:指定 SQL 語(yǔ)句的唯一標(biāo)識(shí)。parameterType
屬性:指定參數(shù)類型。useGeneratedKeys
屬性:是否允許 MyBatis 使用 JDBC 的getGeneratedKeys
方法獲取自增主鍵值。keyProperty
屬性:指定 Java 對(duì)象的哪個(gè)屬性用于接收自增主鍵值。keyColumn
屬性:指定數(shù)據(jù)庫(kù)表的主鍵列名.
示例:
<insert id="insertUser" parameterType="com.example.model.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> INSERT INTO user (username, email) VALUES (#{username}, #{email}) </insert>
<update>
(更新):
- 作用: 定義 UPDATE 語(yǔ)句,用于更新數(shù)據(jù)。
id
屬性:指定 SQL 語(yǔ)句的唯一標(biāo)識(shí)。parameterType
屬性:指定參數(shù)類型。
示例:
<update id="updateUser" parameterType="com.example.model.User"> UPDATE user SET username = #{username}, email = #{email} WHERE id = #{id} </update>
<delete>
(刪除):
- 作用: 定義 DELETE 語(yǔ)句,用于刪除數(shù)據(jù)。
id
屬性:指定 SQL 語(yǔ)句的唯一標(biāo)識(shí)。parameterType
屬性:指定參數(shù)類型。
示例:
<delete id="deleteUserById" parameterType="int"> DELETE FROM user WHERE id = #{id} </delete>
<sql>
(SQL 片段):
- 作用: 定義可以重復(fù)使用的 SQL 代碼片段。
id
屬性:指定 SQL 片段的唯一標(biāo)識(shí)。
示例:
<sql id="userColumns"> id, username, email </sql>
四、動(dòng)態(tài) SQL 元素 (Dynamic SQL Elements)
MyBatis 提供了以下動(dòng)態(tài) SQL 元素,可以根據(jù)不同的條件動(dòng)態(tài)生成 SQL 語(yǔ)句:
<if>
:
- 作用: 根據(jù)條件判斷是否包含某段 SQL 代碼。
test
屬性:指定判斷條件,使用 OGNL 表達(dá)式。
示例:
<select id="selectUserByCondition" parameterType="com.example.model.User" resultMap="UserResultMap"> SELECT * FROM user <where> <if test="username != null and username != ''"> AND username = #{username} </if> <if test="email != null and email != ''"> AND email = #{email} </if> </where> </select>
<choose>
, <when>
, <otherwise>
:
- 作用: 類似于 Java 中的
switch-case
語(yǔ)句,用于選擇其中一個(gè)條件分支。 <choose>
元素:包含多個(gè)<when>
元素和一個(gè)<otherwise>
元素。<when>
元素:指定條件和對(duì)應(yīng)的 SQL 代碼。<otherwise>
元素:指定默認(rèn)的 SQL 代碼(當(dāng)所有<when>
條件都不滿足時(shí)執(zhí)行)。test
屬性:指定<when>
元素的判斷條件,使用 OGNL 表達(dá)式。
示例:
<select id="selectUserByCondition" parameterType="com.example.model.User" resultMap="UserResultMap"> SELECT * FROM user <where> <choose> <when test="username != null and username != ''"> AND username = #{username} </when> <when test="email != null and email != ''"> AND email = #{email} </when> <otherwise> AND 1 = 1 </otherwise> </choose> </where> </select>
<where>
:
- 作用: 動(dòng)態(tài)生成
WHERE
子句,并自動(dòng)處理AND
或OR
關(guān)鍵字。 - 如果
<where>
元素內(nèi)部有任何內(nèi)容,它會(huì)自動(dòng)添加WHERE
關(guān)鍵字。 - 如果
<where>
元素內(nèi)部的內(nèi)容以AND
或OR
開(kāi)頭,它會(huì)自動(dòng)移除這些關(guān)鍵字。
示例:
<select id="selectUserByCondition" parameterType="com.example.model.User" resultMap="UserResultMap"> SELECT * FROM user <where> <if test="username != null and username != ''"> AND username = #{username} </if> <if test="email != null and email != ''"> AND email = #{email} </if> </where> </select>
<set>
:
- 作用: 動(dòng)態(tài)生成
SET
子句,用于 UPDATE 語(yǔ)句,并自動(dòng)處理逗號(hào),
。 - 如果
<set>
元素內(nèi)部有任何內(nèi)容,它會(huì)自動(dòng)添加SET
關(guān)鍵字。 - 如果
<set>
元素內(nèi)部的內(nèi)容以逗號(hào),
開(kāi)頭,它會(huì)自動(dòng)移除這個(gè)逗號(hào)。
示例:
<update id="updateUserSelective" parameterType="com.example.model.User"> UPDATE user <set> <if test="username != null"> username = #{username}, </if> <if test="email != null"> email = #{email}, </if> </set> WHERE id = #{id} </update>
<trim>
:
- 作用: 更通用的動(dòng)態(tài) SQL 元素,可以自定義前綴、后綴、以及前綴和后綴要移除的內(nèi)容。
prefix
屬性:指定前綴。suffix
屬性:指定后綴。prefixOverrides
屬性:指定要移除的前綴。suffixOverrides
屬性:指定要移除的后綴。
示例:
<select id="selectUserByCondition" parameterType="com.example.model.User" resultMap="UserResultMap"> SELECT * FROM user <trim prefix="WHERE" prefixOverrides="AND |OR"> <if test="username != null and username != ''"> AND username = #{username} </if> <if test="email != null and email != ''"> AND email = #{email} </if> </trim> </select> <update id="updateUserSelective" parameterType="com.example.model.User"> UPDATE user <trim prefix="SET" suffixOverrides=","> <if test="username != null"> username = #{username}, </if> <if test="email != null"> email = #{email}, </if> </trim> WHERE id = #{id} </update>
<foreach>
:
- 作用: 用于遍歷集合,生成重復(fù)的 SQL 代碼。
collection
屬性:指定要遍歷的集合。item
屬性:指定集合中元素的別名。index
屬性:指定當(dāng)前元素的索引的別名。open
屬性:指定循環(huán)開(kāi)始時(shí)的字符串。close
屬性:指定循環(huán)結(jié)束時(shí)的字符串。separator
屬性:指定元素之間的分隔符。
示例:
<select id="selectUsersByIds" parameterType="list" resultMap="UserResultMap"> SELECT * FROM user WHERE id IN <foreach item="id" collection="list" open="(" separator="," close=")"> #{id} </foreach> </select> <insert id="insertUsers" parameterType="list"> INSERT INTO user (username, email) VALUES <foreach item="user" collection="list" separator="," > (#{user.username}, #{user.email}) </foreach> </insert>
<bind>
:
- 作用: 創(chuàng)建一個(gè)變量,并將其綁定到 OGNL 表達(dá)式的結(jié)果。
name
屬性: 指定變量名value
屬性: 指定 OGNL 表達(dá)式
示例:
<select id="selectUsersBySearchTerm" parameterType="string" resultMap="UserResultMap"> <bind name="pattern" value="'%' + searchTerm + '%'" /> SELECT * FROM user WHERE username LIKE #{pattern} OR email LIKE #{pattern} </select>
五、DOCTYPE (Document Type Definition)
MyBatis SQL 映射文件需要遵循特定的 DTD 約束.
DTD 聲明:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
DTD 文件:
mybatis-3-mapper.dtd
文件定義了 MyBatis SQL 映射文件的結(jié)構(gòu)。可以在 MyBatis 的官方網(wǎng)站上找到該文件。- 開(kāi)發(fā)中通常不需要我們手動(dòng)修改 DTD 文件,只需要在 XML 配置文件中聲明 DTD 即可。
六、總結(jié)
MyBatis SQL 映射文件是 MyBatis 框架的核心,它定義了 SQL 語(yǔ)句以及如何將 SQL 語(yǔ)句的參數(shù)和結(jié)果映射到 Java 對(duì)象。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot實(shí)現(xiàn)分頁(yè)功能
這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)分頁(yè)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08Spring MVC環(huán)境中文件上傳功能的實(shí)現(xiàn)方法詳解
文件上傳是大家應(yīng)該都不陌生的一個(gè)功能,最近在開(kāi)發(fā)中就又遇到了這個(gè)需求,所以想著總結(jié)一下方便以后需要的時(shí)候參考,下面這篇文章主要給大家介紹了關(guān)于Spring MVC環(huán)境中文件上傳功能的實(shí)現(xiàn)方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-10-10Java中Quartz高可用定時(shí)任務(wù)快速入門
如果你想做定時(shí)任務(wù),有高可用方面的需求,或者僅僅想入門快,上手簡(jiǎn)單,那么選用它準(zhǔn)沒(méi)錯(cuò),感興趣的小伙伴們可以參考一下2022-04-04Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法
本篇文章主要介紹了Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03