最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis?Mapper?接口是如何找到并執(zhí)行SQL的

 更新時(shí)間:2025年09月16日 09:57:39   作者:java干貨  
本文將為你揭開MyBatis這層神秘的面紗,深入剖析其接口與SQL的映射原理,并總結(jié)在Spring?Boot環(huán)境下的最佳實(shí)踐和常見陷阱,感興趣的朋友跟隨小編一起看看吧

每一位使用 MyBatis 的 Java 開發(fā)者,都曾體驗(yàn)過這種“魔法”:我們只定義了一個(gè)簡(jiǎn)單的 UserMapper 接口,沒有寫任何實(shí)現(xiàn)類,但只要在 Service 中注入它并調(diào)用其方法,數(shù)據(jù)庫(kù)操作就奇跡般地完成了。

// 在 Service 中
@Autowired
private UserMapper userMapper;
public User getUser(Long id) {
// 只是調(diào)用了一個(gè)接口方法
return userMapper.selectById(id);
}

UserMapper 只是一個(gè)接口,它沒有實(shí)現(xiàn)類,那 userMapper 這個(gè)注入的 Bean 到底是什么?selectById 這個(gè)方法又是如何與具體的 SQL 語(yǔ)句關(guān)聯(lián)起來的呢?

本文將為你揭開 MyBatis 這層神秘的面紗,深入剖析其接口與 SQL 的映射原理,并總結(jié)在 Spring Boot 環(huán)境下的最佳實(shí)踐和常見陷阱。

1. 核心原理:JDK 動(dòng)態(tài)代理 (Dynamic Proxy)

MyBatis 的“魔法”核心,正是 Java 的 JDK 動(dòng)態(tài)代理 技術(shù)。

當(dāng)你試圖從 Spring 容器中獲取一個(gè) UserMapper 實(shí)例時(shí),Spring 實(shí)際上是請(qǐng)求 MyBatis 的 MapperFactoryBean 來創(chuàng)建一個(gè) Bean。MyBatis 并不會(huì)去尋找這個(gè)接口的實(shí)現(xiàn)類,而是利用 JDK 的 Proxy 類,在運(yùn)行時(shí)動(dòng)態(tài)地為你創(chuàng)建一個(gè)該接口的代理對(duì)象。

這個(gè)代理對(duì)象,就是你注入到 Service 中的 userMapper。它具備了 UserMapper 接口的所有方法,但它不是一個(gè)普通的實(shí)現(xiàn)。你可以把它想象成一個(gè)聰明的“中介”或“調(diào)度員”。

當(dāng)你調(diào)用 userMapper.selectById(1L) 時(shí),實(shí)際發(fā)生了以下事情:

  • 1. 方法攔截: 這個(gè)調(diào)用首先被代理對(duì)象攔截。
  • 2. 信息解析: 代理對(duì)象會(huì)解析出你調(diào)用的信息,包括:
    • • 接口名: com.example.mapper.UserMapper
    • • 方法名: selectById
    • • 參數(shù): 1L
  • 3. SQL 尋址: 這是最關(guān)鍵的一步。代理對(duì)象會(huì)根據(jù)**“接口名 + 方法名”**這個(gè)唯一的坐標(biāo),去 MyBatis 的全局配置中尋找與之對(duì)應(yīng)的 SQL 語(yǔ)句。
  • 4. SQL 執(zhí)行: 找到 SQL 后,代理對(duì)象會(huì)利用底層的 SqlSession,將參數(shù) 1L 傳遞進(jìn)去,通過 JDBC 執(zhí)行這條 SQL。
  • 5. 結(jié)果映射: 將數(shù)據(jù)庫(kù)返回的結(jié)果,根據(jù)配置映射成 Java 對(duì)象并返回。

所以,整個(gè)問題的關(guān)鍵就變成了:MyBatis 是如何完成第3步——**“SQL 尋址”**的?

2. “尋址”的藝術(shù):兩種主要的映射方式

MyBatis 提供了兩種方式,來告訴代理對(duì)象“接口方法”和“SQL語(yǔ)句”之間的對(duì)應(yīng)關(guān)系。

方式一:XML 映射文件 (最強(qiáng)大、最常用)

這是 MyBatis 最傳統(tǒng)也是功能最豐富的映射方式。它遵循兩條黃金法則:

法則1:namespace 必須是 Mapper 接口的全限定名。
這是連接 XML 文件和 Java 接口的“紅線”。

法則2:select/insert/update/delete 等標(biāo)簽的 id 必須與接口中的方法名完全一致。
這是定位到具體 SQL 語(yǔ)句的“門牌號(hào)”。

示例:

UserMapper.java (接口定義)

package com.example.mapper;
public interface UserMapper {
    User selectById(Long id);
    void insert(User user);
}

