首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

MyBatis Mapper 動態代理機制詳解:接口映射規範與最佳實踐

     編輯:Java 相關知識

Mapper 代理核心原理

MyBatis 通過 JDK 動態代理為 Mapper 接口生成實現類,SQL 定義在 XML 中,運行時根據**方法名、參數類型、返回類型**與 XML 中的 `` 節點進行綁定。

四大映射規範(必須遵守)

規範項要求示例
Namespace等於 Mapper 接口全限定名namespace="com.demo.mapper.UserMapper"
Statement ID等於接口方法名id="findUserById"
ParameterType與方法參數類型一致parameterType="int" / parameterType="User"
ResultType/ResultMap與方法返回類型一致resultType="User" / resultMap="UserMap"

Mapper 接口與 XML 範例

// UserMapper.java
public interface UserMapper {
    User findUserById(int id);                    // 單參數
    List findUsersByName(String name);      // 單參數集合返回
    int insertUser(User user);                    // POJO 參數
    int updateUser(User user);                    // POJO 參數
    void deleteUser(int id);                      // void 返回
}
<mapper namespace="com.demo.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>

    <select id="findUsersByName" parameterType="String" resultType="User">
        SELECT * FROM user WHERE name LIKE CONCAT('%', #{name}, '%')
    </select>

    <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user(name, age) VALUES(#{name}, #{age})
    </insert>

    <update id="updateUser" parameterType="User">
        UPDATE user SET name=#{name}, age=#{age} WHERE id=#{id}
    </update>

    <delete id="deleteUser" parameterType="int">
        DELETE FROM user WHERE id = #{id}
    </delete>
</mapper>

SqlMapConfig.xml 註冊方式

單個註冊

<mappers>
    <mapper class="com.demo.mapper.UserMapper"/>
</mappers>

批量掃描包(推薦)

<mappers>
    <package name="com.demo.mapper"/>
</mappers>

前提:Mapper 接口與 XML 同名、同目錄(或 resources 對應目錄)。

進階映射技巧

  1. 多參數 @Param:
    List findByNameAndAge(@Param("name") String name, @Param("age") int age);
    XML 直接用 #{name}, #{age}
  2. Map 參數:方法接收 Map,XML 取值同 key
  3. 結果映射 ResultMap:處理字段名與屬性名不一致、關聯查詢、嵌套結果
  4. 自定義 TypeHandler:枚舉、JSON、加密字段的自動轉換

常見錯誤與排查

| 錯誤現象 | 可能原因 | 解決 | |----------|----------|------| | `BindingException: Invalid bound statement` | Namespace/ID 拼寫錯誤、XML 未被掃描 | 核對四大規範、檢查 package 掃描路徑 | | 參數綁定失敗 | 多參數未加 @Param、parameterType 錯誤 | 加 @Param 或用 Map/POJO 封裝 | | 返回類型不匹配 | resultType 與實際不符、泛型擦除 | 使用 resultMap 或明確指定 resultType | | 事務不生效 | 未配置事務管理器、方法未加 @Transactional | 檢查 Spring 事務配置 |

最佳實踐總結

  1. **接口與 XML 同名同包**,啟用 `` 批量掃描
  2. **單參數用基本類型/POJO,多參數必加 @Param**
  3. **複雜查詢用 ResultMap**,避免 resultType 字段名不匹配
  4. **DAO 層只定義接口**,XML 專注 SQL,業務邏輯在 Service 層
  5. **善用 MyBatis Generator** 生成基礎 CRUD,手寫複雜 SQL
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved