乐于分享
好东西不私藏

MyBatis 源码深度拆解(六):#{} 与 ${} 底层解析 & SQL 预编译

MyBatis 源码深度拆解(六):#{} 与 ${} 底层解析 & SQL 预编译

面试官:#{} 和 ${} 有什么区别?为什么 #{} 能防 SQL 注入?MyBatis 是在哪一步把 #{} 替换成 ? 的?

一、开篇:一个最常见的问题

在 MyBatis 的 Mapper 文件或注解中,我们经常这样写:

SELECT * FROM user WHERE id = #{id}SELECT * FROM user WHERE name like '%${keyword}%'

两种占位符,一个用#{},一个用${},它们到底有什么本质区别?源码中是如何处理的?

本篇目标

  • 深入BoundSql构建过程,看清#{}如何变成?
  • 对比${}的直接拼接逻辑,解释 SQL 注入风险
  • 追踪 PreparedStatement 预编译和参数设置的全过程

二、整体流程概述

核心角色

  • SqlSource:负责解析动态 SQL,生成BoundSql
  • BoundSql:封装最终 SQL(带?)和参数映射信息
  • ParameterHandler:负责将参数设置到 PreparedStatement 中

三、BoundSql的构建入口

3.1 从 MappedStatement 获取 BoundSql

当执行查询时,Executor 需要获取 BoundSql

// MappedStatementpublic BoundSql getBoundSql(Object parameterObject) {    BoundSql boundSql = sqlSource.getBoundSql(parameterObject);    // 处理 parameterMappings 中可能缺失的参数    return boundSql;}

sqlSource接口的实现类有多种,如:

  • StaticSqlSource:静态 SQL(没有${}或动态标签)
  • DynamicSqlSource:包含${}<if>等动态元素的 SQL
  • RawSqlSource:用于封装在 XML 解析阶段就能确定下来的 SQL,可能含有 #{} 占位符,但不包含 ${} 或任何动态 SQL 标签(如 <if><where> 等),在构建时就会完成对 #{} 的解析

对于大多数动态 SQL,使用的是DynamicSqlSource

3.2 DynamicSqlSource.getBoundSql

// DynamicSqlSourcepublic BoundSql getBoundSql(Object parameterObject) {    // 1. 使用 Context 解析动态 SQL,生成最终 SQL 字符串(包含 ${} 的直接拼接和静态文本)    DynamicContext context = new DynamicContext(configuration, parameterObject);    // 在这里,${} 被替换,<if>、<foreach> 等动态标签被处理    rootSqlNode.apply(context);      // rootSqlNode 是动态 SQL 的根节点    // 2. 处理 ${} 替换后,得到包含 #{} 的 SQL    String sql = context.getSql();    // 3. 解析 #{},生成 ParameterMapping 列表,同时将 #{} 替换为 ?    SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);    Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();    SqlSource sqlSource = sqlSourceParser.parse(sql, parameterType, context.getBindings());    // 4. 获取最终的 BoundSql(此时 sql 已经是带 ? 的)    BoundSql boundSql = sqlSource.getBoundSql(parameterObject);    // 5. 将 DynamicContext 中的额外的参数(如 _parameter)复制到 BoundSql 中    context.getBindings().forEach(boundSql::setAdditionalParameter);    return boundSql;}

关键步骤在第 3 步:SqlSourceBuilder.parse 负责 将 #{} 替换成 ?,并提取参数映射

四、#{}的底层解析:SqlSourceBuilder

4.1 SqlSourceBuilder.parse 方法

// SqlSourceBuilderpublic SqlSource parse(String originalSql, Class<?> parameterType, Map<StringObject> additionalParameters) {    ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);    GenericTokenParser parser = new GenericTokenParser("#{""}", handler);    String sql;    if (configuration.isShrinkWhitespacesInSql()) {        // 可选:压缩多余空白字符,使 SQL 规范化,提高缓存命中率        sql = parser.parse(removeExtraWhitespaces(originalSql));    } else {        sql = parser.parse(originalSql);    }    return new StaticSqlSource(configuration, sql, handler.getParameterMappings());}

