1.? 前言
既上次在Mapper.xml文件出現bug之后,痛改前非,決定吃透Mapper.xml映射文件。
讓我們通過具體的代碼段來進一步理解 MyBatis 的 Mapper XML 文件中的每個組成部分。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.goblin.BIbackend.mapper.BillsMapper"><resultMap id="BaseResultMap" type="com.goblin.BIbackend.model.entity.Bills"><id property="id" column="id" jdbcType="BIGINT"/><result property="userId" column="user_id" jdbcType="BIGINT"/><result property="amount" column="Amount" jdbcType="FLOAT"/><result property="billDate" column="bill_date" jdbcType="DATE"/><result property="dueDate" column="due_date" jdbcType="DATE"/><result property="isPaid" column="is_paid" jdbcType="BIGINT"/></resultMap><sql id="Base_Column_List">id,user_id,Amount,bill_date,due_date,is_paid</sql><select id="list" resultType="com.goblin.BIbackend.model.entity.Bills">select * from bills<where><if test="userId != null">user_id = #{userId}</if><if test="amount != null">and Amount = #{amount}</if><if test="billDate != null">and bill_date = #{billDate}</if><if test="dueDate != null">and due_date = #{dueDate}</if><if test="isPaid != null">and is_paid = #{isPaid}</if></where></select><select id="mySelectById" resultType="com.goblin.BIbackend.model.entity.Bills">select * from bills where id = #{id}</select><insert id="myInsert" parameterType="com.goblin.BIbackend.model.entity.Bills">insert into bills (user_id,Amount,bill_date,due_date,is_paid)values (#{userId},#{amount},#{billDate},#{dueDate},#{isPaid})</insert><delete id="myDeleteById" >delete from bills where id = #{id}</delete><select id="mySelectAll" resultMap="BaseResultMap">select * from bills</select><update id="myUpdate" parameterType="com.goblin.BIbackend.model.entity.Bills">update bills where id = #{id}</update></mapper>
2.? 各部分
2.1? <mapper>根元素
<mapper namespace="com.goblin.BIbackend.mapper.BillsMapper"><!-- 其他配置 -->
</mapper>
這個根元素定義了 XML 文件的命名空間,通常對應 Java 中的 Mapper 接口的完全限定名。這有助于區分不同的 Mapper 文件,防止 SQL 語句沖突。
2.2??<resultMap>
?和字段映射
<resultMap id="BaseResultMap" type="com.goblin.BIbackend.model.entity.Bills"><id property="id" column="id" jdbcType="BIGINT"/><result property="userId" column="user_id" jdbcType="BIGINT"/><result property="amount" column="Amount" jdbcType="FLOAT"/><result property="billDate" column="bill_date" jdbcType="DATE"/><result property="dueDate" column="due_date" jdbcType="DATE"/><result property="isPaid" column="is_paid" jdbcType="BIGINT"/>
</resultMap>
這里定義了一個名為 BaseResultMap
的結果映射,它將數據庫查詢結果映射到 com.goblin.BIbackend.model.entity.Bills
類的實例。
具體映射關系如下:
1. id屬性對應數據庫表的id列,數據類型為BIGINT。
2. userId屬性對應數據庫表的user_id列,數據類型為BIGINT。
3. amount屬性對應數據庫表的Amount列,數據類型為FLOAT。
4. billDate屬性對應數據庫表的bill_date列,數據類型為DATE。
5. dueDate屬性對應數據庫表的due_date列,數據類型為DATE。
6. isPaid屬性對應數據庫表的is_paid列,數據類型為BIGINT。
前面是實體類里面定義的名稱,后面是數據庫里面對應的字段名。?
2.3??<sql>
?片段
<sql id="Base_Column_List">id, user_id, Amount, bill_date, due_date, is_paid
</sql>
id
: 為 SQL 片段定義一個標識符,可以在?<select>
?或其他元素中通過?<include>
?引用。- 內容: 列出了查詢操作中需要的列名。這是為了避免在多個?
<select>
?元素中重復相同的列名列表。
2.4? 增刪改查SQL語句
<select id="list" resultType="com.goblin.BIbackend.model.entity.Bills">select * from bills<where><if test="userId != null">user_id = #{userId}</if><if test="amount != null">and Amount = #{amount}</if><if test="billDate != null">and bill_date = #{billDate}</if><if test="dueDate != null">and due_date = #{dueDate}</if><if test="isPaid != null">and is_paid = #{isPaid}</if></where></select><select id="mySelectById" resultType="com.goblin.BIbackend.model.entity.Bills">select * from bills where id = #{id}</select><insert id="myInsert" parameterType="com.goblin.BIbackend.model.entity.Bills">insert into bills (user_id,Amount,bill_date,due_date,is_paid)values (#{userId},#{amount},#{billDate},#{dueDate},#{isPaid})</insert><delete id="myDeleteById" >delete from bills where id = #{id}</delete><update id="myUpdate" parameterType="com.goblin.BIbackend.model.entity.Bills">update bills where id = #{id}</update>
parameterType
和 resultType
?在 SQL 映射文件中用于指定參數和結果的 Java 類型,但它們的作用和使用場景不同。?一定不能寫錯,否則測試接口的時候就錯亂了。
2.4.1??resultType
- 作用:
resultType
?用于指定 MyBatis 查詢操作返回的結果類型。這個屬性告訴 MyBatis 應該如何將查詢結果集的每一行映射到 Java 對象。- 使用場景:通常用在?
<select>
?元素中,用于定義查詢結果應該如何映射到 Java 類的實例。- 示例:
<select id="selectBlog" resultType="Blog">select * from Blog </select>
在這個例子中,
resultType
?指定了查詢結果應該映射到?Blog
?類的實例。
2.4.2??parameterType
- 作用:
parameterType
?用于指定 MyBatis 操作(如?<insert>
、<update>
、<delete>
?或帶有參數的?<select>
)中傳入的參數類型。這個屬性告訴 MyBatis 期待的參數對象的類型,MyBatis 會根據這個類型來自動映射方法參數和 SQL 語句中的占位符。- 使用場景:通常用在需要傳入參數執行數據庫操作的元素中,例如插入、更新或刪除操作。
- 示例:
<select id="selectById" parameterType="java.util.Map" resultType="com.example.Blog">select * from blog where id = #{id} </select>
在這個例子中,
parameterType
?指定了方法的參數類型為?java.util.Map
,這意味著你可以傳遞一個 Map 對象作為查詢參數。
2.4.3? 兩者區別總結?
- 方向:
parameterType
?定義了進入操作的參數類型,而?resultType
?定義了從數據庫查詢返回的結果類型。- 使用位置:
parameterType
?通常用在需要參數的 SQL 操作中,resultType
?則用在查詢操作中。- 映射方式:
parameterType
?映射的是方法的參數到 SQL 語句的占位符,resultType
?映射的是查詢結果集到 Java 對象的屬性。
?2.4.5??占位符#{id}
在 SQL 映射文件中編寫 SQL 語句時,可以使用
#{}
來引用 Java 方法的參數。<select id="selectBlog" resultType="Blog">SELECT * FROM blog WHERE id = #{id} </select>
在這個例子中,
#{id}
就是一個占位符,它將被 MyBatis 替換為方法參數id
的值。參數替換
MyBatis 會根據方法的參數列表自動替換
#{}
中的內容。如果方法的參數是一個簡單類型或 POJO(Plain Old Java Object),MyBatis 會根據參數的名稱來替換占位符。預處理語句
使用
#{}
占位符的 SQL 語句會被 MyBatis 轉換為預處理語句(PreparedStatement),這樣可以提高性能并防止 SQL 注入攻擊。類型處理
MyBatis 會根據參數的實際類型來設置 SQL 語句中的參數。例如,如果參數是
java.sql.Date
類型,MyBatis 會使用適當的 JDBC 方法來設置日期參數。占位符總結
#{}
占位符是 MyBatis 中實現參數化查詢的關鍵機制,它允許開發者將 Java 方法的參數值安全、靈活地傳遞給 SQL 語句。通過使用#{}
,MyBatis 可以自動處理參數的類型轉換和預處理語句的生成,從而提高數據庫操作的效率和安全性。