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

MyBatis 延遲加載深度解密:從使用方式到底層動態(tài)代理原理解析

 更新時間:2026年06月03日 09:16:16   作者:Mahir08  
本文詳細解析MyBatis延遲加載機制,涵蓋定義、配置方式、底層原理、執(zhí)行流程及常見坑點,助你掌握延遲加載優(yōu)化數(shù)據(jù)庫查詢與內(nèi)存使用技巧,應對面試與實際項目挑戰(zhàn),感興趣的朋友一起看看吧

作為 Java 后端開發(fā)者,我們在使用 MyBatis 處理關聯(lián)查詢時,經(jīng)常會遇到一個問題:查詢一個主對象時,會同時查詢出所有關聯(lián)對象,即使這些關聯(lián)對象我們根本用不到。這不僅會導致不必要的數(shù)據(jù)庫查詢,還會占用大量內(nèi)存,影響系統(tǒng)性能。

 延遲加載(懶加載) 正是解決這個問題的最佳方案。它允許我們在真正需要使用關聯(lián)對象時,才去執(zhí)行 SQL 查詢加載數(shù)據(jù),而不是一次性加載所有關聯(lián)數(shù)據(jù)。

面試時,MyBatis 延遲加載更是高頻考點,面試官會層層深挖:

  • MyBatis 支持延遲加載嗎?哪些關聯(lián)查詢支持延遲加載?
  • 延遲加載的底層原理是什么?基于什么設計模式?
  • lazyLoadingEnabledaggressiveLazyLoading有什么區(qū)別?
  • 為什么嵌套結果不支持延遲加載?
  • 延遲加載有哪些常見坑點?如何避免?

這篇文章,我們就從基礎使用→配置方式→底層原理→執(zhí)行流程→坑點與最佳實踐五個維度,徹底搞懂 MyBatis 延遲加載。不僅會講清楚理論,更會結合源碼和實戰(zhàn)案例,讓你看完既能輕松應對面試,又能在實際項目中正確使用延遲加載。

一、先搞懂:什么是延遲加載?

1. 延遲加載的定義

延遲加載(Lazy Loading),也叫懶加載,是一種按需加載的設計思想。它的核心是:只有當真正需要使用某個對象時,才會去加載這個對象的數(shù)據(jù)。

在 MyBatis 中,延遲加載主要用于處理關聯(lián)查詢(一對一、一對多、多對多)。當我們查詢主對象時,不會立即查詢關聯(lián)對象的數(shù)據(jù),而是為關聯(lián)對象生成一個代理對象。只有當我們調(diào)用關聯(lián)對象的 getter 方法時,才會觸發(fā)真正的 SQL 查詢,加載關聯(lián)對象的數(shù)據(jù)。

2. 為什么需要延遲加載?

我們用一個最常見的場景來對比:查詢用戶信息,同時查詢用戶的訂單信息。

不使用延遲加載(立即加載)

-- 一次性查詢用戶和所有訂單
SELECT u.*, o.* FROM user u LEFT JOIN order o ON u.id = o.user_id WHERE u.id = 1

這種方式的問題:

  • 如果用戶有 1000 個訂單,會一次性查詢出所有訂單數(shù)據(jù)
  • 如果我們只需要用戶的基本信息,不需要訂單信息,這些訂單查詢就是完全浪費的
  • 數(shù)據(jù)量越大,性能損耗越嚴重,甚至會導致內(nèi)存溢出

使用延遲加載

-- 第一步:只查詢用戶基本信息
SELECT * FROM user WHERE id = 1
-- 第二步:只有當調(diào)用user.getOrders()時,才執(zhí)行訂單查詢
SELECT * FROM order WHERE user_id = 1

這種方式的優(yōu)勢:

  • 只查詢需要的數(shù)據(jù),減少不必要的數(shù)據(jù)庫查詢
  • 降低內(nèi)存占用,提高系統(tǒng)性能
  • 對于關聯(lián)對象不常訪問的場景,性能提升非常明顯

3. MyBatis 對延遲加載的支持

MyBatis 是支持延遲加載的,但只支持嵌套查詢(也叫子查詢)的延遲加載,不支持嵌套結果的延遲加載。

這是一個非常重要的結論,也是面試最??嫉狞c。很多人以為所有關聯(lián)查詢都支持延遲加載,其實不然。

關聯(lián)查詢方式是否支持延遲加載原理
嵌套查詢(select屬性)?先查詢主表,關聯(lián)對象用代理對象代替,需要時再執(zhí)行子查詢
嵌套結果(resultMap嵌套)?一次性執(zhí)行多表聯(lián)查,將結果映射到主對象和關聯(lián)對象

二、延遲加載的配置方式

MyBatis 提供了兩種配置延遲加載的方式:全局配置局部配置。局部配置的優(yōu)先級高于全局配置。

1. 全局配置

mybatis-config.xml文件中配置全局延遲加載參數(shù):

<settings>
    <!-- 開啟全局延遲加載,默認值為false -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 關閉侵入式延遲加載,默認值為false(MyBatis 3.4.1及以后) -->
    <setting name="aggressiveLazyLoading" value="false"/>
    <!-- 指定延遲加載使用的動態(tài)代理工廠,默認是cglib -->
    <setting name="proxyFactory" value="cglib"/>
</settings>

兩個核心參數(shù)詳解

  • lazyLoadingEnabled:全局延遲加載開關。設置為true時,所有關聯(lián)查詢都會默認使用延遲加載;設置為false時,所有關聯(lián)查詢都會立即加載。
  • aggressiveLazyLoading:侵入式延遲加載開關。這個參數(shù)非常重要,很多人搞不清它的作用:
    • 當設置為true時:調(diào)用主對象的任何方法(如toString()、hashCode()、equals())都會觸發(fā)所有延遲加載屬性的加載
    • 當設置為false時:只有調(diào)用對應延遲加載屬性的 getter 方法時,才會觸發(fā)該屬性的加載

注意:MyBatis 3.4.1 及以后版本,aggressiveLazyLoading的默認值已經(jīng)改為false,這是更合理的默認行為。在這之前的版本,默認值是true

2. 局部配置

如果不想全局開啟延遲加載,可以在單個關聯(lián)查詢上通過fetchType屬性單獨配置:

<resultMap id="userResultMap" type="User">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <!-- 一對一關聯(lián),開啟延遲加載 -->
    <association property="dept" column="dept_id" 
                 select="com.example.mapper.DeptMapper.getDeptById"
                 fetchType="lazy"/>
    <!-- 一對多關聯(lián),關閉延遲加載(立即加載) -->
    <collection property="orders" column="id"
                select="com.example.mapper.OrderMapper.getOrdersByUserId"
                fetchType="eager"/>
</resultMap>

fetchType屬性有兩個可選值:

  • lazy:延遲加載
  • eager:立即加載

局部配置的優(yōu)先級高于全局配置。即使全局關閉了延遲加載,局部設置fetchType="lazy"仍然會生效。

三、延遲加載的底層原理:動態(tài)代理

MyBatis 延遲加載的核心原理是動態(tài)代理。當 MyBatis 發(fā)現(xiàn)某個關聯(lián)屬性需要延遲加載時,不會直接實例化這個屬性,而是為它生成一個代理對象。當調(diào)用這個代理對象的 getter 方法時,才會觸發(fā)真正的 SQL 查詢,加載真實數(shù)據(jù)。

1. 動態(tài)代理的選擇

MyBatis 提供了兩種動態(tài)代理實現(xiàn),通過proxyFactory參數(shù)指定:

  • CGLIB 動態(tài)代理:默認實現(xiàn),基于繼承實現(xiàn),可以代理任何非 final 類
  • Javassist 動態(tài)代理:基于字節(jié)碼生成實現(xiàn),性能比 CGLIB 略高

為什么默認使用 CGLIB? 因為我們要代理的是實體類,而不是接口。JDK 動態(tài)代理只能代理接口,無法代理普通類,所以 MyBatis 選擇了 CGLIB 和 Javassist 這兩種可以代理類的動態(tài)代理實現(xiàn)。

2. 核心接口:ProxyFactory

MyBatis 定義了ProxyFactory接口,用于生成代理對象:

public interface ProxyFactory {
    // 為目標對象生成代理
    Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
}

默認實現(xiàn)是CglibProxyFactory,它使用 CGLIB 的Enhancer類生成代理對象。

3. 代理對象的生成過程

當 MyBatis 處理結果集時,如果發(fā)現(xiàn)某個關聯(lián)屬性配置了延遲加載,會執(zhí)行以下步驟:

  1. 不直接實例化關聯(lián)對象
  2. 創(chuàng)建一個ResultLoader對象,保存關聯(lián)查詢的 SQL 語句、參數(shù)和 Mapper 信息
  3. 調(diào)用ProxyFactory.createProxy()方法,為關聯(lián)對象生成一個代理對象
  4. 將代理對象設置到主對象的對應屬性上

