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

MyBatis 參數(shù)映射機(jī)制實(shí)踐記錄

 更新時(shí)間:2024年12月21日 10:25:56   作者:山高自有客行路  
這篇文章主要介紹了MyBatis 參數(shù)映射機(jī)制實(shí)踐記錄,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

核心組件

1. SqlSessionFactory

MyBatis 的入口點(diǎn)是 SqlSessionFactory,它負(fù)責(zé)創(chuàng)建 SqlSession 實(shí)例。每個(gè) SqlSession 都代表一個(gè)與數(shù)據(jù)庫(kù)的會(huì)話,并且在該會(huì)話中可以執(zhí)行 SQL 操作。

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession session = sqlSessionFactory.openSession()) {
    // 使用 session 進(jìn)行 CRUD 操作
}

2. SqlSession

SqlSession 提供了用于執(zhí)行語(yǔ)句、提交或回滾事務(wù)以及獲取映射器實(shí)例的方法。它是線程不安全的,因此應(yīng)該在方法作用域內(nèi)使用(即每次調(diào)用時(shí)創(chuàng)建和關(guān)閉)。

UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.getUserById(100);

3. Mapper Interface

Mapper 接口定義了與數(shù)據(jù)庫(kù)交互的方法,這些方法通常對(duì)應(yīng)于 SQL 語(yǔ)句。MyBatis 通過(guò)動(dòng)態(tài)代理的方式實(shí)現(xiàn)了這些接口,使得你可以在代碼中像調(diào)用普通 Java 方法一樣調(diào)用它們。

public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(@Param("id") int id);
}

參數(shù)處理的具體流程

ParameterHandler 和 TypeHandler

  • ParameterHandler:如前所述,這是 MyBatis 處理 SQL 語(yǔ)句參數(shù)的核心組件。它根據(jù) SQL 語(yǔ)句中的占位符設(shè)置相應(yīng)的值。
  • TypeHandler:用于將 Java 類型轉(zhuǎn)換為 JDBC 類型,反之亦然。你可以注冊(cè)自定義的 TypeHandler 來(lái)支持特定的數(shù)據(jù)類型。

內(nèi)部工作原理

  • 解析 SQL 語(yǔ)句:當(dāng) MyBatis 解析 XML 或注解定義的 SQL 語(yǔ)句時(shí),它會(huì)識(shí)別出所有的 #{}${} 占位符,并記錄下它們的位置。
  • 創(chuàng)建 ParameterHandler:對(duì)于每一個(gè)需要執(zhí)行的 SQL 語(yǔ)句,MyBatis 都會(huì)創(chuàng)建一個(gè) ParameterHandler 實(shí)例。這個(gè)實(shí)例包含了如何填充 SQL 語(yǔ)句中占位符的信息。
  • 設(shè)置參數(shù)值ParameterHandler 會(huì)遍歷所有占位符,并根據(jù)傳入的參數(shù)對(duì)象(可以是簡(jiǎn)單類型、Java Bean、Map 或集合)來(lái)設(shè)置對(duì)應(yīng)的值。如果參數(shù)是一個(gè)復(fù)雜類型,MyBatis 會(huì)遞歸地訪問(wèn)其屬性,直到找到匹配的值。
  • 應(yīng)用 TypeHandler:對(duì)于每一個(gè)參數(shù)值,MyBatis 會(huì)查找并應(yīng)用適當(dāng)?shù)?TypeHandler 來(lái)確保正確的數(shù)據(jù)類型轉(zhuǎn)換。
  • 執(zhí)行 SQL:最后,帶有正確參數(shù)值的 SQL 語(yǔ)句被發(fā)送到數(shù)據(jù)庫(kù)進(jìn)行執(zhí)行。

參數(shù)映射的實(shí)現(xiàn)細(xì)節(jié)

單個(gè)參數(shù)

對(duì)于單個(gè)參數(shù)的情況,MyBatis 可以直接使用參數(shù)名或默認(rèn)名稱(如 param1)。如果你希望提高代碼的可讀性,建議總是使用 @Param 注解明確指定參數(shù)名。

@Select("SELECT * FROM users WHERE id = #{userId}")
User getUserById(@Param("userId") int id);

多個(gè)參數(shù)

當(dāng)有多個(gè)參數(shù)時(shí),使用 @Param 注解是非常重要的,因?yàn)樗梢宰?MyBatis 知道每個(gè)參數(shù)的名字,從而在 SQL 中通過(guò)名字引用它們。在springBoot的1.x版本/單獨(dú)使用mybatis(使用@Param注解來(lái)指定SQL語(yǔ)句中的參數(shù)名),因?yàn)樵诰幾g時(shí),生成的字節(jié)碼文件當(dāng)中,不會(huì)保留Mapper接口中方法的形參名稱,而是使用var1、var2、...這樣的形參名字,此時(shí)要獲取參數(shù)值時(shí),就要通過(guò)@Param注解來(lái)指定SQL語(yǔ)句中的參數(shù)名。

@Select("SELECT * FROM orders WHERE user_id = #{userId} AND status = #{status}")
List<Order> findOrdersByUserIdAndStatus(@Param("userId") int userId, @Param("status") String status);

Java Bean 或 Map 參數(shù)

對(duì)于復(fù)雜的參數(shù)類型,如 Java Bean 或 Map,MyBatis 會(huì)自動(dòng)解析對(duì)象的屬性或 Map 的鍵值對(duì),允許你在 SQL 中通過(guò)屬性名或鍵名直接引用這些值。

@Select("SELECT * FROM products WHERE category = #{category} AND price < #{maxPrice}")
List<Product> findProducts(ProductCriteria criteria);

數(shù)組和集合參數(shù)

數(shù)組和集合類型的參數(shù)可以通過(guò) <foreach> 標(biāo)簽來(lái)處理,這使得你可以遍歷集合并在 SQL 中插入多值條件。

<select id="getCategoriesByIds" resultType="Category">
  SELECT * FROM categories
  WHERE id IN
  <foreach item="id" collection="ids" open="(" separator="," close=")">
    #{id}
  </foreach>
</select>

動(dòng)態(tài) SQL

MyBatis 支持動(dòng)態(tài) SQL,允許根據(jù)運(yùn)行時(shí)條件構(gòu)造 SQL 語(yǔ)句。這包括使用 <if>, <choose>, <when>, <otherwise>, <trim>, <where>, <set>, 和 <foreach> 標(biāo)簽。

<select id="findActiveBlogWithTitleLike" resultType="Blog">
  SELECT * FROM BLOG
  WHERE state = 'ACTIVE'
  <if test="title != null">
    AND title like #{title}
  </if>
</select>

高級(jí)特性

自定義 TypeHandler

有時(shí)你需要自定義數(shù)據(jù)類型之間的轉(zhuǎn)換邏輯。例如,處理枚舉類型或自定義日期格式。你可以通過(guò)實(shí)現(xiàn) TypeHandler 接口并注冊(cè)到 MyBatis 中來(lái)完成這一需求。

public class EnumTypeHandler<E extends Enum<E>> implements TypeHandler<E> {
    private final Class<E> type;
    public EnumTypeHandler(Class<E> type) {
        if (type == null) throw new IllegalArgumentException("Type argument cannot be null");
        this.type = type;
    }
    @Override
    public void setParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null) {
            ps.setNull(i, Types.VARCHAR);
        } else {
            ps.setString(i, parameter.name());
        }
    }
    @Override
    public E getResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getString(columnName) == null ? null : Enum.valueOf(type, rs.getString(columnName));
    }
    @Override
    public E getResult(ResultSet rs, int columnIndex) throws SQLException {
        return rs.getString(columnIndex) == null ? null : Enum.valueOf(type, rs.getString(columnIndex));
    }
    @Override
    public E getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cs.getString(columnIndex) == null ? null : Enum.valueOf(type, cs.getString(columnIndex));
    }
}

然后在 MyBatis 配置文件中注冊(cè)這個(gè) TypeHandler

<typeHandlers>
  <typeHandler javaType="com.example.MyEnum" handler="com.example.EnumTypeHandler"/>
</typeHandlers>

插件機(jī)制

MyBatis 還提供了插件機(jī)制,允許開發(fā)者攔截和修改 MyBatis 的內(nèi)部行為,如攔截 SQL 執(zhí)行、結(jié)果映射等。這對(duì)于性能監(jiān)控、日志記錄等功能非常有用。

@Intercepts({@Signature(type= Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class ExamplePlugin implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 在這里添加你的邏輯
        return invocation.proceed();
    }
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
    @Override
    public void setProperties(Properties properties) {
        // 設(shè)置插件屬性
    }
}

性能優(yōu)化和最佳實(shí)踐

1. 批量操作

對(duì)于大批量的數(shù)據(jù)操作,考慮使用批量插入、更新或刪除,以減少數(shù)據(jù)庫(kù)交互次數(shù)。可以使用 <foreach> 標(biāo)簽結(jié)合批處理功能。

<insert id="batchInsertUsers">
  INSERT INTO users (name, email)
  VALUES
  <foreach collection="list" item="user" separator=",">
    (#{user.name}, #{user.email})
  </foreach>
</insert>

2. 緩存策略

合理配置一級(jí)緩存和二級(jí)緩存,避免不必要的重復(fù)查詢。一級(jí)緩存是基于 SqlSession 的,而二級(jí)緩存可以在多個(gè) SqlSession 之間共享。

<mapper namespace="com.example.UserMapper">
  <cache/>
  <!-- 其他映射語(yǔ)句 -->
</mapper>

3. 減少不必要的參數(shù)傳遞

只傳遞必要的參數(shù),以減少內(nèi)存消耗和提高性能。對(duì)于復(fù)雜對(duì)象,盡量只傳遞需要的字段。

4. 文檔化和一致性

保持代碼風(fēng)格一致,并為接口和方法添加適當(dāng)?shù)奈臋n說(shuō)明,有助于團(tuán)隊(duì)協(xié)作和維護(hù)。

錯(cuò)誤處理與調(diào)試

1. SQL 日志輸出

開啟 SQL 日志輸出可以幫助你調(diào)試和優(yōu)化 SQL 語(yǔ)句。MyBatis 支持多種日志框架,如 Log4j、SLF4J 等。

# log4j.properties
log4j.logger.org.apache.ibatis=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

2. 異常處理

確保在捕獲異常時(shí)提供足夠的信息,以便快速定位問(wèn)題。可以使用 AOP 或者手動(dòng)捕獲異常,并記錄詳細(xì)的錯(cuò)誤信息。

try {
    // 數(shù)據(jù)庫(kù)操作
} catch (PersistenceException e) {
    logger.error("Database operation failed", e);
    throw e;
}

到此這篇關(guān)于MyBatis 參數(shù)映射機(jī)制的文章就介紹到這了,更多相關(guān)MyBatis 參數(shù)映射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 集合實(shí)現(xiàn)分頁(yè)的方法(業(yè)務(wù)代碼實(shí)現(xiàn)分頁(yè))

    Java 集合實(shí)現(xiàn)分頁(yè)的方法(業(yè)務(wù)代碼實(shí)現(xiàn)分頁(yè))

    在Java開發(fā)中,有些場(chǎng)景比較復(fù)雜,受限制,不好在sql查詢層面實(shí)現(xiàn)分頁(yè),需要在查詢的list結(jié)果后,將list分頁(yè)返回,如何實(shí)現(xiàn)呢,帶著這個(gè)問(wèn)題一起通過(guò)本文學(xué)習(xí)吧
    2025-02-02
  • 關(guān)于Mybatis和JDBC的使用及區(qū)別

    關(guān)于Mybatis和JDBC的使用及區(qū)別

    這篇文章主要介紹了關(guān)于Mybatis和JDBC的使用及區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • 聊聊springboot靜態(tài)資源加載的規(guī)則

    聊聊springboot靜態(tài)資源加載的規(guī)則

    這篇文章主要介紹了springboot靜態(tài)資源加載的規(guī)則,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java中的Fork/Join框架使用詳解

    Java中的Fork/Join框架使用詳解

    這篇文章主要介紹了Java中的Fork/Join框架使用詳解,Fork/Join?框架:就是在必要的情況下,將一個(gè)大任務(wù),進(jìn)行<BR>拆分(fork)成若干個(gè)小任務(wù)(拆到不可再拆時(shí)),再將一個(gè)個(gè)<BR>的小任務(wù)運(yùn)算的結(jié)果進(jìn)行?join?匯總,需要的朋友可以參考下
    2024-01-01
  • java讀取文件顯示進(jìn)度條的實(shí)現(xiàn)方法

    java讀取文件顯示進(jìn)度條的實(shí)現(xiàn)方法

    當(dāng)讀取一個(gè)大文件時(shí),一時(shí)半會(huì)兒無(wú)法看到讀取結(jié)果,就需要顯示一個(gè)進(jìn)度條,是程序員明白已經(jīng)讀了多少文件,可以估算讀取還需要多少時(shí)間,下面的代碼可以實(shí)現(xiàn)這個(gè)功能
    2014-01-01
  • Java 使用openoffice進(jìn)行word轉(zhuǎn)換為pdf的方法步驟

    Java 使用openoffice進(jìn)行word轉(zhuǎn)換為pdf的方法步驟

    這篇文章主要介紹了Java 使用openoffice進(jìn)行word轉(zhuǎn)換為pdf的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java JDBC數(shù)據(jù)庫(kù)連接失敗的7種常見原因及解決方案

    Java JDBC數(shù)據(jù)庫(kù)連接失敗的7種常見原因及解決方案

    Java JDBC(Java Database Connectivity)是Java平臺(tái)中用于執(zhí)行SQL語(yǔ)句的標(biāo)準(zhǔn)API,它為開發(fā)者提供了與各種關(guān)系型數(shù)據(jù)庫(kù)進(jìn)行交互的能力,本文為大家介紹了Java JDBC數(shù)據(jù)庫(kù)連接失敗的7種常見原因及解決方案,需要的朋友可以參考下
    2025-11-11
  • JAVA基礎(chǔ)之?dāng)?shù)組和集合區(qū)別對(duì)比分析

    JAVA基礎(chǔ)之?dāng)?shù)組和集合區(qū)別對(duì)比分析

    文章主要介紹了Java中數(shù)組和集合的基本概念、使用方法以及它們之間的區(qū)別,文章還探討了不可變集合的創(chuàng)建方式及其線程安全和不可篡改的優(yōu)勢(shì),感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • Java中的FutureTask源碼解析

    Java中的FutureTask源碼解析

    這篇文章主要介紹了Java中的FutureTask源碼解析,FutureTask是一個(gè)可取消的異步計(jì)算,這個(gè)類是Future的實(shí)現(xiàn)類,有開始和取消一個(gè)計(jì)算的方法,如果一個(gè)計(jì)算已經(jīng)完成可以查看結(jié)果,需要的朋友可以參考下
    2023-12-12
  • Java基礎(chǔ)第四篇 封裝與接口

    Java基礎(chǔ)第四篇 封裝與接口

    本文將對(duì)介紹Java 的封裝與接口進(jìn)行介紹,將要封裝(encapsulation)對(duì)象的成員(成員包括數(shù)據(jù)成員和方法),從而只允許從外部調(diào)用部分的成員。利用封裝,我們可以提高對(duì)象的易用性和安全性。想具體了解的小伙伴請(qǐng)參考下面文章的內(nèi)容
    2021-09-09

最新評(píng)論

徐州市| 淳安县| 龙里县| 皋兰县| 曲松县| 深州市| 武胜县| 新安县| 东丽区| 淮安市| 全椒县| 玛多县| 华容县| 旬邑县| 三明市| 基隆市| 玉屏| 迁西县| 北海市| 耿马| 潜山县| 无为县| 称多县| 大兴区| 大英县| 西畴县| 大厂| 阿拉善右旗| 和平县| 万山特区| 加查县| 阳西县| 遂溪县| 屏山县| 禄劝| 嘉祥县| 普宁市| 南宁市| 鹤壁市| 荆门市| 福州市|