当前位置: 首页> 文旅> 艺术 > 网页播放的视频如何下载_常州seo收费_长沙谷歌优化_我有广告位怎么找客户

网页播放的视频如何下载_常州seo收费_长沙谷歌优化_我有广告位怎么找客户

时间:2025/7/9 23:48:25来源:https://blog.csdn.net/Octopus21/article/details/143351988 浏览次数:0次
网页播放的视频如何下载_常州seo收费_长沙谷歌优化_我有广告位怎么找客户

文章目录

    • 介绍
    • XMLScriptBuilder初始化
    • parseDynamicTags解析动态节点
    • RawSqlSource分析
      • 代码分析
      • 实例化

介绍

代码入口:

SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);

languageRegistry:用于注册LanguageDriver,LanguageDriver用于解析SQL配置,将配置信息转换为SqlSource对象。

MyBatis中的SqlSource用于描述SQL资源,MyBatis可以通过两种方式配置SQL信息,一种是通过@Selelect、@Insert、@Delete、@Update或者@SelectProvider、@InsertProvider、@DeleteProvider、@UpdateProvider等注解;另一种是通过XML配置文件。SqlSource就代表Java注解或者XML文件配置的SQL资源。

public interface SqlSource {BoundSql getBoundSql(Object parameterObject);}

SqlSource接口的定义非常简单,只有一个getBoundSql()方法,该方法返回一个BoundSql实例。BoundSql是对SQL语句及参数信息的封装,它是SqlSource解析后的结果。如图9-1所示,SqlSource接口有4个不同的实现,分别为StaticSqlSource、DynamicSqlSource、RawSqlSource和ProviderSqlSource。

这4种SqlSource实现类的作用如下。
ProviderSqlSource:用于描述通过@Select、@SelectProvider等注解配置的SQL资源信息。DynamicSqlSource:用于描述Mapper XML文件中配置的SQL资源信息,这些SQL通常包含动态SQL配置或者${}参数占位符,需要在Mapper调用时才能确定具体的SQL语句。
RawSqlSource:用于描述Mapper XML文件中配置的SQL资源信息,与DynamicSqlSource不同的是,这些SQL语句在解析XML配置的时候就能确定,即不包含动态SQL相关配置。
StaticSqlSource:用于描述ProviderSqlSource、DynamicSqlSource及RawSqlSource解析后得到的静态SQL资源。

XMLScriptBuilder初始化

  @Overridepublic SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType) {XMLScriptBuilder builder = new XMLScriptBuilder(configuration, script, parameterType);return builder.parseScriptNode();}

在 MyBatis 源码中,initNodeHandlerMap 方法的作用是初始化一个用于处理不同节点类型的映射表(nodeHandlerMap)。每个节点类型(例如 “trim”、“where”、“set” 等)对应一个处理器(例如 TrimHandler、WhereHandler 等)。这些处理器负责解析和处理相应的 SQL 语句节点。

  private void initNodeHandlerMap() {nodeHandlerMap.put("trim", new TrimHandler());nodeHandlerMap.put("where", new WhereHandler());nodeHandlerMap.put("set", new SetHandler());nodeHandlerMap.put("foreach", new ForEachHandler());nodeHandlerMap.put("if", new IfHandler());nodeHandlerMap.put("choose", new ChooseHandler());nodeHandlerMap.put("when", new IfHandler());nodeHandlerMap.put("otherwise", new OtherwiseHandler());nodeHandlerMap.put("bind", new BindHandler());}

• trim:用于去除 SQL 语句两端的空格或特定字符。
• where:用于生成 WHERE 子句。
• set:用于生成 SET 子句,通常在更新操作中使用。
• foreach:用于处理集合中的元素,通常用于生成批量插入或更新的 SQL。
• if:用于根据条件动态生成 SQL 片段。
• choose、when、otherwise:类似于 Java 的 switch-case 语句,用于动态选择生成不同的 SQL 片段。