关键类GenericTokenParser:一个通用的标记解析器,用开放标记(如#{)和闭合标记(}),每找到一个标记对,就调用 handler 的handleToken方法处理。

  • shrinkWhitespacesInSql是一个全局配置,若开启,会在解析#{}之前先对原始 SQL 进行空白压缩(将连续空白替换为单个空格,去除首尾空白等)。
  • 这样做的好处是:即使 Mapper XML 中 SQL 格式不同(如换行、空格数量差异),最终生成的 BoundSql.sql 字符串相同,可以共享 MappedStatement 的缓存,提高命中率。

4.2 ParameterMappingTokenHandler.handleToken

// ParameterMappingTokenHandler   将实际内容简单整合了下  看源码时注意下public String handleToken(String content) {    // content 是 #{...} 里面的内容,例如 "id", "user.name", "param1"}    // 1. 解析参数名、javaType、jdbcType、typeHandler 等    ParameterMapping.Builder builder = new ParameterMapping.Builder(configuration, content, parameterType);    // ... 解析属性(javaType, jdbcType, mode, numericScale, resultMapId, typeHandler 等)    ParameterMapping mapping = builder.build();    // 2. 添加到参数映射列表    parameterMappings.add(mapping);    // 3. 替换为 ? 占位符    return "?";}

举例输入 SQL:SELECT * FROM user WHERE id = #{id} AND name = #{name}输出 SQL:SELECT * FROM user WHERE id = ? AND name = ?parameterMappings[ParameterMapping{property='id'}, ParameterMapping{property='name'}]

4.3GenericTokenParser的解析逻辑

public String parse(String text) {    if (text == null || text.isEmpty()) return "";    int start = text.indexOf(openToken);    if (start == -1return text;    char[] src = text.toCharArray();    int offset = 0;    StringBuilder builder = new StringBuilder();    StringBuilder expression = null;    do {        // 1. 检查开放标记前是否有转义符 '\'        if (start > 0 && src[start - 1] == '\\') {            // 遇到转义:去掉反斜杠,原样输出 openToken,继续            builder.append(src, offset, start - offset - 1).append(openToken);            offset = start + openToken.length();        } else {            // 2. 找到有效开放标记            builder.append(src, offset, start - offset);            offset = start + openToken.length();            // 3. 寻找闭合标记,处理转义            int end = text.indexOf(closeToken, offset);            while (end > -1) {                if (src[end - 1] != '\\') {                    // 未转义的闭合标记                    expression.append(src, offset, end - offset);                    break;                }                // 转义的闭合标记:去掉反斜杠,保留 closeToken,继续查找                expression.append(src, offset, end - offset - 1).append(closeToken);                offset = end + closeToken.length();                end = text.indexOf(closeToken, offset);            }            if (end == -1) {                // 闭合标记未找到:将剩余部分原样输出                builder.append(src, start, src.length - start);                offset = src.length;            } else {                // 4. 调用 handler 处理内容,并替换为处理结果                builder.append(handler.handleToken(expression.toString()));                offset = end + closeToken.length();            }        }        start = text.indexOf(openToken, offset);    } while (start > -1);    if (offset < src.length) {        builder.append(src, offset, src.length - offset);    }    return builder.toString();}

关键点

  • 转义支持\#{...}会被解析为文本#{...},而非占位符。这允许在 SQL 中输出#{}字面量。
  • 性能优化:使用char[]和手动偏移,避免重复创建子串。
  • 鲁棒性:处理闭合标记缺失、嵌套转义等情况。
// 示例:输入 SQL 中包含转义占位符String sql = "SELECT * FROM user WHERE name = '\\#{value}' AND id = #{id}";// 解析结果:// SELECT * FROM user WHERE name = '#{value}' AND id = ?// 注:\\#{value} 转义后变为 #{value} 字面文本,不会被处理

五、${}的底层解析:VariableTokenHandler

与 #{} 使用专门的 ParameterMappingTokenHandler 不同,${} 的处理发生在 动态 SQL 解析阶段,由对应的 TokenHandler 实现进行直接字符串替换,不产生 ?,也不收集 ParameterMapping。

5.1GenericTokenParser配合VariableTokenHandler

在 DynamicSqlSource 解析动态 SQL 时,会使用 TextSqlNode 处理文本节点,其中就包含 ${} 的解析:

// TextSqlNodepublic boolean apply(DynamicContext context) {    // 创建 GenericTokenParser,使用 ${} 标记  稍微合并了一下    GenericTokenParser parser = new GenericTokenParser("${""}"new BindingTokenParser(context, injectionFilter));    context.appendSql(parser.parse(text));    return true;}

BindingTokenParser.handleToken的实现:

// BindingTokenParser@Overridepublic String handleToken(String content) {    Object parameter = context.getBindings().get("_parameter");    if (parameter == null) {        context.getBindings().put("value"null);    } else if (SimpleTypeRegistry.isSimpleType(parameter.getClass())) {        context.getBindings().put("value", parameter);    }    // 使用 OGNL 或反射从参数对象中获取 property 的值    Object value = OgnlCache.getValue(content, context.getBindings());    // 直接返回 value 的字符串形式(null 会转为空字符串)    String srtValue = value == null ? "" : String.valueOf(value);    checkInjection(srtValue);    return srtValue;}

关键差异

  • ${}:直接获取参数值,转成字符串拼接到 SQL 中,不产生?,也不收集ParameterMapping
  • #{}:替换为 ?,收集参数映射,后续通过 PreparedStatement 设置参数

在 MyBatis 解析 SQL 时,SqlSourceBuilder.parse 会将 #{} 占位符替换为 ?,同时通过 ParameterMappingTokenHandler 收集每个 #{} 的参数属性(如参数名、Java 类型、JDBC 类型等),生成 ParameterMapping 列表并存入 BoundSql需要强调的是,这个阶段 MyBatis 不会在 SQL 字符串里给参数值加任何引号,只是单纯地替换成 ?到了执行阶段,PreparedStatementHandler或

DefaultParameterHandler会依据 ParameterMapping 的顺序,通过 PreparedStatement 的 setXxx 方法为每个 ? 设置具体的参数值。此时,JDBC 驱动会根据参数的 java.sql.Types 类型来决定如何格式化值(例如对字符串类型自动加上单引号并进行转义)。所以,“自动加引号”实际上是 JDBC 预编译机制 + 驱动实现 带来的结果,而不是 MyBatis 在 SQL 文本拼接阶段的行为。这也正是 #{} 能够安全传递参数、避免 SQL 注入的根本原因。

六、PreparedStatement预编译和参数设置

经过SqlSourceBuilder处理后,SQL 已经变成带?的形式。接下来到PreparedStatementHandler中执行。

6.1 预编译:StatementHandler.prepare

public abstract class BaseStatementHandler implements StatementHandler {    @Override    public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {        ErrorContext.instance().sql(boundSql.getSql()); // 记录即将执行的SQL        Statement statement = null;        try {            // 1. 关键步骤:调用子类实现的instantiateStatement()来创建具体的Statement对象            statement = instantiateStatement(connection);            setStatementTimeout(statement, transactionTimeout);            setFetchSize(statement);            return statement;        } catch (SQLException e) {            closeStatement(statement);            throw e;        } catch (Exception e) {            closeStatement(statement);            throw new ExecutorException("Error preparing statement.  Cause: " + e, e);        }    }    // 抽象方法,留给子类去实现,用于创建具体的Statement    protected abstract Statement instantiateStatement(Connection connection) throws SQLException;}

这里获得的PreparedStatement已经完成了 SQL 预编译,数据库会保存该 SQL 的执行计划。

6.2 参数设置:ParameterHandler.setParameters

// DefaultParameterHandlerpublic void setParameters(PreparedStatement ps) {    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();    for (int i = 0; i < parameterMappings.size(); i++) {        ParameterMapping mapping = parameterMappings.get(i);        String propertyName = mapping.getProperty();        Object value = 从参数对象中获取 propertyName 的值;        // 根据 jdbcType 和 typeHandler 设置参数        typeHandler.setParameter(ps, i + 1, value, jdbcType);    }}

#{} 产生的 ParameterMapping 告诉 MyBatis:第 i+1 个 ? 应该填入什么值,使用什么类型处理器。

七、#{} 与 ${} 完整对比

维度

#{}

${}

处理时机

SQL 解析阶段(SqlSourceBuilder

动态 SQL 解析阶段(TextSqlNode

处理方式

替换为 ?,收集 ParameterMapping

直接拼接参数值的字符串表示

预编译

是(PreparedStatement

否(普通 Statement,或拼接后再预编译)

SQL 注入风险

(参数值与 SQL 结构分离)

(参数值改变 SQL 结构)

适用场景

几乎所有参数传递

表名、列名、ORDER BY 字段等无法使用占位符的地方

缓存影响

相同的 SQL 模板可缓存(参数不同不影响)

SQL 字符串直接变化,不易命中缓存

SQL 注入示例

-- 使用 ${}SELECT * FROM user WHERE name = '${name}'-- 如果 name 传入 ' OR '1'='1,SQL 变为:SELECT * FROM user WHERE name = '' OR '1'='1'   -- 永远为真,返回所有用户-- 使用 #{}SELECT * FROM user WHERE name = #{name}-- 传入同样的值,预编译后:SELECT * FROM user WHERE name = ?-- 参数值被当作字符串字面量,' OR '1'='1 不会改变 SQL 结构

八、源码级风险验证:${}的危险性

在 MyBatis 源码中,如果错误使用 ${},会导致 SQL 注入。例如在 Mapper XML 中:

<select id="findUser" resultType="User">    SELECT * FROM user WHERE name = '${name}'</select>

name = "xxx' OR '1'='1"时,最终生成的 SQL 为:

SELECT * FROM user WHERE name = 'xxx' OR '1'='1'

这是因为 ${} 处理时,只是简单调用 String.valueOf(value),不做任何转义,直接拼接到 SQL 字符串中。

九、面试高频题

Q1:#{}是如何防止 SQL 注入的?

A#{}在解析阶段被替换成?,后续使用PreparedStatement设置参数。PreparedStatement会将参数值进行转义类型安全处理,确保参数值不会改变 SQL 结构。例如字符串参数中的单引号会被自动转义,从而避免了 SQL 注入。

Q2:${}在什么场景下必须使用?

A:当需要动态传入数据库对象名(如表名、列名、排序字段)时,不能使用#{},因为?占位符只能用于值,不能用于标识符。例如:

  • SELECT * FROM ${tableName}
  • ORDER BY ${columnName} ${orderType}

Q3:MyBatis 如何处理动态 SQL 中的${}嵌套#{}

A:解析顺序是先处理${}(在DynamicSqlSource阶段),再处理#{}(在SqlSourceBuilder阶段)。所以${}中可以包含#{}?这通常不推荐,因为${}替换后可能破坏#{}的结构,造成解析错误。

Q4:BoundSql中的parameterMappings是如何生成的?

A:由ParameterMappingTokenHandler在解析#{}时依次收集。每一个#{}产生一个ParameterMapping,记录属性名、javaType、jdbcType、typeHandler 等信息,用于后续设置参数。

Q5:使用#{}时,参数值为 null 会怎么办?

A:MyBatis 会使用jdbcType决定如何处理。如果配置了jdbcType(如#{name, jdbcType=VARCHAR}),则按指定类型设置 null;如果没有指定,某些数据库驱动可能报错(如 Oracle 需要明确jdbcType)。一般建议设置全局配置jdbcTypeForNull=NULL


十、下篇预告

第 7 篇我们将深入一级缓存,彻底拆解:

  • 一级缓存的存储结构(PerpetualCache+HashMap
  • 缓存 Key 的生成规则(CacheKey的组成)
  • 一级缓存何时命中、何时失效
  • 为什么一级缓存是 SqlSession 级别

如果觉得有帮助,欢迎点赞、在看、转发支持!

系列持续更新,关注不走丢 👇

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-11 14:11:59 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/850117.html
  2. 运行时间 : 0.089588s [ 吞吐率:11.16req/s ] 内存消耗:4,672.52kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=a38e0130c0fc936002c6bd31dabac8e7
  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.000424s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000643s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000299s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000249s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000481s ]
  6. SELECT * FROM `set` [ RunTime:0.000196s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000527s ]
  8. SELECT * FROM `article` WHERE `id` = 850117 LIMIT 1 [ RunTime:0.002268s ]
  9. UPDATE `article` SET `lasttime` = 1783750319 WHERE `id` = 850117 [ RunTime:0.002146s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000247s ]
  11. SELECT * FROM `article` WHERE `id` < 850117 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000510s ]
  12. SELECT * FROM `article` WHERE `id` > 850117 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001154s ]
  13. SELECT * FROM `article` WHERE `id` < 850117 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000707s ]
  14. SELECT * FROM `article` WHERE `id` < 850117 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001551s ]
  15. SELECT * FROM `article` WHERE `id` < 850117 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000630s ]
0.091337s