4. 代理對象的執(zhí)行流程

當我們調(diào)用代理對象的 getter 方法時,會觸發(fā)代理對象的攔截器方法,執(zhí)行以下流程:

  1. 檢查關聯(lián)對象是否已經(jīng)加載
  2. 如果沒有加載,調(diào)用ResultLoader.loadResult()方法執(zhí)行 SQL 查詢
  3. 將查詢得到的真實對象替換代理對象
  4. 返回真實對象的對應方法結果

核心源碼(CglibProxyFactory)

public static class CglibMethodInterceptor implements MethodInterceptor {
    private final Object target;
    private final ResultLoaderMap lazyLoader;
    private final Configuration configuration;
    private final ObjectFactory objectFactory;
    private final List<Class<?>> constructorArgTypes;
    private final List<Object> constructorArgs;
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        // 檢查是否是延遲加載的屬性的getter方法
        if (lazyLoader != null && !lazyLoader.isLoaded()) {
            // 如果是getter方法,觸發(fā)加載
            if (isGetter(method)) {
                lazyLoader.load();
            }
            // 如果aggressiveLazyLoading為true,任何方法調(diào)用都觸發(fā)所有延遲加載
            else if (configuration.isAggressiveLazyLoading()) {
                lazyLoader.loadAll();
            }
        }
        // 執(zhí)行真實對象的方法
        return methodProxy.invoke(target, args);
    }
}

四、延遲加載的完整執(zhí)行流程

我們以查詢用戶及其訂單為例,完整拆解延遲加載的執(zhí)行流程:

步驟 1:執(zhí)行主查詢

User user = userMapper.getUserById(1L);

MyBatis 執(zhí)行主查詢 SQL:

SELECT * FROM user WHERE id = 1

步驟 2:結果集映射

DefaultResultSetHandler處理結果集,映射 User 對象的基本屬性。當處理到orders屬性時:

  1. 發(fā)現(xiàn)orders配置了延遲加載
  2. 創(chuàng)建ResultLoader對象,保存訂單查詢的信息:
    • Mapper 方法:com.example.mapper.OrderMapper.getOrdersByUserId
    • 參數(shù):1(用戶 ID)
  3. 調(diào)用CglibProxyFactory生成List<Order>的代理對象
  4. 將代理對象設置到user.orders屬性上

此時,user對象已經(jīng)返回,但user.orders是一個代理對象,還沒有執(zhí)行訂單查詢。

步驟 3:調(diào)用 getter 方法觸發(fā)加載

// 此時才會觸發(fā)訂單查詢
List<Order> orders = user.getOrders();

代理對象的intercept方法被調(diào)用:

  1. 檢查orders是否已經(jīng)加載,發(fā)現(xiàn)沒有加載
  2. 調(diào)用ResultLoader.loadResult()方法
  3. 從 SqlSession 中獲取OrderMapper,執(zhí)行getOrdersByUserId(1L)
  4. 執(zhí)行訂單查詢 SQL:
    SELECT * FROM order WHERE user_id = 1
  5. 將查詢得到的真實List<Order>對象替換代理對象
  6. 返回真實的訂單列表

步驟 4:后續(xù)調(diào)用直接返回真實對象

// 第二次調(diào)用,直接返回真實對象,不會再執(zhí)行SQL
List<Order> orders2 = user.getOrders();

此時,orders已經(jīng)加載完成,后續(xù)調(diào)用會直接返回真實對象,不會再執(zhí)行 SQL 查詢。

五、兩種延遲加載模式

根據(jù)aggressiveLazyLoading參數(shù)的不同,MyBatis 有兩種延遲加載模式:

1. 侵入式延遲加載(aggressiveLazyLoading = true)

當調(diào)用主對象的任何方法時,都會觸發(fā)所有延遲加載屬性的加載。

示例

User user = userMapper.getUserById(1L);
// 調(diào)用toString()方法,會觸發(fā)orders和dept兩個延遲加載屬性的加載
System.out.println(user.toString());

這種模式的缺點很明顯:即使我們不需要關聯(lián)對象,只要調(diào)用了主對象的任何方法,都會觸發(fā)所有關聯(lián)查詢,失去了延遲加載的意義。

