精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

建行二面:Mybatis 是如何工作的?

開發 數據庫
本文,我們通過核心源碼分析了 MyBatis, 它是一個輕量級的 ORM框架,它通過配置文件和注解將 Java 對象與數據庫記錄映射起來。

MyBatis 是一款優秀的持久層框架,它通過簡化 JDBC操作和提供靈活的 SQL映射方式,使 Java 開發人員能夠更高效地進行數據庫操作。那么,MyBatis的執行原理是什么?這篇文章我們將深入地分析。

一、MyBatis 配置解析

MyBatis 的配置文件通常包括全局配置文件(mybatis-config.xml)和映射文件(XXXMapper.xml)。全局配置文件主要用于配置數據源和其他全局性的信息,而映射文件則用于定義 SQL 語句。

1. 全局配置文件解析

全局配置文件在 MyBatis 啟動時被解析。SqlSessionFactoryBuilder 是 MyBatis 解析配置文件的入口點。它通過 build 方法接收一個 Reader 或 InputStream,然后調用 XMLConfigBuilder 來解析 XML 配置文件。

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
        XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
        return build(parser.parse());
    } catch (Exception e) {
        throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
        ErrorContext.instance().reset();
        try {
            inputStream.close();
        } catch (IOException e) {
            // Intentionally ignore. Prefer previous error.
        }
    }
}

XMLConfigBuilder 解析配置文件并構建出 Configuration 對象,該對象包含了 MyBatis 的所有配置信息。

2. 映射文件解析

映射文件中定義了 SQL 語句,通過 XMLMapperBuilder 進行解析。每個 <mapper> 標簽對應一個 MappedStatement 對象,MappedStatement 包含了 SQL 語句、輸入輸出參數類型、結果集映射等信息。

public void parse() {
    if (!configuration.isResourceLoaded(resource)) {
        configurationElement(parser.evalNode("/mapper"));
        configuration.addLoadedResource(resource);
        bindMapperForNamespace();
    }
    parsePendingResultMaps();
    parsePendingCacheRefs();
    parsePendingStatements();
}

二、SQL 語句解析

MyBatis 支持動態 SQL,通過 <if>, <choose>, <foreach> 等標簽,可以根據不同的條件構造 SQL。動態 SQL 是 MyBatis 的一大特色,通過 SqlSource 接口實現。SqlSource 的主要實現類有 StaticSqlSource, DynamicSqlSource, RawSqlSource 等。

動態 SQL 解析

DynamicSqlSource 是處理動態 SQL 的核心類。它通過 SqlNode 樹來表示 SQL 語句的結構,SqlNode 是一個接口,常用的實現類有 IfSqlNode, ChooseSqlNode, WhereSqlNode 等。每個 SqlNode 的 apply 方法負責將節點轉換為 SQL 字符串。

public class DynamicSqlSource implements SqlSource {
    private final Configuration configuration;
    private final SqlNode rootSqlNode;

    public DynamicSqlSource(Configuration configuration, SqlNode rootSqlNode) {
        this.configuration = configuration;
        this.rootSqlNode = rootSqlNode;
    }
    
    @Override
    public BoundSql getBoundSql(Object parameterObject) {
        DynamicContext context = new DynamicContext(configuration, parameterObject);
        rootSqlNode.apply(context);
        SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
        Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
        SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
        return sqlSource.getBoundSql(parameterObject);
    }
}

三、參數設置

在獲得最終的 SQL 語句后,MyBatis 需要將參數傳遞給 SQL 語句。ParameterHandler 接口負責這項工作,默認實現是 DefaultParameterHandler。

public class DefaultParameterHandler implements ParameterHandler {
    private final TypeHandlerRegistry typeHandlerRegistry;
    private final MappedStatement mappedStatement;
    private final Object parameterObject;
    private final BoundSql boundSql;
    private final Configuration configuration;

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

    @Override
    public void setParameters(PreparedStatement ps) throws SQLException {
        ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        if (parameterMappings != null) {
            for (int i = 0; i < parameterMappings.size(); i++) {
                ParameterMapping parameterMapping = parameterMappings.get(i);
                if (parameterMapping.getMode() != ParameterMode.OUT) {
                    Object value;
                    String propertyName = parameterMapping.getProperty();
                    if (boundSql.hasAdditionalParameter(propertyName)) {
                        value = boundSql.getAdditionalParameter(propertyName);
                    } else if (parameterObject == null) {
                        value = null;
                    } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                        value = parameterObject;
                    } else {
                        MetaObject metaObject = configuration.newMetaObject(parameterObject);
                        value = metaObject.getValue(propertyName);
                    }
                    TypeHandler typeHandler = parameterMapping.getTypeHandler();
                    JdbcType jdbcType = parameterMapping.getJdbcType();
                    if (value == null && jdbcType == null) {
                        jdbcType = configuration.getJdbcTypeForNull();
                    }
                    typeHandler.setParameter(ps, i + 1, value, jdbcType);
                }
            }
        }
    }
}

四、SQL 執行

SQL 執行是 MyBatis 的核心功能之一。Executor 接口定義了執行操作的基本方法,主要的實現類有 SimpleExecutor, ReuseExecutor, BatchExecutor。這些執行器通過 StatementHandler 執行 SQL 語句。

public class SimpleExecutor extends BaseExecutor {
    public SimpleExecutor(Configuration configuration, Transaction transaction) {
        super(configuration, transaction);
    }

    @Override
    public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
        Statement stmt = null;
        try {
            Configuration configuration = ms.getConfiguration();
            StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
            stmt = prepareStatement(handler, ms.getStatementLog());
            return handler.update(stmt);
        } finally {
            closeStatement(stmt);
        }
    }
}

五、結果處理

MyBatis 提供了強大的結果集映射功能,允許將 SQL 查詢結果映射為 Java 對象。ResultSetHandler 接口負責處理結果集,DefaultResultSetHandler 是其主要實現類。

public class DefaultResultSetHandler implements ResultSetHandler {
    private final TypeHandlerRegistry typeHandlerRegistry;
    private final ObjectFactory objectFactory;
    private final boolean useConstructorMappings;
    private final ReflectorFactory reflectorFactory;
    private final MappedStatement mappedStatement;
    private final RowBounds rowBounds;
    private final ParameterHandler parameterHandler;
    private final ResultHandler<?> resultHandler;
    private final BoundSql boundSql;

    public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler<?> resultHandler, BoundSql boundSql, RowBounds rowBounds) {
        this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
        this.objectFactory = mappedStatement.getConfiguration().getObjectFactory();
        this.useConstructorMappings = mappedStatement.getConfiguration().isUseConstructorMappings();
        this.reflectorFactory = mappedStatement.getConfiguration().getReflectorFactory();
        this.mappedStatement = mappedStatement;
        this.rowBounds = rowBounds;
        this.parameterHandler = parameterHandler;
        this.resultHandler = resultHandler;
        this.boundSql = boundSql;
    }

    @Override
    public List<Object> handleResultSets(Statement stmt) throws SQLException {
        final List<Object> multipleResults = new ArrayList<>();
        int resultSetCount = 0;
        ResultSetWrapper rsw = getFirstResultSet(stmt);
        List<ResultMap> resultMaps = mappedStatement.getResultMaps();
        int resultMapCount = resultMaps.size();
        validateResultMapsCount(rsw, resultMapCount);
        while (rsw != null && resultMapCount > resultSetCount) {
            ResultMap resultMap = resultMaps.get(resultSetCount);
            handleResultSet(rsw, resultMap, multipleResults, null);
            rsw = getNextResultSet(stmt);
            cleanUpAfterHandlingResultSet();
            resultSetCount++;
        }
        return collapseSingleResultList(multipleResults);
    }
}

六、總結

本文,我們通過核心源碼分析了 MyBatis, 它是一個輕量級的 ORM框架,它通過配置文件和注解將 Java 對象與數據庫記錄映射起來,其核心在于通過 XML和注解配置 SQL語句,利用執行器執行 SQL,并通過結果集處理器將結果映射為 Java對象。

MyBatis的設計使得開發者可以專注于 SQL本身,而不必關心底層 JDBC操作的細節,了解和掌握其執行原理和設計模式,可以幫組我們在實際應用中更好地使用 MyBatis。

責任編輯:趙寧寧 來源: 猿java
相關推薦

2025-03-28 10:47:05

開發注解Java

2024-09-29 09:50:05

2024-10-29 09:42:50

2025-04-08 09:20:00

Sentinel限流微服務

2025-03-20 09:59:55

Spring@ProfileJava

2025-03-25 12:00:00

@Value?Spring開發

2024-10-10 17:17:57

2021-04-25 09:58:48

mmapJava面試

2025-03-18 08:30:00

Spring開發java

2021-03-17 15:54:32

IO零拷貝方式

2024-07-30 14:01:51

Java字節碼JVM?

2024-10-15 09:25:08

JDBCMybatis數據庫

2021-05-10 17:20:55

AIOps開發人員人工智能

2011-08-08 13:45:58

jQuery

2024-09-27 16:33:44

2024-08-30 08:59:15

2024-09-06 17:55:27

Springboot開發

2023-04-18 14:53:48

2010-08-02 16:56:03

ICMP協議

2023-04-18 15:09:50

點贊
收藏

51CTO技術棧公眾號

国产成人在线播放| 欧美羞羞免费网站| 美脚丝袜一区二区三区在线观看| 无码人妻精品一区二区三区蜜桃91 | 欧美视频综合| 国产一区二区三区四区五区美女 | 懂色中文一区二区在线播放| 日本亚洲欧洲色| 欧美激情精品久久久久久免费| 国产 日韩 欧美 综合 一区| 欧美三级韩国三级日本一级| 免费看欧美黑人毛片| 成人动漫在线免费观看| 成人黄色777网| 国产人妖伪娘一区91| 久久精品视频日本| 国产精品久久久久无码av| 日韩av在线精品| 毛片毛片毛片毛| 在线精品亚洲欧美日韩国产| 亚洲欧美日韩系列| 神马影院我不卡| 婷婷婷国产在线视频| 国产精品亚洲成人| 国产欧美精品一区二区三区介绍| 全部毛片永久免费看| 中文在线日韩| 日韩在线视频线视频免费网站| 亚洲天堂美女视频| 韩国三级成人在线| 精品视频免费看| 国产成人无码一二三区视频| 美女精品导航| 一区二区免费视频| 日韩中文字幕在线观看| 香港三级日本三级| 一区二区三区国产好| 欧美美女一区二区在线观看| 无码人妻丰满熟妇区毛片| 国产乱妇乱子在线播视频播放网站| 亚洲色图视频免费播放| 亚洲v国产v在线观看| 欧美在线观看在线观看| av网站免费线看精品| 国产精品视频免费观看| 亚洲第一精品网站| 国产精品99久久久久久似苏梦涵 | 日韩在线观看免费高清| 你懂得视频在线观看| 欧美理论电影大全| 在线观看国产欧美| 18精品爽国产三级网站| 精品一二三区| 色狠狠久久aa北条麻妃| 日本高清黄色片| 欧美艳星介绍134位艳星| 国产亚洲精品久久久优势| 亚洲一区视频在线播放| 精品国内自产拍在线观看视频 | 99热这里只有精品4| 日韩国产专区| 久久精品99久久久久久久久| 国产人妻精品一区二区三区不卡 | 欧美爱爱视频免费看| bbw在线视频| 欧美特黄级在线| 免费观看成人在线视频| 成人一级视频| 欧美一区二区三区电影| 日本wwwwwww| 人人香蕉久久| 在线不卡国产精品| 黄色香蕉视频在线观看| 欧美激情视频一区二区三区免费| 欧美黑人xxxx| 五月婷婷中文字幕| 日本在线不卡一区| 91欧美激情另类亚洲| 亚洲免费黄色片| 久久久五月婷婷| 在线看视频不卡| 超碰在线99| 91国产丝袜在线播放| 男人的天堂最新网址| 视频成人永久免费视频| 亚洲精品国产精品国自产观看浪潮| 国产肉体xxxx裸体784大胆| 国产日产精品_国产精品毛片| 久久久91精品国产一区不卡| 久久精品国产亚洲AV无码麻豆 | www.cao超碰| 永久免费精品视频| 国产亚洲xxx| 日韩欧美中文字幕视频| 香蕉久久夜色精品国产| 国产女精品视频网站免费| 亚洲伦理在线观看| 国产亚洲美州欧州综合国| avove在线观看| 中文字幕在线高清| 欧美一区二区人人喊爽| 欧美特黄一区二区三区| 这里只有精品在线| 欧美最近摘花xxxx摘花| 99久久亚洲精品日本无码 | 日韩午夜中文字幕| 性欧美精品中出| 国内在线观看一区二区三区| 国产精品免费看久久久香蕉| 人妻少妇一区二区三区| 国产精品久久毛片a| 国产欧美日韩网站| 大胆国模一区二区三区| 日韩毛片在线看| www青青草原| 美国一区二区三区在线播放| 欧美成人第一区| 午夜伦理在线视频| 精品视频在线视频| 极品人妻一区二区三区| 黄色成人av网站| 成人国产精品免费视频| 国产女人在线视频| 精品久久久视频| 91亚洲一线产区二线产区| 91九色精品| 国产乱肥老妇国产一区二 | 99国产精品久久久久久久成人 | 亚洲人成绝费网站色www| 麻豆一区产品精品蜜桃的特点| 美女脱光内衣内裤视频久久网站| 农村寡妇一区二区三区| 三级在线观看视频| 欧美mv日韩mv| 精品99在线观看| 国产在线国偷精品产拍免费yy| 亚洲电影免费| 成人自拍视频网| 中文在线不卡视频| 波多野结衣在线观看视频| 91香蕉视频污| 蜜臀久久99精品久久久酒店新书| 亚洲国产国产| 青青草原一区二区| 国产系列在线观看| 欧美性xxxxx极品少妇| 丁香花五月婷婷| 视频在线在亚洲| 日韩电影大全在线观看| 你懂得影院夜精品a| 国产香蕉一区二区三区在线视频 | 日本中文字幕一区二区| 亚洲欧美日韩国产精品| 免费污污视频在线观看| 国产日韩欧美精品一区| 亚欧激情乱码久久久久久久久| 日韩精品一区二区久久| 91精品国产综合久久香蕉的用户体验 | 国产精选一区| 国产精品一区二区三| 日本美女在线中文版| 在线综合亚洲欧美在线视频 | 色悠悠亚洲一区二区| 日韩精品电影一区二区| 免费不卡在线视频| 国产盗摄视频在线观看| 高潮按摩久久久久久av免费| 2018中文字幕一区二区三区| 国产中文字幕在线| 欧美日韩国产另类一区| 极品颜值美女露脸啪啪| av一二三不卡影片| 免费男同深夜夜行网站| 正在播放日韩欧美一页 | 亚洲日本香蕉视频| 欧美亚洲一区三区| 三级影片在线看| 91蝌蚪国产九色| 欧美丝袜在线观看| 影音先锋一区| 日韩一区二区三区高清| 在线视频亚洲欧美中文| 日本人成精品视频在线| 成人免费高清| 亚洲欧美日韩中文在线| 国产欧美久久久精品免费| 午夜在线电影亚洲一区| 人成免费在线视频| 夫妻av一区二区| 黑人粗进入欧美aaaaa| 自拍日韩欧美| 欧洲国产精品| www.国产精品一区| 国产精品入口日韩视频大尺度| 超碰在线无需免费| 精品亚洲一区二区| 性做久久久久久久| 欧美日韩视频在线一区二区 | 羞羞网站在线看| 国产一区二区美女视频| 午夜精品无码一区二区三区| 91成人免费在线视频| 日本三级欧美三级| 中文字幕一区二区三区不卡| 你懂得在线视频| 国产一区二区三区综合| 欧美日韩大尺度| 亚洲日本激情| 777久久精品一区二区三区无码 | 一区二区三区四区在线观看视频| 性网爆门事件集合av| 欧美日韩一二三| 日本一区二区免费电影| 亚洲综合色丁香婷婷六月图片| 一级片黄色录像| 久久综合久久久久88| av漫画在线观看| 国产麻豆精品视频| 在线不卡一区二区三区| 日本中文一区二区三区| 爱福利视频一区二区| 亚洲久久在线| 国产又粗又猛又爽又黄的网站| 五月婷婷六月综合| 日韩欧美三级一区二区| 综合伊思人在钱三区| 国内视频一区| 国产精东传媒成人av电影| 91色p视频在线| 祥仔av免费一区二区三区四区| 日本中文字幕不卡免费| 在线女人免费视频| 91精品国产91久久久久久| 久久青青色综合| 精品中文字幕乱| 在线你懂的视频| 欧美成人第一页| 成人高清免费在线| 久久久999精品视频| 久热国产在线| 欧美超级乱淫片喷水| 精品176二区| 欧美成人午夜激情视频| 成人影院在线看| 欧美老女人性视频| 免费在线看污片| 国内精品中文字幕| 涩涩视频在线| 日韩av第一页| 欧美性www| 成人激情在线播放| 日本精品视频| 国产精品xxxx| 日韩有码一区| 茄子视频成人在线观看 | 久久日一线二线三线suv| 日本japanese极品少妇| 91蜜桃在线免费视频| 日本理论中文字幕| 中文字幕字幕中文在线中不卡视频| 91麻豆精品成人一区二区| 亚洲精品日日夜夜| 日韩熟女精品一区二区三区| 欧美性xxxxxxxxx| 最新国产中文字幕| 欧美日韩高清影院| 亚洲奶汁xxxx哺乳期| 亚洲美女自拍视频| 日本中文字幕电影在线免费观看| 欧美第一淫aaasss性| 麻豆视频在线观看免费网站黄| 国产成人福利视频| 亚洲精品毛片| 国产伦精品一区二区三区免| 蜜臀av免费一区二区三区| 亚洲午夜在线观看| 欧美精品一线| 日本在线观看a| 狠狠色狠狠色合久久伊人| 农村末发育av片一区二区 | 亚洲精品720p| 91caoporn在线| 欧美精品videos| 超薄肉色丝袜脚交一区二区| 97视频热人人精品| 一区二区导航| 久久男人资源站| 日本在线观看不卡视频| 香蕉视频免费网站| 亚洲国产精品av| 日韩欧美亚洲一区二区三区| 欧美人xxxx| 偷拍25位美女撒尿视频在线观看| www.亚洲一区| 天堂中文在线播放| 99视频免费观看| 波多野结衣在线观看一区二区| 亚洲色欲久久久综合网东京热| 石原莉奈在线亚洲三区| 麻豆av免费看| 国产精品毛片久久久久久| 日韩欧美a级片| 欧美一区二区久久| 国产香蕉视频在线看| 高清欧美性猛交xxxx| 亚洲精品乱码日韩| 青青草原成人| 亚洲国产激情| 99精品视频国产| 欧美激情一区二区三区不卡| 日韩免费不卡视频| 欧美一卡2卡三卡4卡5免费| 岛国视频免费在线观看| 97久久精品视频| 亚洲欧洲国产精品一区| 亚欧精品在线| 久久一二三四| 日本黄色特级片| 五月婷婷色综合| www.欧美国产| 超碰精品一区二区三区乱码| 成人午夜在线| 色一情一乱一伦一区二区三区| 亚洲一区观看| 亚洲国产精品无码久久久久高潮| 一区二区三区在线观看国产| 国产一区二区小视频| 中文字幕精品av| 国产成人免费| 一本一道久久a久久综合精品| 日韩精品国产精品| 性欧美一区二区| 91久久一区二区| 精品三级久久久久久久电影聊斋| 69av视频在线播放| 欧美调教在线| 哪个网站能看毛片| 久久精品视频免费| 欧产日产国产69| 亚洲欧洲黄色网| 欧美一级大黄| 亚洲国产一区二区三区在线 | 色偷偷88欧美精品久久久| 青青草视频在线观看| 992tv成人免费视频| 久久精品66| 黄色片一级视频| 国产日韩欧美高清在线| 免费看av在线| 日韩中文字幕国产精品| 啪啪av大全导航福利综合导航| 在线国产精品网| 国产成人免费网站| 日本亚洲色大成网站www久久| 亚洲成人三级在线| 理论不卡电影大全神| 欧美日韩综合另类| 日韩精品一区第一页| 国产传媒视频在线| 欧美一区日韩一区| 男女羞羞视频在线观看| 就去色蜜桃综合| 日本va欧美va精品| 波多野结衣久久久久| 精品国产伦一区二区三区观看方式| 草美女在线观看| 欧美日韩国产不卡在线看| 日韩成人午夜电影| www.av成人| 亚洲黄色av网站| 精品日韩视频| 国产精品视频二| 久久奇米777| 欧美高清69hd| 九九热精品在线| 亚洲v天堂v手机在线| 岛国av免费在线| 五月天激情综合| yw193.com尤物在线| caoporen国产精品| 狂野欧美一区| 亚洲一级生活片| 亚洲精品自产拍| 国产区一区二| 日本三级免费观看| 亚洲视频在线观看三级| 五月天婷婷激情网| 91精品久久久久| 蜜桃伊人久久| 538精品在线观看| 亚洲午夜激情免费视频| 136国产福利精品导航网址应用| 欧美日韩亚洲一二三| 亚洲男人电影天堂| 蝌蚪视频在线播放| 国产精品免费在线| 精品一区二区影视| av黄色在线播放| 久久久久久久久久国产| 欧美熟乱15p|