乐于分享
好东西不私藏

MyBatis 源码解读(一):整体架构与启动初始化

MyBatis 源码解读(一):整体架构与启动初始化

写在前面

看 MyBatis 源码的人一般分两种:一种是面试被问得怀疑人生来补课的,另一种是真要在项目里搞深度定制(写分页插件、魔改缓存策略之类)。不管你是哪一种,入口都一样——你得先搞明白 MyBatis 启动的时候到底干了些什么勾当,那些 XML 配置是怎么一步步变成运行时能用的对象的。

这篇文章就把这条链路从头跟到尾。读完之后你应该能回答一个面试高频题:SqlSessionFactoryBuilder.build() 这一行代码背后,到底发生了多少事?

剧透:比你以为的多得多。

一、整体架构:三层楼,各干各的

先不急着看代码。MyBatis 的模块划分搞不清楚,后面读源码就像逛商场不带导览图——走到哪算哪,永远不知道自己在几楼。

MyBatis 的源码包结构大致分三层:

层次
核心包
职责
通俗理解
接口层
session
对外暴露 API
前台,你打交道的窗口
核心处理层
executor
scriptingmappingbuilder
SQL 解析、执行、结果映射
后厨,真正干活的地方
基础支撑层
type
iologgingreflectiontransaction
类型转换、资源加载、日志、反射、事务
水电气,离了谁都转不了

一个 SQL 从发出到返回结果,要经过的完整路径:

SqlSession → Executor → StatementHandler → ParameterHandler → JDBC                                                           ↓SqlSession ← Executor ← ResultSetHandler ← ResultSet ← JDBC

打个比方:SqlSession 是服务员接单,Executor 是后厨调度,StatementHandler 是厨师,ParameterHandler 是配菜工,ResultSetHandler 是装盘出菜的。JDBC 就是灶台——真正跟数据库"火拼"的地方。

这个流程后面几篇会逐层展开。这篇聚焦最前面的问题:这条链路上用到的所有对象,是谁创建的、什么时候创建的?

答案就藏在启动初始化流程里。

二、启动入口:SqlSessionFactoryBuilder——一次性工具人

不管是纯 MyBatis 还是 Spring 集成,最终都会走到同一个入口:

SqlSessionFactory factory = new SqlSessionFactoryBuilder()    .build(inputStream);

看 SqlSessionFactoryBuilder 的源码(org.apache.ibatis.session.SqlSessionFactoryBuilder),这个类薄得离谱——本质上就干一件事:把配置文件的输入流甩给 XMLConfigBuilder 去解析,然后用解析结果创建 DefaultSqlSessionFactory

核心方法:

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) { }    }}public SqlSessionFactory build(Configuration config){returnnew DefaultSqlSessionFactory(config);}

两行关键代码,其余都是打杂的异常处理和资源关闭:

  1. parser.parse() —— 解析 XML,构建 Configuration 对象
  2. build(config) —— 用 Configuration 创建 DefaultSqlSessionFactory

SqlSessionFactoryBuilder 没有任何状态,用完即弃。就像搬家公司——帮你把家具从旧家搬到新家,完事走人,你不会留着搬家公司的电话天天打。这也解释了为什么官方文档说它最好的使用方式就是方法局部变量——用完就被 GC 回收,不需要留引用。

三、XMLConfigBuilder:配置解析的主厨

3.1 继承体系

XMLConfigBuilder 继承自 BaseBuilder,整个 Builder 家族长这样:

BaseBuilder  ├── XMLConfigBuilder        — 解析 mybatis-config.xml(大盘总控)  ├── XMLMapperBuilder        — 解析 Mapper XML(每个 Mapper 文件一个实例)  ├── XMLStatementBuilder     — 解析 <select>/<insert> 等标签(最小粒度)  └── MapperAnnotationBuilder — 解析 Mapper 接口上的注解(注解派的入口)

BaseBuilder 持有一个 Configuration 引用和几个注册器(TypeAliasRegistryTypeHandlerRegistry),子类共享这些注册器来完成类型转换和别名查找。这就好比后厨共享一个调料架——大家都能用,但调料架只有一份。

3.2 构造方法:Configuration 的诞生