UserMapper.xml (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">
    <select id="selectById" resultType="com.example.model.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
    <insert id="insert">
        INSERT INTO users(username, email) VALUES(#{username}, #{email})
    </insert>
</mapper>

當(dāng)調(diào)用 UserMapper.selectById() 時(shí),代理對(duì)象會(huì)精確地找到 namespace 為 com.example.mapper.UserMapper 的 XML 文件中,id 為 selectById 的 <select> 標(biāo)簽,并執(zhí)行其中的 SQL。

方式二:注解 (簡(jiǎn)單 SQL 的便捷之選)

對(duì)于簡(jiǎn)單的 SQL 語(yǔ)句,我們可以完全拋棄 XML,直接在接口方法上使用注解。

示例:

package com.example.mapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User selectById(Long id);
    @Insert("INSERT INTO users(username, email) VALUES(#{username}, #{email})")
    void insert(User user);
}

這種方式非常直觀,但當(dāng) SQL 變得復(fù)雜,特別是需要?jiǎng)討B(tài) SQL(ifforeach等)時(shí),XML 的表現(xiàn)力遠(yuǎn)勝于注解。

3. 讓 MyBatis 找到你的 Mapper:掃描與注冊(cè)

我們已經(jīng)定義好了映射關(guān)系,但還需要告訴 MyBatis 去哪里“發(fā)現(xiàn)”這些接口和 XML 文件。

在現(xiàn)代 Spring Boot 項(xiàng)目中,這通常通過 mybatis-spring-boot-starter 自動(dòng)完成,我們只需提供少量配置。

1. @MapperScan 注解 (推薦)
在你的 Spring Boot 主啟動(dòng)類上,添加 @MapperScan 注解,并指定 Mapper 接口所在的包路徑。

@SpringBootApplication
@MapperScan("com.example.mapper")
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

這個(gè)注解會(huì)告訴 MyBatis:“請(qǐng)掃描 com.example.mapper 包下的所有接口,并將它們注冊(cè)為 Mapper Bean。”

2. @Mapper 注解
你也可以不在啟動(dòng)類上使用 @MapperScan,而是在每個(gè) Mapper 接口上單獨(dú)添加 @Mapper 注解。

@Mapper
public interface UserMapper { ... }

這樣,只要 UserMapper 接口在 Spring Boot 的組件掃描路徑下,它就會(huì)被自動(dòng)發(fā)現(xiàn)。但當(dāng) Mapper 接口很多時(shí),@MapperScan 顯然更方便。

3. XML 文件的位置
默認(rèn)情況下,MyBatis Spring Boot Starter 會(huì)在 classpath 中,尋找與 Mapper 接口同包同名的 XML 文件。

標(biāo)準(zhǔn)的 Maven 項(xiàng)目結(jié)構(gòu):

src/
  main/
    java/
      com/
        example/
          mapper/
            UserMapper.java
    resources/
      com/
        example/
          mapper/
            UserMapper.xml  <-- XML 放在 resources 目錄下,但包結(jié)構(gòu)與 Java 接口保持一致

如果你想把 XML 文件集中存放在另一個(gè)地方,可以在 application.yml 中通過 mybatis.mapper-locations 屬性來指定:

mybatis:
  mapper-locations: classpath:mappers/*.xml

4. 常見問題與陷阱

BindingException: Type ... is not known to the MapperRegistry.

含義: “未在 Mapper 注冊(cè)表中找到該類型”。

原因: MyBatis 根本沒發(fā)現(xiàn)你的 Mapper 接口。請(qǐng)檢查 @MapperScan 的包路徑是否正確,或者接口上是否漏了 @Mapper 注解。

BindingException: Invalid bound statement (not found): ...

含義: “無效的綁定語(yǔ)句(未找到)”。

原因: 接口找到了,但接口里的方法沒找到對(duì)應(yīng)的 SQL。請(qǐng)檢查:

1. XML 的 namespace 是否是接口的全限定名,一個(gè)字母都不能錯(cuò)。

2. XML 標(biāo)簽的 id 是否與方法名完全一致。

3. XML 文件是否被構(gòu)建工具(Maven/Gradle)正確地打包進(jìn)了最終的 jar 文件中。

 XML 文件未被打包:
如果你的 XML 文件放在 src/main/java 目錄下,Maven 默認(rèn)不會(huì)打包 .xml 文件。你需要在 pom.xml 中添加如下配置:

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

總結(jié)

MyBatis 的接口映射機(jī)制,看似“神奇”,實(shí)則建立在一套清晰、嚴(yán)謹(jǐn)?shù)囊?guī)則之上:

  • 1. 核心是 JDK 動(dòng)態(tài)代理,它在運(yùn)行時(shí)為你的接口創(chuàng)建了一個(gè)實(shí)現(xiàn)類。
  • 2. 映射的“鑰匙”是“全限定接口名 + 方法名”
  • 3. 映射關(guān)系可以通過 XML 或注解來定義。
  • 4. @MapperScan 是告知 MyBatis 從哪里開始尋找這些“鑰匙”的入口。

到此這篇關(guān)于MyBatis Mapper 接口是如何找到并執(zhí)行 SQL 的的文章就介紹到這了,更多相關(guān)MyBatis Mapper 接口執(zhí)行 SQL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis中foreach報(bào)錯(cuò):_frch_item_0 not found的解決方法

    mybatis中foreach報(bào)錯(cuò):_frch_item_0 not found的解決方法

    這篇文章主要給大家介紹了mybatis中foreach報(bào)錯(cuò):_frch_item_0 not found的解決方法,文章通過示例代碼介紹了詳細(xì)的解決方法,對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-06-06
  • mybatis-plus實(shí)現(xiàn)邏輯刪除的示例代碼

    mybatis-plus實(shí)現(xiàn)邏輯刪除的示例代碼

    在大多數(shù)公司里,都會(huì)采用邏輯刪除的方式,本文主要介紹了mybatis-plus實(shí)現(xiàn)邏輯刪除的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • java捕獲AOP級(jí)別的異常并將其傳遞到Controller層

    java捕獲AOP級(jí)別的異常并將其傳遞到Controller層

    如何在一個(gè)現(xiàn)代的Java應(yīng)用中,捕獲AOP(面向切面編程)級(jí)別的異常,并將這些異常傳遞到Controller層進(jìn)行合適的處理,異常處理在構(gòu)建可靠的應(yīng)用程序中起著關(guān)鍵作用,而AOP則可以幫助我們更好地管理和組織代碼,我們將深入研究如何結(jié)合AOP和異常處理來構(gòu)建健壯的應(yīng)用
    2023-09-09
  • 使用Java打印出所有的水仙花數(shù)的解決方法

    使用Java打印出所有的水仙花數(shù)的解決方法

    水仙花數(shù)也被稱為超完全數(shù)字不變數(shù)、自戀數(shù)、自冪數(shù),是指一個(gè)?n?位數(shù)?(n≥3),它的每個(gè)位上的數(shù)字的?n?次冪之和等于它本身,本文將通過?Java?語(yǔ)言來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的程序,用于找出并打印所有三位數(shù)中的水仙花數(shù),需要的朋友可以參考下
    2026-01-01
  • java使用poi生成excel的步驟

    java使用poi生成excel的步驟

    2010以上格式使用XSSFWorkBook對(duì)象, 2003格式使用HSSFWorkBook對(duì)象, 其他對(duì)象操作基本一樣,本文重點(diǎn)給大家介紹java使用poi生成excel的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2022-04-04
  • 一文詳解java如何實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用

    一文詳解java如何實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用

    從?Java?8?開始,便引入了一種稱為“流式?API”的編程風(fēng)格,當(dāng)然也被稱為“鏈?zhǔn)皆O(shè)置”或“鏈?zhǔn)秸{(diào)用”,本文主要來和大家討論一下如何實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,感興趣的可以了解下
    2023-12-12
  • Servlet+JavaBean+JSP打造Java Web注冊(cè)與登錄功能

    Servlet+JavaBean+JSP打造Java Web注冊(cè)與登錄功能

    比作MVC的話,控制器部分采用Servlet來實(shí)現(xiàn),模型部分采用JavaBean來實(shí)現(xiàn),而大部分的視圖采用Jsp頁(yè)面來實(shí)現(xiàn),接下來我們就來詳細(xì)看看如何用Servlet+JavaBean+JSP打造Java Web注冊(cè)與登錄功能
    2016-05-05
  • java使用DOM4J對(duì)XML文件進(jìn)行增刪改查操作

    java使用DOM4J對(duì)XML文件進(jìn)行增刪改查操作

    這篇文章主要為大家詳細(xì)介紹了java使用DOM4J對(duì)XML文件進(jìn)行增刪改查操作,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 使用IDEA工具配置和運(yùn)行vue項(xiàng)目及遇到的坑

    使用IDEA工具配置和運(yùn)行vue項(xiàng)目及遇到的坑

    這篇文章主要介紹了使用IDEA工具配置和運(yùn)行vue項(xiàng)目及遇到的坑,需要的朋友可以參考下
    2018-09-09
  • java 中序列化與readResolve()方法的實(shí)例詳解

    java 中序列化與readResolve()方法的實(shí)例詳解

    這篇文章主要介紹了java 中序列化與readResolve()方法的實(shí)例詳解的相關(guān)資料,這里提供實(shí)例幫助大家理解這部分知識(shí),需要的朋友可以參考下
    2017-08-08

最新評(píng)論

黄冈市| 平南县| 崇左市| 班玛县| 杭州市| 镇沅| 宝应县| 普安县| 垣曲县| 湘阴县| 紫金县| 巴中市| 同江市| 政和县| 绥芬河市| 和平县| 松滋市| 新郑市| 广水市| 凤阳县| 东城区| 凤台县| 西峡县| 冕宁县| 清流县| 朝阳区| 平江县| 固安县| 长沙县| 肥乡县| 丘北县| 南阳市| 奎屯市| 临沂市| 湖北省| 寻甸| 常山县| 晴隆县| 泾源县| 梁河县| 庆元县|