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

MyBatis?ParameterHandler的具體使用

 更新時(shí)間:2025年08月29日 11:05:02   作者:靈魂獵手  
本文主要介紹了MyBatis?ParameterHandler的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、概述

書接上回,StatementHandler參數(shù)處理&結(jié)果處理,分別委托給ParameterHandler&ResultSetHandler(注意不是ResultHandler)。那么本文介紹一下ParameterHandler。

本系列的第二章,我們講了Mybatis的參數(shù)處理,那個(gè)參數(shù)處理,是把Mapper中各種可能的參數(shù)封裝為Map,而這個(gè)參數(shù)處理,是把Map參數(shù),設(shè)置到JDBC的Statement中。

二、源碼

MyBatis中ParameterHandler只有一個(gè)實(shí)現(xiàn)DefaultParameterHandler,我們通過源碼來解析其工作原理。

1 關(guān)鍵屬性

DefaultParameterHandler 的關(guān)鍵屬性:

  • MappedStatement:包含SQL元信息;
  • parameterObject:Mapper方法傳入的原始參數(shù);
  • BoundSql:包含解析后的 SQL 語句和參數(shù)映射列表;
  • TypeHandlerRegistry:類型處理器注冊(cè)表,用于查找合適的 TypeHandler。
public class DefaultParameterHandler implements ParameterHandler {
    private final MappedStatement mappedStatement;
    private final Object parameterObject;
    private final BoundSql boundSql;
    private final Configuration configuration;
    private final TypeHandlerRegistry typeHandlerRegistry;

    public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
        this.mappedStatement = mappedStatement;
        this.parameterObject = parameterObject;
        this.boundSql = boundSql;
        this.configuration = mappedStatement.getConfiguration();
        this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
    }
}

2.setParameters

setParameters 是ParameterHandler的核心方法,負(fù)責(zé)將參數(shù)綁定到 PreparedStatement 中:

@Override
public void setParameters(PreparedStatement ps) {
  ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
  // 獲取SQL中的參數(shù)映射列表(每個(gè)元素對(duì)應(yīng)一個(gè)占位符)
  List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
  if (parameterMappings != null) {
    // 遍歷每個(gè)參數(shù)映射,依次綁定到PreparedStatement
    for (int i = 0; i < parameterMappings.size(); i++) {
      ParameterMapping parameterMapping = parameterMappings.get(i);
      // 忽略輸出參數(shù)(存儲(chǔ)過程場(chǎng)景)
      if (parameterMapping.getMode() != ParameterMode.OUT) {
        Object value;
        String propertyName = parameterMapping.getProperty(); // 參數(shù)名稱(如"id"、"user.name")
        // 獲取參數(shù)值:從原始參數(shù)對(duì)象中解析propertyName對(duì)應(yīng)的 value
        if (boundSql.hasAdditionalParameter(propertyName)) {
          // 從附加參數(shù)中獲取(<foreach>或<bind>標(biāo)簽可以提供額外參數(shù))
          value = boundSql.getAdditionalParameter(propertyName);
        } else if (parameterObject == null) {
          value = null; // 參數(shù)為null時(shí)直接設(shè)為null
        } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
          // 參數(shù)本身就是TypeHandler可以處理的類型
          value = parameterObject;
        } else {
          // 參數(shù)是復(fù)雜對(duì)象,通過反射獲取propertyName對(duì)應(yīng)的屬性值
          MetaObject metaObject = configuration.newMetaObject(parameterObject);
          value = metaObject.getValue(propertyName);
        }
        // 獲取參數(shù)對(duì)應(yīng)的TypeHandler(負(fù)責(zé)Java類型→JDBC類型的轉(zhuǎn)換)
        TypeHandler typeHandler = parameterMapping.getTypeHandler();
        JdbcType jdbcType = parameterMapping.getJdbcType();
        if (value == null && jdbcType == null) {
          jdbcType = configuration.getJdbcTypeForNull();
        }
        try {
          // 調(diào)用TypeHandler的方法,將value綁定到PreparedStatement的第i+1個(gè)占位符
          typeHandler.setParameter(ps, i + 1, value, jdbcType);
        } catch (SQLException e) {
          throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
        }
      }
    }
  }
}

這段代碼的執(zhí)行流程可分為三步:

  1. 解析參數(shù)映射列表(ParameterMapping),每個(gè)元素對(duì)應(yīng) SQL 中的一個(gè)占位符
  2. 根據(jù)參數(shù)名稱從參數(shù)對(duì)象中獲取參數(shù)值(支持復(fù)雜對(duì)象的屬性訪問)
  3. 通過 TypeHandler 將參數(shù)值轉(zhuǎn)換為 JDBC 類型并綁定到 PreparedStatement

AdditionalParameter這個(gè)額外參數(shù)是什么?

  1. foreach標(biāo)簽中的item、index都會(huì)被解析為額外參數(shù);
  2. bind標(biāo)簽,也可以提供額外參數(shù),你可以利用bind標(biāo)簽,使用OGNL表達(dá)式以外創(chuàng)建一個(gè)變量,并將其綁定到當(dāng)前的上下文。

3.TypeHandler

TypeHandler(類型處理器)負(fù)責(zé)Java類型與JDBC類型之間的轉(zhuǎn)換,不只是ParameterHandler處理參數(shù)需要他,ResultSetHandler處理返回結(jié)果時(shí)也需要他。

1.TypeHandler接口定義

通過接口定義就可以看出來,TypeHandler負(fù)責(zé)JAVA類型與JDBC類型互相轉(zhuǎn)換。

public interface TypeHandler<T> {
    void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
    
    T getResult(ResultSet rs, String columnName) throws SQLException;
    
    T getResult(ResultSet rs, int columnIndex) throws SQLException;
    
    T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}

2. 內(nèi)置TypeHandler體系

MyBatis 提供了豐富的內(nèi)置 TypeHandler,這里的例子只是冰山一角,有興趣可以看下源碼,一般情況下,是不需要自己自定義類型轉(zhuǎn)換器的。具體實(shí)現(xiàn)這里不深入了,比較簡(jiǎn)單,模板模式,BaseTypeHandler實(shí)現(xiàn)了一些通用邏輯,子類就是JDBC API的各種調(diào)用。有興趣可以直接看源碼。

類型分類典型實(shí)現(xiàn)類功能說明
基本類型IntegerTypeHandler處理 Integer 與 JDBC INTEGER 轉(zhuǎn)換
字符串類型StringTypeHandler處理 String 與 JDBC VARCHAR 轉(zhuǎn)換
日期類型LocalDateTimeTypeHandler處理 Java 8 日期類型與 JDBC 日期類型轉(zhuǎn)換
枚舉類型EnumTypeHandler處理枚舉的名稱與 JDBC 類型轉(zhuǎn)換
集合 / 數(shù)組類型ArrayTypeHandler處理 Java 數(shù)組與 JDBC ARRAY 類型轉(zhuǎn)換

4. JdbcTypeForNull 的作用

jdbcTypeForNull是 MyBatis中用于處理null值參數(shù)的重要配置,當(dāng)參數(shù)值為 null且未指定具體JDBC 類型時(shí)生效。

其主要作用是解決不同數(shù)據(jù)庫對(duì) null 值處理的兼容性問題,某些數(shù)據(jù)庫,對(duì) null 值的類型非常敏感,需要明確指定 JDBC 類型,比如Oracle,需要設(shè)置為NULL。

可以在xml中配置

<configuration>
    <settings>
        <!-- 設(shè)置null值默認(rèn)的JDBC類型 -->
        <setting name="jdbcTypeForNull" value="NULL"/>
    </settings>
</configuration>

三、小結(jié)

ParameterHandler是MyBatis處理Statement的參數(shù)的核心組件,通過與 TypeHandler協(xié)作,實(shí)現(xiàn)了Java 類型到JDBC類型的靈活轉(zhuǎn)換,支撐了MyBatis對(duì)各種復(fù)雜參數(shù)場(chǎng)景的處理能力。

到此這篇關(guān)于MyBatis ParameterHandler的具體使用的文章就介紹到這了,更多相關(guān)MyBatis ParameterHandler內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot使用Jwt處理跨域認(rèn)證問題的教程詳解

    SpringBoot使用Jwt處理跨域認(rèn)證問題的教程詳解

    這篇文章主要介紹了SpringBoot使用Jwt處理跨域認(rèn)證問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • SpringBoot集成jjwt和使用方式

    SpringBoot集成jjwt和使用方式

    本文詳細(xì)介紹了JWT依賴(以jjwt為例)的引入和使用方法,首先,需要在項(xiàng)目中引入jwt依賴,隨后在Spring的啟動(dòng)類application.yml中進(jìn)行相應(yīng)配置,最后,提供了一份完整的jwt工具類代碼,供讀者直接使用,以上內(nèi)容便是作者的個(gè)人經(jīng)驗(yàn)分享,期望能為讀者提供參考并得到支持
    2024-10-10
  • Java深入淺出講解多線程的概念到使用

    Java深入淺出講解多線程的概念到使用

    哈哈!經(jīng)過一個(gè)階段的學(xué)習(xí),Java基礎(chǔ)知識(shí)學(xué)習(xí)終于到多線程了!Java多線程以及后面互斥鎖的概念都是Java基礎(chǔ)學(xué)習(xí)的難點(diǎn),所以我做了一個(gè)總結(jié),希望對(duì)大家也有幫助
    2022-05-05
  • SpringBoot異步調(diào)用方法實(shí)現(xiàn)場(chǎng)景代碼實(shí)例

    SpringBoot異步調(diào)用方法實(shí)現(xiàn)場(chǎng)景代碼實(shí)例

    這篇文章主要介紹了SpringBoot異步調(diào)用方法實(shí)現(xiàn)場(chǎng)景代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • SpringCloud 如何提取公共配置

    SpringCloud 如何提取公共配置

    這篇文章主要介紹了SpringCloud 提取公共配置的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Mybatis使用foreach批量插入Oracle提示命令未正確結(jié)束方式

    Mybatis使用foreach批量插入Oracle提示命令未正確結(jié)束方式

    文章主要討論了在Oracle和MySQL中使用foreach標(biāo)簽時(shí)的語法差異,以及foreach元素的屬性介紹,包括item、index、collection、open、separator和close等
    2025-11-11
  • springboot使用外置的Servlet容器步驟

    springboot使用外置的Servlet容器步驟

    本文給大家介紹springboot使用外置的Servlet容器的步驟,本文結(jié)合圖文實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2025-07-07
  • Java中Map與對(duì)象之間互相轉(zhuǎn)換的幾種常用方式

    Java中Map與對(duì)象之間互相轉(zhuǎn)換的幾種常用方式

    在Java中將對(duì)象和Map相互轉(zhuǎn)換是常見的操作,可以通過不同的方式實(shí)現(xiàn)這種轉(zhuǎn)換,下面這篇文章主要給大家介紹了關(guān)于Java中Map與對(duì)象之間互相轉(zhuǎn)換的幾種常用方式,需要的朋友可以參考下
    2024-01-01
  • springboot使用Thymeleaf報(bào)錯(cuò)常見的幾種解決方案

    springboot使用Thymeleaf報(bào)錯(cuò)常見的幾種解決方案

    這篇文章主要介紹了springboot使用Thymeleaf報(bào)錯(cuò)常見的幾種解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • java發(fā)送http請(qǐng)求并獲取狀態(tài)碼的簡(jiǎn)單實(shí)例

    java發(fā)送http請(qǐng)求并獲取狀態(tài)碼的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)硪黄猨ava發(fā)送http請(qǐng)求并獲取狀態(tài)碼的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-05-05

最新評(píng)論

长治县| 金溪县| 宿州市| 河西区| 五大连池市| 洱源县| 宁陕县| 繁峙县| 华坪县| 台北市| 辽阳县| 博白县| 芦溪县| 社会| 安龙县| 美姑县| 田阳县| 正镶白旗| 高雄县| 安龙县| 胶州市| 乌恰县| 崇阳县| 昌江| 株洲县| 斗六市| 富阳市| 城市| 申扎县| 苏尼特左旗| 廊坊市| 阿图什市| 资源县| 札达县| 汽车| 门源| 开远市| 勐海县| 富裕县| 无锡市| 滦南县|