parseDynamicTags解析动态节点

  protected MixedSqlNode parseDynamicTags(XNode node) {List<SqlNode> contents = new ArrayList<>();NodeList children = node.getNode().getChildNodes();for (int i = 0; i < children.getLength(); i++) {XNode child = node.newXNode(children.item(i));// 如果子节点是文本节点或 CDATA 节点,提取其文本内容并创建 TextSqlNode 对象if (child.getNode().getNodeType() == Node.CDATA_SECTION_NODE|| child.getNode().getNodeType() == Node.TEXT_NODE) {String data = child.getStringBody("");TextSqlNode textSqlNode = new TextSqlNode(data);// 如果是动态的,添加到 contents 列表中,并标记为动态;否则,创建一个静态文本节点并添加if (textSqlNode.isDynamic()) {// 检查这个文本节点是否为动态,即是否包含 ${}动态表达式contents.add(textSqlNode);isDynamic = true;} else {// 将带有#{}符号的SQL封装到StaticTextSqlNode节点上contents.add(new StaticTextSqlNode(data));}} else if (child.getNode().getNodeType() == Node.ELEMENT_NODE) {// 如果子节点是元素节点,获取节点名称并查找对应的处理器(NodeHandler)String nodeName = child.getNode().getNodeName();NodeHandler handler = nodeHandlerMap.get(nodeName);if (handler == null) {throw new BuilderException("Unknown element <" + nodeName + "> in SQL statement.");}handler.handleNode(child, contents);isDynamic = true;}}// 将所有解析的 SQL 节点封装到 MixedSqlNode 对象中并返回return new MixedSqlNode(contents);}

以下面这个SQL语句作为范例进行描述解析

    select * from t_user where id = #{id}<choose><when test="name != null">AND name like #{name}</when><otherwise>AND name = #{name}</otherwise></choose>

select * from t_user where id = #{id} 文本走的是Node.TEXT_NODE
而对于 都属于Node.ELEMENT_NODE
如果子节点是元素节点,获取节点名称并查找对应的处理器(NodeHandler)

   // 如果子节点是元素节点,获取节点名称并查找对应的处理器(NodeHandler)String nodeName = child.getNode().getNodeName();// 获取对应的节点处理器NodeHandler handler = nodeHandlerMap.get(nodeName);if (handler == null) {throw new BuilderException("Unknown element <" + nodeName + "> in SQL statement.");}// 执行具体的节点处理器解析方法handler.handleNode(child, contents);isDynamic = true;

解析完各个Node节点后,封装SqlSource

  public SqlSource parseScriptNode() {// 解析动态 SQL 标签,并生成一个 MixedSqlNode 对象MixedSqlNode rootSqlNode = parseDynamicTags(context);SqlSource sqlSource;if (isDynamic) {// 如果是包含${}符号或者包含动态SQL的元素节点sqlSource = new DynamicSqlSource(configuration, rootSqlNode);} else {// 纯文本SQL,仅包含#{}sqlSource = new RawSqlSource(configuration, rootSqlNode, parameterType);}return sqlSource;}

RawSqlSource分析

代码分析

RawSqlSource 的作用是将没有动态 SQL 标签的 SQL 语句(例如 、 等)直接解析成静态 SQL,避免了动态解析的开销。它会将 SQL 中的 #{} 占位符参数解析成 StaticSqlSource,然后存储为 BoundSql 对象,以便在执行时直接使用。

  public RawSqlSource(Configuration configuration, String sql, Class<?> parameterType) {// 解析SQL语句SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);// 获取入参类型Class<?> clazz = parameterType == null ? Object.class : parameterType;//解析SQL语句sqlSource = sqlSourceParser.parse(sql, clazz, new HashMap<>());}

下面这段代码是 SqlSourceParser 的 parse 方法,它负责将包含 #{} 占位符的 SQL 字符串解析为 StaticSqlSource 对象。StaticSqlSource 表示一个纯静态的 SQL 源,适合不含动态 SQL 标签的场景。以下是对这段源码的详细分析

 public SqlSource parse(String originalSql, Class<?> parameterType, Map<String, Object> additionalParameters) {ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);String sql;if (configuration.isShrinkWhitespacesInSql()) {sql = parser.parse(removeExtraWhitespaces(originalSql));} else {sql = parser.parse(originalSql);}return new StaticSqlSource(configuration, sql, handler.getParameterMappings());}

ParameterMappingTokenHandler 是 MyBatis 中一个用于处理 #{} 占位符的处理器。它会根据 parameterType 和 additionalParameters 等信息,将 #{} 占位符替换为相应的 JDBC 参数标记(如 ?),并生成对应的 ParameterMapping 列表,用于描述每个参数的类型和属性。

GenericTokenParser 是 MyBatis 中一个通用的占位符解析器,它能够识别带有指定前后缀的占位符。这里的 parser 会针对 #{} 占位符进行解析,将匹配到的 #{} 内的内容交给 handler 处理。

通过 GenericTokenParser 对 SQL 字符串进行解析,处理 #{} 占位符。
removeExtraWhitespaces(originalSql) 方法会去除多余的空白字符,确保 SQL 语句结构更简洁。
最终的 sql 字符串中,#{} 占位符将被替换为 ?,以便后续参数绑定

解析完成后,parse 方法会返回一个 StaticSqlSource 对象。StaticSqlSource 是 MyBatis 中用于表示静态 SQL 的 SqlSource 实现,适合不包含动态逻辑的 SQL。handler.getParameterMappings() 获取所有参数的映射信息,以便在执行时能够将参数正确绑定到 SQL 的 ?占位符上。

实例化

示例SQL:

     select * from t_user where id = #{id} name = #{name}

parse 方法的整体流程是:解析 #{} 占位符,将其替换为 ?,并记录参数映射信息。

经过 parse 处理后,原始 SQL 将被替换为:select * from t_user where id = ? name = ?
在这里插入图片描述
handler.getParameterMappings() 的作用是返回一个 ParameterMapping 列表,用于描述 SQL 中的 #{} 占位符参数的映射信息。ParameterMapping 对象包含了每个参数的名称、类型、Java 属性等,这些信息在 SQL 执行时用于将实际参数绑定到 ? 占位符上。
在这里插入图片描述
ParameterMappingTokenHandler 会生成一个 ParameterMapping 列表,包含两个参数的映射信息。
在 SQL 执行时,MyBatis 会使用 parameterMappings 列表来将 User 对象中的 id 和 name 属性值绑定到 SQL 中的 ? 占位符上。
ParameterMappingTokenHandler 在解析 #{} 占位符时,会将每个参数按出现的顺序记录到 parameterMappings列表中。比如,#{id} 出现在 #{name} 之前,那么 parameterMappings 列表中,id 的映射会排在 name 之前。MyBatis 通过 parameterMappings 中记录的参数顺序、名称等信息,将参数依次正确绑定到 SQL 中的 ? 占位符上,因此在参数传递过程中能确保参数的正确替换位置。

关键字:网页播放的视频如何下载_常州seo收费_长沙谷歌优化_我有广告位怎么找客户

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: