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

Mybatis框架之代理模式(Proxy Pattern)的實現(xiàn)

 更新時間:2024年11月19日 09:46:42   作者:Katie。  
本文主要介紹了MyBatis框架中使用代理模式ProxyPattern的原理和實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

MyBatis 框架中大量使用了代理模式 (Proxy Pattern),尤其在 Mapper 接口 的實現(xiàn)上。代理模式使得 MyBatis 能夠在不直接實現(xiàn)接口的情況下動態(tài)地提供接口的實現(xiàn),從而簡化數(shù)據庫操作代碼,同時提供更強大的功能。下面將詳細解讀 MyBatis 中的代理模式的工作原理及其實現(xiàn)。

1. 什么是代理模式 (Proxy Pattern)?

代理模式 是一種結構型設計模式,它為某個對象提供一個代理對象,以控制對這個對象的訪問。代理對象通常會對請求進行預處理或后處理,然后將請求傳遞給實際的目標對象。

代理模式的特點

  • 控制訪問:通過代理對象來控制對目標對象的訪問。
  • 延遲加載:可以在代理中實現(xiàn)懶加載。
  • 增強功能:可以在調用目標對象之前或之后執(zhí)行額外的操作(例如日志、權限檢查、事務管理等)。

2. MyBatis 中代理模式的應用

在 MyBatis 中,代理模式的主要應用場景是 Mapper 接口。開發(fā)者只需要定義 Mapper 接口,而無需提供接口的實現(xiàn)類。MyBatis 會在運行時為這些接口創(chuàng)建動態(tài)代理對象,通過代理對象來執(zhí)行 SQL 語句。

2.1 MyBatis 如何使用代理模式

  • Mapper 接口:用戶定義的接口,用于聲明數(shù)據庫操作方法(如 getUserById、insertUser 等)。
  • Mapper 動態(tài)代理:MyBatis 通過 JDK 動態(tài)代理 為 Mapper 接口生成代理對象。
  • SqlSession.getMapper() 方法:用于獲取 Mapper 接口的代理實例。當調用代理實例的方法時,會由 MyBatis 攔截并執(zhí)行相應的 SQL 語句。

3. 代理模式的工作流程

3.1 工作原理

  • 開發(fā)者定義一個 Mapper 接口,聲明數(shù)據庫操作方法。
  • 通過 SqlSession.getMapper(Class<T> clazz) 方法獲取接口的代理對象。
  • 調用代理對象的方法時,MyBatis 會通過 MapperProxy 攔截方法調用。
  • MapperProxy 通過 MappedStatement 查找對應的 SQL 語句,并執(zhí)行相應的數(shù)據庫操作。
  • 將查詢結果封裝成接口方法的返回類型(如 List<User>)。

3.2 Mapper 代理示意圖

UserMapper (接口)
    ↓
SqlSession.getMapper(UserMapper.class)
    ↓
MapperProxy (JDK 動態(tài)代理)
    ↓
MappedStatement (映射 SQL)
    ↓
執(zhí)行 SQL 并返回結果

4. 實際代碼示例

4.1 創(chuàng)建 Mapper 接口 (UserMapper.java)

package com.example.mapper;

import com.example.model.User;
import java.util.List;

public interface UserMapper {
    // 查詢所有用戶
    List<User> getAllUsers();

    // 根據 ID 查詢用戶
    User getUserById(int id);
}

4.2 編寫 Mapper XML 文件 (UserMapper.xml)

<?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="getAllUsers" resultType="com.example.model.User">
        SELECT * FROM users;
    </select>

    <select id="getUserById" parameterType="int" resultType="com.example.model.User">
        SELECT * FROM users WHERE id = #{id};
    </select>
</mapper>

4.3 MyBatis 配置文件 (mybatis-config.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mydatabase"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

4.4 使用 SqlSession 獲取 Mapper 代理對象 (MyBatisExample.java)

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.example.mapper.UserMapper;
import com.example.model.User;
import java.io.InputStream;
import java.util.List;

public class MyBatisExample {
    public static void main(String[] args) {
        String resource = "mybatis-config.xml";
        try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
            // 創(chuàng)建 SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            // 打開 SqlSession
            try (SqlSession session = sqlSessionFactory.openSession()) {
                // 獲取 Mapper 接口的代理對象
                UserMapper userMapper = session.getMapper(UserMapper.class);

                // 調用代理對象的方法
                List<User> users = userMapper.getAllUsers();
                users.forEach(user -> System.out.println(user.getName()));

                // 根據 ID 查詢用戶
                User user = userMapper.getUserById(1);
                System.out.println("User ID 1: " + user.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. MyBatis 代理模式的實現(xiàn)細節(jié)

  • MapperProxy 類:MyBatis 使用 MapperProxy 類來實現(xiàn) JDK 動態(tài)代理。MapperProxy 實現(xiàn)了 InvocationHandler 接口,用于攔截 Mapper 接口方法的調用。

  • MapperMethod 類MapperProxy 會將攔截到的方法調用委托給 MapperMethod 對象。MapperMethod 根據方法名查找對應的 MappedStatement,然后執(zhí)行相應的 SQL 語句。

MapperProxy 示例(簡化版)

public class MapperProxy implements InvocationHandler {
    private SqlSession sqlSession;
    private Class<?> mapperInterface;

    public MapperProxy(SqlSession sqlSession, Class<?> mapperInterface) {
        this.sqlSession = sqlSession;
        this.mapperInterface = mapperInterface;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String statementId = mapperInterface.getName() + "." + method.getName();
        return sqlSession.selectList(statementId, args);
    }
}

6. 代理模式的優(yōu)勢

  • 解耦:開發(fā)者只需定義接口,無需編寫實現(xiàn)類,降低代碼耦合度。
  • 簡化代碼:減少重復的數(shù)據庫操作代碼,提高開發(fā)效率。
  • 動態(tài)性:通過動態(tài)代理機制,在運行時動態(tài)生成代理對象,減少硬編碼。
  • 靈活擴展:可以輕松添加攔截器,實現(xiàn)如日志記錄、權限校驗、事務控制等功能。

7. 代理模式的不足

  • 性能開銷:動態(tài)代理在方法調用時有一定的性能開銷,特別是在高并發(fā)場景下。
  • 調試困難:由于沒有實際的實現(xiàn)類,調試時無法直接跳轉到方法實現(xiàn),調試復雜度增加。
  • 學習成本:對于不熟悉動態(tài)代理機制的開發(fā)者,理解 MyBatis 的內部工作原理可能有一定的難度。

8. 總結

MyBatis 通過代理模式大幅簡化了數(shù)據庫操作代碼,使得開發(fā)者可以更專注于業(yè)務邏輯而不是 SQL 操作。MyBatis 代理模式的核心是使用 JDK 動態(tài)代理機制,在運行時為 Mapper 接口生成代理對象,從而將接口方法映射到相應的 SQL 語句執(zhí)行。代理模式的使用提高了 MyBatis 的靈活性和擴展性,是其重要的設計亮點之一。

到此這篇關于Mybatis框架之代理模式(Proxy Pattern)的文章就介紹到這了,更多相關Mybatis 代理模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java實現(xiàn)圖片拼接

    Java實現(xiàn)圖片拼接

    這篇文章主要為大家詳細介紹了Java實現(xiàn)圖片拼接的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Java統(tǒng)計接口耗時的六種常見方法

    Java統(tǒng)計接口耗時的六種常見方法

    有些小伙伴在工作中,可能經常遇到這樣的場景:線上接口突然變慢,用戶抱怨連連,你卻一頭霧水,不知道問題出在哪里,其實,這些問題都離不開一個基礎技能如何準確統(tǒng)計接口耗時,所以本文就跟大家一起聊聊統(tǒng)計接口耗時的6種常見方法,需要的朋友可以參考下
    2025-10-10
  • SpringBoot中使用MyBatis-Plus詳細步驟

    SpringBoot中使用MyBatis-Plus詳細步驟

    MyBatis-Plus是MyBatis的增強工具,簡化了MyBatis的使用,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • 圖書信息管理java實現(xiàn)代碼

    圖書信息管理java實現(xiàn)代碼

    這篇文章主要為大家詳細介紹了圖書信息管理java實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • java中File類的使用方法

    java中File類的使用方法

    本篇文章介紹了,在java中File類的使用方法。需要的朋友參考下
    2013-04-04
  • Java?+?Selenium?+?OpenCV解決自動化測試中的滑塊驗證問題

    Java?+?Selenium?+?OpenCV解決自動化測試中的滑塊驗證問題

    OpenCV是一個基于Apache2.0許可(開源)發(fā)行的跨平臺計算機視覺和機器學習軟件庫,可以運行在Linux、Windows、Android和Mac?OS操作系統(tǒng)上,這篇文章主要介紹了Java?+?Selenium?+?OpenCV解決自動化測試中的滑塊驗證,需要的朋友可以參考下
    2022-07-07
  • 如何在SpringBoot項目里進行統(tǒng)一異常處理

    如何在SpringBoot項目里進行統(tǒng)一異常處理

    這篇文章主要介紹了如何在SpringBoot項目里進行統(tǒng)一異常處理,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值。需要的小伙伴可以參考一下
    2022-07-07
  • Java利用AlphaComposite類合并圖像

    Java利用AlphaComposite類合并圖像

    這篇文章主要介紹了Java利用AlphaComposite類合并圖像,幫助大家更好的利用Java處理圖像,感興趣的朋友可以了解下
    2020-10-10
  • Spring aop+反射實現(xiàn)電話號加密

    Spring aop+反射實現(xiàn)電話號加密

    線上項目涉及大量查詢接口中,存在電話號明文展示不合規(guī)的問題。如果對每個接口返回結果中電話號相關字段修改相關代碼邏輯,則工作量較大花費時間多。因此設計電話號加密注解,減少工作量。
    2021-06-06
  • java虛擬機運行時數(shù)據區(qū)分析

    java虛擬機運行時數(shù)據區(qū)分析

    這篇文章主要介紹了java虛擬機運行時數(shù)據區(qū)分析,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11

最新評論

阳谷县| 白沙| 万载县| 五寨县| 望奎县| 甘孜| 建湖县| 白银市| 桐乡市| 罗平县| 贡觉县| 新巴尔虎左旗| 宁国市| 安塞县| 稷山县| 万源市| 丰宁| 桓仁| 葫芦岛市| 合川市| 绵竹市| 新民市| 芷江| 门头沟区| 牙克石市| 安康市| 金门县| 长白| 洪雅县| 清徐县| 高密市| 蓬莱市| 红河县| 穆棱市| 宁阳县| 漳平市| 三都| 宿松县| 徐州市| 黄山市| 元江|