欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mybatis Mapper接口和xml綁定的多種方式、內(nèi)部實(shí)現(xiàn)原理和過程解析

 更新時(shí)間:2023年11月15日 15:09:57   作者:say榮帥  
在Mybatis中,我們需要?jiǎng)?chuàng)建一個(gè)與實(shí)體類對(duì)應(yīng)的Mapper接口,然后在該接口上添加方法,這些方法對(duì)應(yīng)著SQL語(yǔ)句,這篇文章主要介紹了Mybatis Mapper接口和xml綁定的多種方式、內(nèi)部實(shí)現(xiàn)原理和過程,需要的朋友可以參考下

一、綁定方式

1. XML文件方式

在Mybatis中,我們需要?jiǎng)?chuàng)建一個(gè)與實(shí)體類對(duì)應(yīng)的Mapper接口,然后在該接口上添加方法,這些方法對(duì)應(yīng)著SQL語(yǔ)句。然后,我們需要?jiǎng)?chuàng)建一個(gè)XML文件,這個(gè)文件中包含了SQL語(yǔ)句和映射關(guān)系。

例如,我們有一個(gè)User實(shí)體類和一個(gè)UserMapper接口:

public interface UserMapper {
    User getUserById(int id);
}

然后,我們可以創(chuàng)建一個(gè)名為UserMapper.xml的文件,內(nèi)容如下:

<mapper namespace="com.example.dao.UserMapper">
    <select id="getUserById" resultType="com.example.entity.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

在這個(gè)XML文件中,namespace屬性指定了Mapper接口的全限定名,id屬性指定了SQL語(yǔ)句的唯一標(biāo)識(shí)符,resultType屬性指定了查詢結(jié)果的類型。

2. 注解方式

Mybatis也支持通過注解的方式來(lái)進(jìn)行映射。首先,需要在Mapper接口上添加@Mapper注解,然后在方法上添加@Select、@Insert、@Update、@Delete等注解來(lái)指定SQL語(yǔ)句。

例如,我們可以將上面的UserMapper接口改為注解方式:

import org.apache.ibatis.annotations.*;
@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User getUserById(int id);
}

在這個(gè)例子中,@Mapper注解表示這是一個(gè)Mapper接口,@Select注解表示這是一個(gè)查詢語(yǔ)句,#{id}是參數(shù)占位符。

3. 需要注意

啟動(dòng)類上添加@MapperScan注解指定掃描路徑

@SpringBootApplication
@MapperScan("com.example.mapper") // 指定掃描路徑
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

不用@MapperScan注解,也可以在mybatis-config.xml中配置mapper映射文件的位置和命名空間

<configuration>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/> // 指定Mapper映射文件的位置和名稱
    </mappers>
</configuration>

二、實(shí)現(xiàn)原理

1. 原理

Mybatis的Mapper接口和xml綁定的原理主要依賴于JDK動(dòng)態(tài)代理技術(shù)。

而Mybatis中MapperProxy代理類是mybatis實(shí)現(xiàn)Mapper接口和xml綁定的核心類之一。它實(shí)現(xiàn)了InvocationHandler接口,用于攔截Mapper接口方法的調(diào)用,并將方法名和參數(shù)傳遞給SqlSession對(duì)象執(zhí)行相應(yīng)的SQL語(yǔ)句。

2. MapperProxy代理類的實(shí)現(xiàn)過程

  • 首先,通過JDK動(dòng)態(tài)代理技術(shù)生成一個(gè)MapperProxy代理類實(shí)例。這個(gè)代理類實(shí)現(xiàn)了Mapper接口,并重寫了接口中的方法。
  • 在重寫的方法中,MapperProxy會(huì)攔截方法調(diào)用,并將方法名和參數(shù)傳遞給SqlSession對(duì)象執(zhí)行相應(yīng)的SQL語(yǔ)句。
  • SqlSession對(duì)象會(huì)根據(jù)Mapper接口的namespace值找到對(duì)應(yīng)的mapper.xml文件,并根據(jù)id值找到對(duì)應(yīng)的SQL語(yǔ)句。然后,根據(jù)返回值類型和參數(shù)類型等信息,生成相應(yīng)的Java代碼。這些Java代碼會(huì)包含對(duì)SqlSession的操作,例如查詢、更新等操作。最終,SqlSession對(duì)象會(huì)將這些Java代碼編譯成字節(jié)碼,并加載到JVM中運(yùn)行。
  • 當(dāng)SQL語(yǔ)句執(zhí)行完畢后,SqlSession對(duì)象會(huì)將結(jié)果返回給MapperProxy代理類。然后,MapperProxy代理類會(huì)將結(jié)果映射為Java對(duì)象,并返回給調(diào)用者。

3. MapperProxy代理類源碼

下面是MapperProxy代理class的核心方法實(shí)現(xiàn):mybatis3.5.9

public class MapperProxy<T> implements InvocationHandler, Serializable {
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, args);
      } else {
        return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }
  private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
    try {
      return MapUtil.computeIfAbsent(methodCache, method, m -> {
        if (m.isDefault()) {
          try {
            if (privateLookupInMethod == null) {
              return new DefaultMethodInvoker(getMethodHandleJava8(method));
            } else {
              return new DefaultMethodInvoker(getMethodHandleJava9(method));
            }
          } catch (IllegalAccessException | InstantiationException | InvocationTargetException
              | NoSuchMethodException e) {
            throw new RuntimeException(e);
          }
        } else {
          return new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
        }
      });
    } catch (RuntimeException re) {
      Throwable cause = re.getCause();
      throw cause == null ? re : cause;
    }
  }
  private MethodHandle getMethodHandleJava9(Method method)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    final Class<?> declaringClass = method.getDeclaringClass();
    return ((Lookup) privateLookupInMethod.invoke(null, declaringClass, MethodHandles.lookup())).findSpecial(
        declaringClass, method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes()),
        declaringClass);
  }
  private MethodHandle getMethodHandleJava8(Method method)
      throws IllegalAccessException, InstantiationException, InvocationTargetException {
    final Class<?> declaringClass = method.getDeclaringClass();
    return lookupConstructor.newInstance(declaringClass, ALLOWED_MODES).unreflectSpecial(method, declaringClass);
  }
}

到此這篇關(guān)于Mybatis Mapper接口和xml綁定的多種方式、內(nèi)部實(shí)現(xiàn)原理和過程的文章就介紹到這了,更多相關(guān)Mybatis Mapper接口和xml綁定內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis 數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)示例

    Mybatis 數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)示例

    在Java應(yīng)用程序中,與數(shù)據(jù)庫(kù)的連接是非常昂貴的,因此,當(dāng)我們使用MyBatis進(jìn)行數(shù)據(jù)操作時(shí),需要一個(gè)連接池來(lái)分配并管理這些連接,本文主要介紹了Mybatis 數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • 關(guān)于maven的用法和幾個(gè)常用的命令

    關(guān)于maven的用法和幾個(gè)常用的命令

    這篇文章主要介紹了關(guān)于maven的用法和幾個(gè)常用的命令,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • SpringBoot實(shí)現(xiàn)簡(jiǎn)單的登錄注冊(cè)的項(xiàng)目實(shí)戰(zhàn)

    SpringBoot實(shí)現(xiàn)簡(jiǎn)單的登錄注冊(cè)的項(xiàng)目實(shí)戰(zhàn)

    本文主要介紹了SpringBoot實(shí)現(xiàn)簡(jiǎn)單的登錄注冊(cè)的項(xiàng)目實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • JAVA?OOM內(nèi)存溢出問題深入解析

    JAVA?OOM內(nèi)存溢出問題深入解析

    這篇文章主要為大家介紹了JAVA?OOM內(nèi)存溢出問題深入解析,在生產(chǎn)環(huán)境搶修中,我們經(jīng)常會(huì)碰到應(yīng)用系統(tǒng)java內(nèi)存OOM的情況,這個(gè)問題非常常見,今天我們就這個(gè)問題來(lái)深入學(xué)習(xí)探討一下
    2023-10-10
  • 基于IDEA查看maven依賴結(jié)構(gòu)流程解析

    基于IDEA查看maven依賴結(jié)構(gòu)流程解析

    這篇文章主要介紹了基于IDEA查看maven依賴結(jié)構(gòu)流程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • spring中@Transactional?注解失效的原因及解決辦法

    spring中@Transactional?注解失效的原因及解決辦法

    面試中經(jīng)常會(huì)被問到事務(wù)失效的場(chǎng)景有哪些,本文主要介紹了spring中@Transactional?注解失效的原因及解決辦法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • Java關(guān)于JDK1.8中的Optional類

    Java關(guān)于JDK1.8中的Optional類

    本文主要介紹了Optional類的一些常用方法,以及其應(yīng)用場(chǎng)景,其主要是為了規(guī)避空指針異常(NPE)。熟練的運(yùn)用Optional類可以很大的簡(jiǎn)化我們的代碼,使代碼簡(jiǎn)潔明了。,需要的朋友可以參考下面文章內(nèi)容
    2021-09-09
  • java版實(shí)現(xiàn)2048游戲功能

    java版實(shí)現(xiàn)2048游戲功能

    這篇文章主要為大家詳細(xì)介紹了java版實(shí)現(xiàn)2048游戲功能,相加數(shù)字出現(xiàn)2048即可,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • RocketMQ消息中間件超詳細(xì)解讀

    RocketMQ消息中間件超詳細(xì)解讀

    這篇文章主要介紹了RocketMQ消息中間件超詳細(xì)解讀,RocketMQ作為一款純java、分布式、隊(duì)列模型的開源消息中間件,支持事務(wù)消息、順序消息、批量消息、定時(shí)消息、消息回溯等,本文就來(lái)詳細(xì)解讀一下,需要的朋友可以參考下
    2023-05-05
  • Java中進(jìn)程與線程的區(qū)別

    Java中進(jìn)程與線程的區(qū)別

    這篇文章主要介紹了Java進(jìn)程與線程的區(qū)別,進(jìn)程(Process)是操作系統(tǒng)分配資源的基本單位,線程(Thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的基本單位,下文更多兩者區(qū)別。需要的小伙伴可以參考一下
    2022-05-05

最新評(píng)論