privateXMLConfigBuilder(XPathParser parser,        String environment, Properties props){super(new Configuration());  // ← Configuration 在这里出生    ErrorContext.instance().resource("SQL Mapper Configuration");this.configuration.setVariables(props);this.parsed = false;this.environment = environment;this.parser = parser;}

注意 super(new Configuration())Configuration 的无参构造方法可不是空壳,它在出生那一刻就干了不少活——注册内置的类型别名(int → Integerstring → String)和类型处理器。这些是 MyBatis 开箱即用的基础能力,就像新手机预装的系统应用,你没得选,但还真离不开。

XPathParser 在构造 XMLConfigBuilder 之前就已经创建好了,它负责把 XML 文件解析成 DOM 树,并提供 XPath 查询能力。验证 DTD 的工作由 XMLMapperEntityResolver 完成——它很聪明,会从类路径下加载本地的 DTD 文件,而不是傻乎乎地去远程拉取。毕竟谁也不想因为网络抖动导致框架启动失败。

3.3 parse() 方法:解析入口,只准进一次

public Configuration parse(){if (parsed) {thrownew BuilderException("Each XMLConfigBuilder can only be used once.");    }    parsed = true;    parseConfiguration(parser.evalNode("/configuration"));return configuration;}

parsed 标志位保证一个 XMLConfigBuilder 实例只被调用一次。这不是防御性编程的过度设计——Configuration 对象在解析过程中是被逐步填充的,就像往碗里加料,调完味了你再往里倒一遍酱汁,那不叫加料,那叫灾难。

3.4 parseConfiguration:按顺序解析各节点——顺序很重要

这是最核心的方法,决定了配置的加载顺序:

privatevoidparseConfiguration(XNode root){try {        propertiesElement(root.evalNode("properties"));        Properties settings = settingsAsProperties(            root.evalNode("settings"));        loadCustomVfs(settings);        loadCustomLogImpl(settings);        typeAliasesElement(root.evalNode("typeAliases"));        pluginElement(root.evalNode("plugins"));        objectFactoryElement(root.evalNode("objectFactory"));        objectWrapperFactoryElement(            root.evalNode("objectWrapperFactory"));        reflectorFactoryElement(            root.evalNode("reflectorFactory"));        settingsElement(settings);        environmentsElement(root.evalNode("environments"));        databaseIdProviderElement(            root.evalNode("databaseIdProvider"));        typeHandlerElement(root.evalNode("typeHandlers"));        mapperElement(root.evalNode("mappers"));    } catch (Exception e) {thrownew BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);    }}

这个顺序不是随意排的。几个值得注意的点:

  • properties 最先解析:后面的 settings、dataSource 等节点可能引用 ${placeholder},properties 不先加载,后面全是问号——跟做菜一个道理,调料得先备好,不然下锅的时候才发现盐罐子是空的
  • settings 先读后用:先读成 Properties 对象,中间穿插了 VFS 和日志配置的处理,最后才通过 settingsElement() 把设置值写入 Configuration。因为 settings 里有些配置会影响后续组件的行为(比如 cacheEnabled 决定要不要给 Executor 套一层 CachingExecutor 装饰器),得先把前面的杂事干完再应用
  • mappers 压轴解析:Mapper 解析依赖前面所有配置就位——typeAliases、typeHandlers、plugins 缺一不可。把它放最后,就像上菜前得先把桌布、餐具、调料碟都摆好

四、几个关键节点的解析细节

4.1 properties:三级覆盖——谁说了算?

propertiesElement 处理 <properties> 节点时的优先级,从低到高:

  1. <properties> 节点 resource 或 url 属性引用的外部文件(最软)
  2. <properties> 节点中 <property> 子标签定义的属性
  3. 方法参数传入的 Properties(通过 build() 的第三个参数传入,最硬)

覆盖规则:硬的覆盖软的。代码传入的参数是钦定的,谁也改不了;外部文件里的属性是默认值,随时可以被覆盖。这个设计跟 Spring 的属性覆盖策略思路一致——运行时参数应该优先于配置文件。毕竟线上出了问题要临时改个配置,总不能改完配置文件再重新打包部署吧?

源码里的实现方式很直白——先加载低优先级的,再用高优先级的 putAll 覆盖:

privatevoidpropertiesElement(XNode context)throws Exception {if (context != null) {        Properties defaults = context.getChildrenAsProperties();        String resource = context.getStringAttribute("resource");        String url = context.getStringAttribute("url");if (resource != null && url != null) {thrownew BuilderException("The properties element cannot specify both "                + "a URL and a resource based property file reference.");        }if (resource != null) {            defaults.putAll(                Resources.getResourceAsProperties(resource));        } elseif (url != null) {            defaults.putAll(                Resources.getUrlAsProperties(url));        }        Properties vars = configuration.getVariables();if (vars != null) {            defaults.putAll(vars);        }        parser.setVariables(defaults);        configuration.setVariables(defaults);    }}

注意一个小细节:resource 和 url 不能同时指定。这是 DTD 约束之外的一个运行时校验——MyBatis 在"你不能既要又要"这件事上立场很坚定。

4.2 settings:框架行为的全局开关

settings 节点控制 MyBatis 的核心行为,可以理解为框架的"控制面板"。settingsAsProperties 先把 XML 里的设置项读成 Properties,然后 settingsElement 把这些值逐个设到 Configuration 上。

一些能直接影响架构行为的 settings:

设置项
默认值
影响
一句话解释
cacheEnabled
true
是否启用二级缓存
开了就给 Executor 穿马甲
lazyLoadingEnabled
false
延迟加载开关
关了就是饿汉,开了就是懒汉
defaultExecutorType
SIMPLE
Executor 类型
SIMPLE/REUSE/BATCH 三选一
localCacheScope
SESSION
一级缓存范围
SESSION 级别可能踩坑
aggressiveLazyLoading
false (3.4.1+)
任意方法触发延迟加载
开了就是"一碰就加载"

settingsElement 方法逻辑简单但代码很长——逐个读取配置值并调用 Configuration 的 setter。有个细节值得夸:如果你配了一个不认识的 key,直接抛异常,不会静默忽略。这比那些"配错了也不报错,只是默默不生效"的框架厚道多了——早发现比晚排查好一百倍。

4.3 environments:数据源和事务——选哪个环境?

environmentsElement 解析 <environments> 节点,核心逻辑是根据 default 属性选中一个 <environment>,然后分别解析事务工厂和数据源:

privatevoidenvironmentsElement(XNode context)throws Exception {if (context != null) {if (environment == null) {            environment = context.getStringAttribute("default");        }for (XNode child : context.getChildren()) {            String id = child.getStringAttribute("id");if (isSpecifiedEnvironment(id)) {                TransactionFactory txFactory =                    transactionManagerElement(                        child.evalNode("transactionManager"));                DataSourceFactory dsFactory =                    dataSourceElement(                        child.evalNode("dataSource"));                DataSource dataSource = dsFactory.getDataSource();                Environment.Builder environmentBuilder =new Environment.Builder(id)                        .transactionFactory(txFactory)                        .dataSource(dataSource);                configuration.setEnvironment(                    environmentBuilder.build());            }        }    }}

Environment 是 Configuration 的一个内部组件,封装了 TransactionFactory 和 DataSource。这里用了 Builder 模式,因为 Environment 一旦构建就不应该被修改——数据源和事务工厂在运行时切换,好比飞机在飞行途中换引擎,出事概率不小。

事务管理器的类型通过 type 属性指定:JDBC 对应 JdbcTransactionFactory(自己管事务),MANAGED 对应 ManagedTransactionFactory(交给容器管)。数据源同理:UNPOOLED(来一个连一个)、POOLED(连池子里捞)、JNDI(从容器借)分别对应不同的 DataSourceFactory 实现。这些别名映射都是通过 TypeAliasRegistry 完成的。

4.4 mappers:SQL 映射的加载——压轴大戏

这是初始化过程中最复杂的部分。mapperElement 方法处理四种映射方式,就像食堂有四个窗口:

privatevoidmapperElement(XNode parent)throws Exception {if (parent != null) {for (XNode child : parent.getChildren()) {if ("package".equals(child.getName())) {// 1. 按包名扫描——自助餐模式,一扫一大片                String mapperPackage =                    child.getStringAttribute("name");                configuration.addMappers(mapperPackage);            } else {                String resource =                    child.getStringAttribute("resource");                String url =                    child.getStringAttribute("url");                String mapperClass =                    child.getStringAttribute("class");if (resource != null && url == null                        && mapperClass == null) {// 2. 指定 XML 资源路径——按菜单点菜                    ErrorContext.instance().resource(resource);                    InputStream inputStream =                        Resources.getResourceAsStream(resource);                    XMLMapperBuilder mapperParser =new XMLMapperBuilder(inputStream,                            configuration, resource,                            configuration.getSqlFragments());                    mapperParser.parse();                } elseif (resource == null && url != null                        && mapperClass == null) {// 3. 指定 XML 的 URL——叫外卖                    ErrorContext.instance().resource(url);                    InputStream inputStream =                        Resources.getUrlAsStream(url);                    XMLMapperBuilder mapperParser =new XMLMapperBuilder(inputStream,                            configuration, url,                            configuration.getSqlFragments());                    mapperParser.parse();                } elseif (resource == null && url == null                        && mapperClass != null) {// 4. 指定 Mapper 接口类——直接找厨师                    Class<?> mapperInterface =                        Resources.classForName(mapperClass);                    configuration.addMapper(mapperInterface);                } else {thrownew BuilderException("A mapper element may only specify "                        + "a url, resource or class, "                        + "but not a combination.");                }            }        }    }}

四种方式,每次只能选一种——又是"不能既要又要"。不管走哪条路,最终都会到达 XMLMapperBuilder.parse() 或 MapperAnnotationBuilder。前者解析 XML 形式的 Mapper,后者处理接口上的注解(比如 @Select)。

XMLMapperBuilder.parse() 做的事,按顺序排列:

  1. 检查是否已加载过(通过 configuration.isResourceLoaded)——防止重复加载
  2. 解析 <cache-ref> 和 <cache> 缓存配置
  3. 解析 <resultMap> 结果映射
  4. 解析 <parameterMap>(已过时但保留兼容——老项目的命也是命)
  5. 解析 <sql> SQL 片段
  6. 逐个解析 <select>/<insert>/<update>/<delete>,每个标签生成一个 MappedStatement 对象
  7. 处理未解析的引用(跨 Mapper 的缓存引用等)

这里有个容易忽略的细节:MappedStatement 的 id 是 namespace + "." + id,所以同一个 namespace 下不能有重复 id。不同 namespace 下倒是可以有相同 id——它们是不同的 MappedStatement。这就像同一栋楼里不同公司可以有同名员工,但同一家公司里不允许重名。

五、Configuration:MyBatis 的"上帝对象"

经过上面所有步骤的解析,Configuration 对象被填充完毕。它是 MyBatis 运行时的"上帝对象"——几乎所有组件都直接或间接依赖它。如果你在源码里迷路了,找 Configuration,它就是那张总地图。

Configuration 里存了什么?挑重点列:

// 核心运行时配置——决定框架行为protectedboolean cacheEnabled = true;protectedboolean lazyLoadingEnabled = false;protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;// 组件注册器——四大金刚protectedfinal TypeAliasRegistry typeAliasRegistry;protectedfinal TypeHandlerRegistry typeHandlerRegistry;protectedfinal MapperRegistry mapperRegistry;protectedfinal InterceptorChain interceptorChain;// SQL 映射——所有 SQL 都在这里protectedfinal Map<String, MappedStatement> mappedStatements;protectedfinal Map<String, Cache> caches;protectedfinal Map<String, ResultMap> resultMaps;// 环境配置——数据库连接在哪protected Environment environment;

Configuration 还承担了工厂职责——newExecutor()newStatementHandler()newParameterHandler()newResultSetHandler() 这些方法都在这里。创建组件的同时,它会调用 interceptorChain.pluginAll() 给组件套上插件代理。这个设计把组件创建和插件植入统一管理了——不然代理创建逻辑散落各处,维护起来是噩梦。

六、DefaultSqlSessionFactory:启动流程的终点

回到 SqlSessionFactoryBuilder.build(),最终返回的是 DefaultSqlSessionFactory

public SqlSessionFactory build(Configuration config){returnnew DefaultSqlSessionFactory(config);}

就这么一行。DefaultSqlSessionFactory 持有 Configuration 引用,它的 openSession() 方法才是运行时的起点。但那是下一篇的故事了——这篇已经够长了。

七、初始化流程总览

把完整链路画出来,一图胜千言:

mybatis-config.xml       │       ▼SqlSessionFactoryBuilder.build()       │       ▼XMLConfigBuilder 构造  ├── 创建 XPathParser(DOM 解析 + DTD 验证)  ├── 创建 Configuration(注册内置别名和处理器)  └── 设置 parsed = false       │       ▼XMLConfigBuilder.parse()       │       ▼parseConfiguration()  ├── properties     → configuration.variables       (调料先备好)  ├── settings       → configuration 各字段           (开关先设好)  ├── typeAliases    → typeAliasRegistry              (别名注册好)  ├── plugins        → interceptorChain               (插件挂上去)  ├── objectFactory  → configuration.objectFactory    (对象工厂就位)  ├── environments   → configuration.environment      (数据源连上)  ├── typeHandlers   → typeHandlerRegistry            (类型处理器注册好)  └── mappers        → mapperRegistry + mappedStatements (SQL 映射加载完)       │       ▼new DefaultSqlSessionFactory(configuration)

八、几个值得琢磨的设计点

为什么 Configuration 用"上帝对象"而不是拆成多个小类?

Configuration 确实体量大,字段多到让人头皮发麻。但它解决了一个实际问题:各组件之间的配置是一致的。如果拆成多个配置对象,组件之间传递配置的复杂度会急剧上升——你传五个小对象进来,还得保证它们之间的数据不矛盾。MyBatis 选了简单粗暴但有效的方案:一个对象持有所有状态。在框架场景下,这是合理的权衡。就像总控室——虽然一堆屏幕看着眼花,但至少信息都集中在一个地方,不用跑来跑去。

为什么 XMLConfigBuilder 只能用一次?

因为解析过程是增量修改 Configuration 的过程。如果允许重复调用 parse(),同一个 namespace 的 Mapper 会被重复注册,mappedStatements 会出现重复 key 或覆盖。用 parsed 标志位一刀切,虽然粗暴但安全——就像一次性筷子,用完就扔,不用担心上一个人用过。

为什么 mappers 放在最后解析?

Mapper 解析依赖 typeAliases、typeHandlers、plugins 这些前置配置。比如 <resultType> 里的别名需要 TypeAliasRegistry 已就绪,<resultMap> 里的 typeHandler 需要 TypeHandlerRegistry 已就绪,插件的注册需要在 Mapper 解析之前完成。解析顺序 = 依赖顺序——先铺路,再跑车。

下篇预告

下一篇从 DefaultSqlSessionFactory.openSession() 开始,跟踪 SqlSession 的创建过程。看看 Executor 是怎么被选型和初始化的——SIMPLE、REUSE、BATCH 三兄弟到底有啥区别,还有 Mapper 接口的动态代理是怎么绑上去的。那才是 SQL 真正开始执行的地方。


本系列文章基于 MyBatis 3.5.x 源码,写作时对照源码逐行验证。如果发现有问题的地方,欢迎指正。

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-06-24 23:07:14 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/785529.html
  2. 运行时间 : 0.091654s [ 吞吐率:10.91req/s ] 内存消耗:4,832.48kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=0dab3e4bc17b2625897dc9ea927e18e8
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000660s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000841s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000352s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000283s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000543s ]
  6. SELECT * FROM `set` [ RunTime:0.000256s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000592s ]
  8. SELECT * FROM `article` WHERE `id` = 785529 LIMIT 1 [ RunTime:0.000777s ]
  9. UPDATE `article` SET `lasttime` = 1782313634 WHERE `id` = 785529 [ RunTime:0.000889s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000271s ]
  11. SELECT * FROM `article` WHERE `id` < 785529 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000534s ]
  12. SELECT * FROM `article` WHERE `id` > 785529 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000431s ]
  13. SELECT * FROM `article` WHERE `id` < 785529 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000876s ]
  14. SELECT * FROM `article` WHERE `id` < 785529 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000863s ]
  15. SELECT * FROM `article` WHERE `id` < 785529 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001310s ]
0.094291s