2. 按需延遲加載(aggressiveLazyLoading = false)

只有調(diào)用對應延遲加載屬性的 getter 方法時,才會觸發(fā)該屬性的加載。

示例

User user = userMapper.getUserById(1L);
// 調(diào)用toString()方法,不會觸發(fā)任何延遲加載
System.out.println(user.toString());
// 只有調(diào)用getOrders()時,才會觸發(fā)訂單查詢
List<Order> orders = user.getOrders();
// 調(diào)用getDept()時,才會觸發(fā)部門查詢
Dept dept = user.getDept();

這是推薦的模式,也是 MyBatis 3.4.1 及以后的默認模式。它真正實現(xiàn)了按需加載,只有在需要的時候才會執(zhí)行查詢。

六、常見坑點與避坑指南

1. 坑 1:嵌套結果不支持延遲加載

問題:很多人以為所有關聯(lián)查詢都支持延遲加載,其實只有嵌套查詢(select屬性)支持,嵌套結果不支持。

錯誤示例

<!-- 嵌套結果,不支持延遲加載,會一次性查詢所有數(shù)據(jù) -->
<resultMap id="userResultMap" type="User">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <collection property="orders" ofType="Order">
        <id column="order_id" property="id"/>
        <result column="order_no" property="orderNo"/>
    </collection>
</resultMap>
<select id="getUserById" resultMap="userResultMap">
    SELECT u.*, o.id as order_id, o.order_no 
    FROM user u LEFT JOIN order o ON u.id = o.user_id 
    WHERE u.id = #{id}
</select>

原因:嵌套結果是通過多表聯(lián)查一次性獲取所有數(shù)據(jù),然后在內(nèi)存中進行結果映射,無法實現(xiàn)按需加載。

2. 坑 2:Session 關閉后訪問延遲加載屬性

問題:如果在 SqlSession 關閉后訪問延遲加載的屬性,會拋出LazyInitializationException異常。

錯誤示例

SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(1L);
sqlSession.close(); // 關閉SqlSession
// 此時訪問延遲加載屬性,會拋出異常
List<Order> orders = user.getOrders();

原因:延遲加載需要使用 SqlSession 來執(zhí)行查詢。如果 SqlSession 已經(jīng)關閉,就無法執(zhí)行 SQL 查詢了。

解決方案

  • 在 SqlSession 關閉前訪問所有需要的延遲加載屬性
  • 使用 Spring 整合 MyBatis,Spring 會自動管理 SqlSession 的生命周期,不會出現(xiàn)這個問題
  • 關閉延遲加載,使用立即加載

3. 坑 3:實體類是 final 的

問題:如果實體類是 final 的,CGLIB 無法生成代理對象,導致延遲加載失效。

錯誤示例

// final類,無法被CGLIB代理
public final class User {
    private Long id;
    private String name;
    private List<Order> orders;
    // getter和setter
}

原因:CGLIB 動態(tài)代理是基于繼承實現(xiàn)的,無法繼承 final 類。

解決方案:去掉實體類的 final 修飾符。

4. 坑 4:在 equals、hashCode、toString 中訪問延遲加載屬性

問題:如果在實體類的equals()、hashCode()toString()方法中訪問了延遲加載的屬性,會觸發(fā)不必要的查詢。

錯誤示例

public class User {
    private Long id;
    private String name;
    private List<Order> orders;
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", orders=" + orders + // 訪問延遲加載屬性
                '}';
    }
}

原因:當調(diào)用user.toString()時,會訪問orders屬性,觸發(fā)延遲加載,執(zhí)行不必要的 SQL 查詢。

解決方案:在equals()hashCode()toString()方法中,只包含基本屬性,不要包含延遲加載的關聯(lián)屬性。

5. 坑 5:N+1 查詢問題

問題:延遲加載本質上就是 N+1 查詢問題。如果查詢了 100 個用戶,然后每個用戶都調(diào)用getOrders(),會執(zhí)行 1+100=101 次 SQL 查詢。

原因:先執(zhí)行 1 次主查詢獲取所有用戶,然后每個用戶執(zhí)行 1 次訂單查詢。

解決方案

  • 如果需要訪問所有用戶的訂單,使用嵌套結果的一次性查詢
  • 如果只有少數(shù)用戶需要訪問訂單,使用延遲加載
  • 使用批量查詢優(yōu)化,減少 SQL 查詢次數(shù)

