MyBatis?SQL映射文件的作用和結(jié)構(gòu)詳解
MyBatis SQL 映射文件定義了 SQL 語(yǔ)句以及如何將 SQL 語(yǔ)句的參數(shù)和結(jié)果映射到 Java 對(duì)象。
一、 作用 (Purpose)
MyBatis SQL 映射文件(通常命名為 XXXMapper.xml)的主要作用是:
- 定義 SQL 語(yǔ)句: 在 XML 映射文件中編寫(xiě) SQL 語(yǔ)句,包括 SELECT, INSERT, UPDATE, DELETE 等各種類(lèi)型的 SQL 語(yǔ)句。
- 參數(shù)映射 (Parameter Mapping): 定義如何將 Java 方法的參數(shù)映射到 SQL 語(yǔ)句中的參數(shù)。 可以使用
#和$占位符,并指定參數(shù)類(lèi)型、jdbcType 等信息。 - 結(jié)果映射 (Result Mapping): 定義如何將 SQL 語(yǔ)句的查詢(xún)結(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ǔ)句的緩存行為,提高查詢(xún)性能。
- 與 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ā)者專(zhuān)注于 SQL 語(yǔ)句的編寫(xiě)和優(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 (查詢(xún)) -->
<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ǔ)句的查詢(xún)結(jié)果映射到 Java 對(duì)象。
id屬性:指定resultMap的唯一標(biāo)識(shí)。type屬性:指定要映射的 Java 類(lèi)型。
子元素:
<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 類(lèi)型。select屬性:指定用于查詢(xún)關(guān)聯(lián)對(duì)象的 SQL 語(yǔ)句的 ID。
<collection>:定義一對(duì)多關(guān)系映射。property屬性:指定 Java 對(duì)象的屬性名。column屬性:指定數(shù)據(jù)庫(kù)表中的列名。ofType屬性:指定集合中元素的 Java 類(lèi)型。select屬性:指定用于查詢(xún)集合元素的 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> (查詢(xún)):
- 作用: 定義 SELECT 語(yǔ)句,用于查詢(xún)數(shù)據(jù)。
id屬性:指定 SQL 語(yǔ)句的唯一標(biāo)識(shí)。 與 Mapper 接口中的方法名對(duì)應(yīng)。parameterType屬性:指定參數(shù)類(lèi)型。resultType屬性:指定結(jié)果類(lèi)型(如果使用簡(jiǎn)單類(lèi)型映射)。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類(lèi)型, 可選值為 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ù)類(lèi)型。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ù)類(lèi)型。
示例:
<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ù)類(lèi)型。
示例:
<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>:
- 作用: 類(lèi)似于 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-08
Spring 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-10
Java中Quartz高可用定時(shí)任務(wù)快速入門(mén)
如果你想做定時(shí)任務(wù),有高可用方面的需求,或者僅僅想入門(mén)快,上手簡(jiǎn)單,那么選用它準(zhǔn)沒(méi)錯(cuò),感興趣的小伙伴們可以參考一下2022-04-04
Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法
本篇文章主要介紹了Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03

