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