七、最佳實踐

  1. 合理使用延遲加載:只在關聯(lián)對象不常訪問的場景下使用延遲加載。如果經(jīng)常訪問關聯(lián)對象,使用嵌套結果的一次性查詢性能更好。
  2. 關閉侵入式延遲加載:將aggressiveLazyLoading設置為false,實現(xiàn)真正的按需加載。
  3. 優(yōu)先使用局部配置:不要全局開啟延遲加載,而是在需要的關聯(lián)查詢上單獨使用fetchType="lazy"配置,避免不必要的延遲加載。
  4. 避免在 Session 關閉后訪問延遲加載屬性:在 Spring 整合 MyBatis 的環(huán)境中,這個問題會自動解決;在原生 MyBatis 環(huán)境中,要確保在 Session 關閉前訪問所有需要的屬性。
  5. 實體類不要加 final 修飾符:避免 CGLIB 無法生成代理對象。
  6. 不要在 equals、hashCode、toString 中訪問延遲加載屬性:避免觸發(fā)不必要的查詢。
  7. 監(jiān)控 SQL 執(zhí)行:在開發(fā)環(huán)境中開啟 SQL 日志,檢查是否有不必要的延遲加載查詢。

八、高頻面試題解答

  • 問:MyBatis 支持延遲加載嗎?原理是什么? 答:MyBatis 支持延遲加載,但只支持嵌套查詢的延遲加載。它的底層原理是動態(tài)代理:當發(fā)現(xiàn)某個關聯(lián)屬性需要延遲加載時,MyBatis 會為該屬性生成一個代理對象。當調(diào)用代理對象的 getter 方法時,才會觸發(fā)真正的 SQL 查詢,加載真實數(shù)據(jù)。
  • 問:lazyLoadingEnabledaggressiveLazyLoading有什么區(qū)別? 答:lazyLoadingEnabled是全局延遲加載開關,控制是否開啟延遲加載;aggressiveLazyLoading是侵入式延遲加載開關,控制何時觸發(fā)延遲加載。當aggressiveLazyLoading為 true 時,調(diào)用主對象的任何方法都會觸發(fā)所有延遲加載屬性的加載;為 false 時,只有調(diào)用對應屬性的 getter 方法才會觸發(fā)加載。
  • 問:為什么嵌套結果不支持延遲加載? 答:嵌套結果是通過多表聯(lián)查一次性獲取所有數(shù)據(jù),然后在內(nèi)存中進行結果映射。它在查詢時已經(jīng)獲取了所有關聯(lián)數(shù)據(jù),無法實現(xiàn)按需加載。只有嵌套查詢是先查詢主表,關聯(lián)數(shù)據(jù)在需要時再單獨查詢,所以支持延遲加載。
  • 問:MyBatis 使用什么動態(tài)代理實現(xiàn)延遲加載?為什么? 答:MyBatis 默認使用 CGLIB 動態(tài)代理,也支持 Javassist 動態(tài)代理。因為 JDK 動態(tài)代理只能代理接口,而我們要代理的是實體類,所以不能使用 JDK 動態(tài)代理。CGLIB 和 Javassist 都是基于字節(jié)碼生成的動態(tài)代理,可以代理普通類。
  • 問:延遲加載有什么優(yōu)缺點? 答:優(yōu)點是按需加載,減少不必要的數(shù)據(jù)庫查詢,降低內(nèi)存占用,提高系統(tǒng)性能;缺點是會產(chǎn)生 N+1 查詢問題,并且在 Session 關閉后無法訪問延遲加載屬性。
  • 問:延遲加載的對象在 Session 關閉后為什么不能使用? 答:因為延遲加載需要使用 SqlSession 來執(zhí)行 SQL 查詢。如果 SqlSession 已經(jīng)關閉,就無法獲取數(shù)據(jù)庫連接,也就無法執(zhí)行查詢了,會拋出LazyInitializationException異常。
  • 問:如何解決延遲加載的 N+1 問題? 答:如果需要訪問所有關聯(lián)對象,使用嵌套結果的一次性查詢;如果只有少數(shù)對象需要訪問關聯(lián)對象,使用延遲加載;也可以使用批量查詢優(yōu)化,減少 SQL 查詢次數(shù)。

九、總結

MyBatis 延遲加載是一個非常實用的性能優(yōu)化特性,它通過動態(tài)代理實現(xiàn)了按需加載,減少了不必要的數(shù)據(jù)庫查詢和內(nèi)存占用。

回顧一下全文的核心內(nèi)容:

  • MyBatis 只支持嵌套查詢的延遲加載,不支持嵌套結果的延遲加載
  • 延遲加載的底層原理是動態(tài)代理,默認使用 CGLIB 實現(xiàn)
  • 兩個核心參數(shù):lazyLoadingEnabled控制是否開啟延遲加載,aggressiveLazyLoading控制何時觸發(fā)加載
  • 延遲加載會產(chǎn)生 N+1 查詢問題,需要根據(jù)場景合理使用
  • 常見坑點包括 Session 關閉后訪問、實體類是 final 的、在 toString 中訪問延遲加載屬性等

理解了延遲加載的原理和坑點,你就能在實際項目中正確使用延遲加載,提高系統(tǒng)性能,同時避免常見的問題。

到此這篇關于MyBatis 延遲加載深度解密:從使用方式到底層動態(tài)代理原理解析的文章就介紹到這了,更多相關MyBatis 延遲加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Mybatis-Plus自動填充更新操作相關字段的實現(xiàn)

    Mybatis-Plus自動填充更新操作相關字段的實現(xiàn)

    這篇文章主要介紹了Mybatis-Plus自動填充更新操作相關字段的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • java模擬post請求發(fā)送json的例子

    java模擬post請求發(fā)送json的例子

    本篇文章主要介紹了java模擬post請求發(fā)送json的例子,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • java 實現(xiàn)websocket的兩種方式實例詳解

    java 實現(xiàn)websocket的兩種方式實例詳解

    這篇文章主要介紹了java 實現(xiàn)websocket的兩種方式實例詳解,一種使用tomcat的websocket實現(xiàn),一種使用spring的websocket,本文通過代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2018-07-07
  • Kafka調(diào)試技巧及心得分享

    Kafka調(diào)試技巧及心得分享

    Kafka消費組機制確保每個消息只被一個消費者消費,新增機器時根據(jù)策略分配分區(qū),本地調(diào)試時,修改代碼后可能需要重新測試和造消息,但可以通過配置參數(shù)控制消費偏移量,線上環(huán)境調(diào)試可以通過接口拉取處理
    2026-02-02
  • Java實現(xiàn)的微信圖片處理工具類【裁剪,合并,等比例縮放等】

    Java實現(xiàn)的微信圖片處理工具類【裁剪,合并,等比例縮放等】

    這篇文章主要介紹了Java實現(xiàn)的微信圖片處理工具類,可實現(xiàn)針對圖片的裁剪、合并、等比例縮放、旋轉、識別等各種常見的圖片處理功能,需要的朋友可以參考下
    2017-11-11
  • Spring創(chuàng)建bean的幾種方式及使用場景

    Spring創(chuàng)建bean的幾種方式及使用場景

    本文主要介紹了Spring創(chuàng)建bean的幾種方式及使用場景,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • 輕松掌握Java橋接模式

    輕松掌握Java橋接模式

    這篇文章主要幫助大家輕松掌握Java橋接模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 一小時迅速入門Mybatis之bind與多數(shù)據(jù)源支持 Java API

    一小時迅速入門Mybatis之bind與多數(shù)據(jù)源支持 Java API

    這篇文章主要介紹了一小時迅速入門Mybatis之bind與多數(shù)據(jù)源支持 Java API,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • Java使用TCP實現(xiàn)在線聊天的示例代碼

    Java使用TCP實現(xiàn)在線聊天的示例代碼

    這篇文章主要介紹了Java使用TCP實現(xiàn)在線聊天的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • nacos注冊中心單節(jié)點ap架構源碼解析(最新推薦)

    nacos注冊中心單節(jié)點ap架構源碼解析(最新推薦)

    這篇文章主要介紹了nacos注冊中心單節(jié)點ap架構源碼解析,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01

最新評論

玉环县| 乐陵市| 汨罗市| 平山县| 临颍县| 西吉县| 西城区| 赤壁市| 大田县| 遂昌县| 鄄城县| 闻喜县| 容城县| 南涧| 蓝田县| 万荣县| 凤庆县| 开封市| 上饶市| 舒兰市| 洛阳市| 晋宁县| 泰州市| 庄河市| 电白县| 沂南县| 墨江| 三门县| 申扎县| 永济市| 宁国市| 当雄县| 平谷区| 海盐县| 淮阳县| 炉霍县| 玉树县| 依兰县| 遂平县| 和平县| 资源县|