当前位置: 首页 > news >正文

网站怎么吸引流量郴州优化公司

网站怎么吸引流量,郴州优化公司,wordpress不让收录文件是哪个,山东建设网站1. 目录结构 XNode类#xff1a; 作用#xff1a;XNode 类表示XML文档中的一个节点#xff08;Element或Node#xff09;#xff0c;它用于封装XML节点的信息#xff0c;例如标签名、属性和子节点等。使用场景#xff1a;MyBatis使用 XNode 来解析XML配置文件中的各种元…1. 目录结构 XNode类 作用XNode 类表示XML文档中的一个节点Element或Node它用于封装XML节点的信息例如标签名、属性和子节点等。使用场景MyBatis使用 XNode 来解析XML配置文件中的各种元素如select, update, insert, delete等并提供了一种方便的方式来访问这些元素的属性和子元素。 PropertyParser类 作用PropertyParser 类是MyBatis用于解析属性表达式的工具类。属性表达式是在XML配置文件中引用JavaBean属性的方式通常用于动态SQL。使用场景MyBatis在解析动态SQL语句或属性表达式时会使用 PropertyParser 来解析${}和#{}中的属性表达式并将其替换为实际的属性值或SQL参数。 GenericTokenParser类 作用GenericTokenParser 类是MyBatis用于解析通用占位符例如${}和#{}的工具类。它允许你指定一个TokenHandler接口的实现用于处理占位符内的内容。使用场景MyBatis在解析SQL语句中的占位符时会使用 GenericTokenParser 来查找和替换占位符内的内容然后将处理后的SQL语句返回。 ParsingException类 作用ParsingException 类是MyBatis中的自定义异常类用于表示解析过程中的异常情况。它通常用于捕获和处理解析XML配置文件或SQL语句时可能发生的错误。使用场景当MyBatis在解析配置文件或SQL语句时遇到不合法的语法或结构时会抛出 ParsingException 异常以便开发者识别和处理问题。 TokenHandler接口 作用TokenHandler 接口是一个回调接口定义了如何处理占位符内的内容。它用于与 GenericTokenParser 类一起工作允许开发者自定义处理占位符内部内容的逻辑。使用场景当MyBatis使用 GenericTokenParser 解析占位符时它会调用 TokenHandler 接口的实现来处理占位符内的内容。开发者可以实现自定义的 TokenHandler 来定义处理逻辑例如从配置文件或参数中获取属性值。 XPathParser类 作用XPathParser 类是MyBatis中的XML解析工具用于解析XML配置文件和映射文件。它提供了一种方便的方式来处理XML文档包括节点遍历、属性获取、XPath表达式解析等。使用场景XPathParser 类通常用于加载和解析MyBatis的XML配置文件例如mybatis-config.xml和映射文件。它允许MyBatis以一种结构化的方式访问和操作XML配置文件中的内容。 2. XPathParser类 参数 XPathParser 类通常用于加载和解析MyBatis的XML配置文件例如mybatis-config.xml和映射文件。它允许MyBatis以一种结构化的方式访问和操作XML配置文件中的内容。 public class XPathParser {private final Document document;private boolean validation;private EntityResolver entityResolver;private Properties variables;private XPath xpath;//省略 }document属性XML 被解析后生成的org.w3c.dom.Document对象。 validation 属性是否校验 XML 。一般情况下值为 true 。 entityResolver属性org.xml.sax.EntityResolver对象XML 实体解析器。默认情况下对 XML 进行校验时会基于 XML 文档开始位置指定的 DTD 文件或 XSD 文件。例如说解析mybatis-config.xml 配置文件时会加载http://mybatis.org/dtd/mybatis-3-config.dtd这个 DTD 文件。但是如果每个应用启动都从网络加载该 DTD 文件势必在弱网络下体验非常下甚至说应用部署在无网络的环境下还会导致下载不下来那么就会出现 XML 校验失败的情况。所以在实际场景下MyBatis 自定义了 [EntityResolver](# 3. XMLMapperEntityResolver) 的实现达到使用本地DTD 文件从而避免下载网络DTD 文件的效果. xpath 属性javax.xml.xpath.XPath 对象用于查询 XML 中的节点和元素。如果对 XPath 的使用不了解的胖友请先跳转 《Java XPath 解析器 - 解析 XML 文档》 中进行简单学习灰常简单。 variables 属性变量 Properties 对象用来替换需要动态配置的属性值。例如 dataSource typePOOLEDproperty namedriver value${driver}/property nameurl value${url}/property nameusername value${username}/property namepassword value${password}/ /dataSourcevariables 的来源即可以在常用的 Java 配置文件中配置也可以使用 MyBatis property / 标签进行配置。例如 properties resourceorg/mybatis/example/config.propertiesproperty nameusername valuedev_user/property namepassword valueF2Fa3!33TYyg/ /properties这里配置的 username 和 password 属性就可以替换上面的 ${username} 和 ${password} 这两个动态属性。具体如何实现的可以看下面的 PropertyParser#parse(String string, Properties variables) 方法。 构造方法 解释完属性后,我们可以看见后面有一长串的构造方法,挑选其中一个 /*** 构造 XPathParser 对象** param xml XML 文件地址* param validation 是否校验 XML* param variables 变量 Properties 对象* param entityResolver XML 实体解析器*/ public XPathParser(String xml, boolean validation, Properties variables, EntityResolver entityResolver) {//1. 公共构造方法commonConstructor(validation, variables, entityResolver);//2. 创建document对象,将xml文件解析成一个document对象this.document createDocument(new InputSource(new StringReader(xml))); }private void commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver) {this.validation validation;this.entityResolver entityResolver;this.variables variables;// 创建 XPathFactory 对象XPathFactory factory XPathFactory.newInstance();this.xpath factory.newXPath(); }/*** 创建 Document 对象,这里就是简单的调用别人提供的java xml api,就像我们调用netty提供的api那样** param inputSource XML 的 InputSource 对象* return Document 对象*/ private Document createDocument(InputSource inputSource) {// important: this must only be called AFTER common constructortry {// 1. 创建 DocumentBuilderFactory 对象DocumentBuilderFactory factory DocumentBuilderFactory.newInstance();// 设置是否验证 XMLfactory.setValidating(validation); factory.setNamespaceAware(false);factory.setIgnoringComments(true);factory.setIgnoringElementContentWhitespace(false);factory.setCoalescing(false);factory.setExpandEntityReferences(true);// 2. 创建 DocumentBuilder 对象DocumentBuilder builder factory.newDocumentBuilder();// 设置实体解析器builder.setEntityResolver(entityResolver); // 实现都空的builder.setErrorHandler(new ErrorHandler() { Overridepublic void error(SAXParseException exception) throws SAXException {throw exception;}Overridepublic void fatalError(SAXParseException exception) throws SAXException {throw exception;}Overridepublic void warning(SAXParseException exception) throws SAXException {}});// 3. 解析 XML 文件return builder.parse(inputSource);} catch (Exception e) {throw new BuilderException(Error creating document instance. Cause: e, e);} }至此,我们可以通过构造方法创建一个对象对xml文件进行解析 例如,在org.apache.ibatis.parsing.XPathParserTest#shouldTestXPathParserMethods方法中,我们可以通过测试代码解析nodelet_test.xml中的元素,通过构造方法后获得的XPathParser对象已经对xml文件进行解析,如下 eval元素 eval 元素的方法用于获得 Boolean、Short、Integer、Long、Float、Double、String 类型的元素的值。我们以 #evalString(Object root, String expression) 方法为例子代码如下 public String evalString(Object root, String expression) {// 1. 获得指定元素或节点的值String result (String) evaluate(expression, root, XPathConstants.STRING);// 2. 基于 variables 替换动态值如果 result 为动态值,还记得variables是什么吗?Properties 对象用来替换需要动态配置的属性值。result PropertyParser.parse(result, variables);return result; }/*** 获得指定元素或节点的值,例如在上例中箭头所指表达式为/employee/id , 节点为[#document:null] , 返回类型为String,那么返回的结果就是result ${id_var}** param expression 表达式* param root 指定节点* param returnType 返回类型* return 值*/ private Object evaluate(String expression, Object root, QName returnType) {try {return xpath.evaluate(expression, root, returnType);} catch (Exception e) {throw new BuilderException(Error evaluating XPath. Cause: e, e);} }在这里没有使用动态替换,因此即便result “${id_var}”,在经过PropertyParser#parse(String string, Properties variables)进行动态解析后,结果依然保持不变. 除了上面的vealString之类的方法,还有一个evalNode()方法,用户获得Node类型的节点的值,代码如下 //返回 Node 数组 public ListXNode evalNodes(String expression) { return evalNodes(document, expression); }public ListXNode evalNodes(Object root, String expression) {// 1. 封装成 XNode 数组ListXNode xnodes new ArrayList();// 2. 获得 Node 数组NodeList nodes (NodeList) evaluate(expression, root, XPathConstants.NODESET);for (int i 0; i nodes.getLength(); i) {xnodes.add(new XNode(this, nodes.item(i), variables));}return xnodes; }//返回 Node 对象 public XNode evalNode(String expression) { return evalNode(document, expression); }public XNode evalNode(Object root, String expression) {//1. 获得 Node 对象Node node (Node) evaluate(expression, root, XPathConstants.NODE);if (node null) {return null;}//2. 封装成 XNode 对象return new XNode(this, node, variables); }1处,返回结果有 Node 对象和数组两种情况根据方法参数 expression 需要获取的节点不同。 2处,会将结果Node封装为org.apache.ibatis.parsing.XNode对象,主要为了动态值的替换,例如测试方法org.apache.ibatis.parsing.XPathParserTest#shouldTestXPathParserMethods调用parser.evalNode(/employee/id).toString().trim()这条语句时,会产生下面的一个XNode对象,也就是获取xml文件中id节点的值了 3. XMLMapperEntityResolver MyBatis 自定义 EntityResolver 实现类用于加载本地的 mybatis-3-config.dtd 和 mybatis-3-mapper.dtd 这两个 DTD 文件。 简单介绍一下DTD文件的作用,菜教程 DTD文件用于验证和定义相应的XML文件的结构和规则以确保XML文件的正确性和一致性。解析器会根据publicId和systemId来决定使用哪个DTD文件进行验证。 mybatis-config.dtd 定义了MyBatis配置文件中允许的元素和属性包括数据源配置、事务管理器配置、映射器配置等。mybatis-mapper.dtd 定义了映射文件中允许的元素和属性包括SQL语句、参数映射、结果映射等。 public class XMLMapperEntityResolver implements EntityResolver {private static final String IBATIS_CONFIG_SYSTEM ibatis-3-config.dtd;private static final String IBATIS_MAPPER_SYSTEM ibatis-3-mapper.dtd;private static final String MYBATIS_CONFIG_SYSTEM mybatis-3-config.dtd;private static final String MYBATIS_MAPPER_SYSTEM mybatis-3-mapper.dtd;/*** 本地 mybatis-config.dtd 文件*/private static final String MYBATIS_CONFIG_DTD org/apache/ibatis/builder/xml/mybatis-3-config.dtd;/*** 本地 mybatis-mapper.dtd 文件*/private static final String MYBATIS_MAPPER_DTD org/apache/ibatis/builder/xml/mybatis-3-mapper.dtd;/*** 将公共DTD转换为本地DTD** param publicId publicId 是DTD声明中的 PUBLIC 标识符。它用于指定一个公共标准的标识符通常用于引用在公共资源中定义的DTD。* param systemId 是DTD声明中的 SYSTEM 标识符。它用于指定一个系统标准的标识符通常用于引用本地文件系统或远程资源中的DTD。* return The InputSource for the DTD** throws org.xml.sax.SAXException If anything goes wrong*/Overridepublic InputSource resolveEntity(String publicId, String systemId) throws SAXException {try {if (systemId ! null) {String lowerCaseSystemId systemId.toLowerCase(Locale.ENGLISH);// 本地 mybatis-config.dtd 文件if (lowerCaseSystemId.contains(MYBATIS_CONFIG_SYSTEM) || lowerCaseSystemId.contains(IBATIS_CONFIG_SYSTEM)) {return getInputSource(MYBATIS_CONFIG_DTD, publicId, systemId);// 本地 mybatis-mapper.dtd 文件} else if (lowerCaseSystemId.contains(MYBATIS_MAPPER_SYSTEM) || lowerCaseSystemId.contains(IBATIS_MAPPER_SYSTEM)) {return getInputSource(MYBATIS_MAPPER_DTD, publicId, systemId);}}return null;} catch (Exception e) {throw new SAXException(e.toString());}}private InputSource getInputSource(String path, String publicId, String systemId) {InputSource source null;if (path ! null) {try {// 创建 InputSource 对象InputStream in Resources.getResourceAsStream(path);source new InputSource(in);// 设置 publicId、systemId 属性source.setPublicId(publicId);source.setSystemId(systemId);} catch (IOException e) {// ignore, null is ok}}return source;}}4. GenericTokenParser 在初识mybatis源码时,我会产生这样的疑惑,这里的Token指的是什么,与SpringSecurity中的Token的区别是什么? 在GPT之后,给出如下解释 在 MyBatis 中“token” 通常指的是通用标记解析器GenericTokenParser中的占位符标记用于解析 SQL 语句或其他文本中的占位符例如 ${variable} 或 #{parameter}。这些占位符标记允许你在 SQL 语句中插入变量或参数值以动态生成 SQL 查询语句。通用标记解析器会将这些标记替换为实际的值从而生成最终的 SQL 语句。MyBatis 使用这种机制来支持参数化查询和动态 SQL。在 Spring Security 中“token” 通常指的是认证令牌Authentication Token或访问令牌Access Token的概念。这些令牌用于身份验证和授权用于验证用户的身份并控制用户对资源的访问。Spring Security 使用这种机制来保护应用程序的安全性实现认证和授权功能。 public class GenericTokenParser {// 开放令牌例如 ${private final String openToken;// 关闭令牌例如 }private final String closeToken;// 用于处理找到的令牌的处理器private final TokenHandler handler;// 构造函数接收开放令牌关闭令牌和令牌处理器作为参数public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {this.openToken openToken;this.closeToken closeToken;this.handler handler;}// 解析文本的方法public String parse(String text) {// 如果文本为空直接返回空字符串if (text null || text.isEmpty()) {return ;}// 搜索开放令牌的位置int start text.indexOf(openToken);// 如果没有找到开放令牌直接返回原文本if (start -1) {return text;}// 把文本转换为字符数组char[] src text.toCharArray();int offset 0;// 用于构建结果的字符串构建器final StringBuilder builder new StringBuilder();// 用于构建找到的令牌的字符串构建器StringBuilder expression null;// 当还能找到开放令牌时执行循环while (start -1) {// 如果开放令牌前面是反斜杠那么这个开放令牌是转义的需要忽略if (start 0 src[start - 1] \\) {// 添加转义的开放令牌builder.append(src, offset, start - offset - 1).append(openToken);offset start openToken.length();} else {// 找到开放令牌开始搜索关闭令牌if (expression null) {expression new StringBuilder();} else {expression.setLength(0);}// 添加开放令牌前面的文本builder.append(src, offset, start - offset);offset start openToken.length();int end text.indexOf(closeToken, offset);// 当还能找到关闭令牌时执行循环while (end -1) {// 如果关闭令牌前面是反斜杠那么这个关闭令牌是转义的需要忽略if (end offset src[end - 1] \\) {// 添加转义的关闭令牌expression.append(src, offset, end - offset - 1).append(closeToken);offset end closeToken.length();end text.indexOf(closeToken, offset);} else {// 添加关闭令牌前面的令牌文本expression.append(src, offset, end - offset);offset end closeToken.length();break;}}if (end -1) {// 如果没有找到关闭令牌添加剩余的文本builder.append(src, start, src.length - start);offset src.length;} else {// 添加处理后的令牌builder.append(handler.handleToken(expression.toString()));offset end closeToken.length();}}// 搜索下一个开放令牌start text.indexOf(openToken, offset);}// 添加剩余的文本if (offset src.length) {builder.append(src, offset, src.length - offset);}// 返回构建的字符串return builder.toString();} }测试案例org.apache.ibatis.parsing.GenericTokenParserTest 像上面两幅图那样,就可以把我们xml文件中诸如#{id}通过反射去转换为具体的id内容了,再去看看带有转义字符的 5. PropertyParser public class PropertyParser {private static final String KEY_PREFIX org.apache.ibatis.parsing.PropertyParser.;/*** 特殊属性键指示是否在占位符上启用默认值。* p* 默认值为false 表示禁用占位符上的默认值如果指定true 则可以在占位符上指定键和默认值例如${db.username:postgres} 。* /p** since 3.4.2*/public static final String KEY_ENABLE_DEFAULT_VALUE KEY_PREFIX enable-default-value;/*** 特殊属性键用于指定占位符上键和默认值的分隔符。* p* 默认分隔符是: 。* /p** since 3.4.2*/public static final String KEY_DEFAULT_VALUE_SEPARATOR KEY_PREFIX default-value-separator;private static final String ENABLE_DEFAULT_VALUE false;private static final String DEFAULT_VALUE_SEPARATOR :;private PropertyParser() {// Prevent Instantiation}//1.public static String parse(String string, Properties variables) {VariableTokenHandler handler new VariableTokenHandler(variables);GenericTokenParser parser new GenericTokenParser(${, }, handler);return parser.parse(string);}//2.private static class VariableTokenHandler implements TokenHandler {private final Properties variables; // 存储变量的属性private final boolean enableDefaultValue; // 是否启用默认值private final String defaultValueSeparator; // 默认值分隔符private VariableTokenHandler(Properties variables) {this.variables variables;// 解析属性值获取是否启用默认值和默认值分隔符this.enableDefaultValue Boolean.parseBoolean(getPropertyValue(KEY_ENABLE_DEFAULT_VALUE, ENABLE_DEFAULT_VALUE));this.defaultValueSeparator getPropertyValue(KEY_DEFAULT_VALUE_SEPARATOR, DEFAULT_VALUE_SEPARATOR);}private String getPropertyValue(String key, String defaultValue) {// 获取属性值如果属性为空则使用默认值return (variables null) ? defaultValue : variables.getProperty(key, defaultValue);}Overridepublic String handleToken(String content) {if (variables ! null) {String key content;if (enableDefaultValue) {final int separatorIndex content.indexOf(defaultValueSeparator);String defaultValue null;if (separatorIndex 0) {key content.substring(0, separatorIndex);defaultValue content.substring(separatorIndex defaultValueSeparator.length());}if (defaultValue ! null) {// 如果启用了默认值并且默认值存在则返回属性值或默认值return variables.getProperty(key, defaultValue);}}if (variables.containsKey(key)) {// 如果属性中包含该键则返回属性值return variables.getProperty(key);}}// 如果属性为空或属性中不包含该键则返回原始的标记内容return ${ content };}}}先看看1处的代码,它主要是 创建一个VariableTokenHandler对象 创建一个[GenericTokenParser](# 4. GenericTokenParser) 调用org.apache.ibatis.parsing.GenericTokenParser#parse方法对对象进行动态替换,从而完成动态映射的功能 再来看看2处的代码,它是org.apache.ibatis.parsing.TokenHandler的实现类,主要用于定义一些动态字符串的映射规则,例如将id-123456. 测试代码org.apache.ibatis.parsing.PropertyParserTest 写在后面,这里会有很多借鉴的内容,有以下三个原因 本博客只是作为本人学习记录并用以分享,并不是专业的技术型博客笔者是位刚刚开始尝试阅读源码的人,对源码的阅读流程乃至整体架构并不熟悉,观看他人博客可以帮助我快速入门如果只是笔者自己观看,难免会有很多弄不懂乃至理解错误的地方,观看他人的体会能有效改善这个问题
http://www.huolong8.cn/news/353372/

相关文章:

  • 中国建设网站下载主题猫-wordpress
  • 网站打开慢 可以只换空间不换域名吗网站建设经济可行性分析
  • 高校二级网站建设意义装修案例分享的文案
  • 做盗版小说网站能赚钱不软件公司工资高吗
  • 南充北京网站建设华为手机应用引擎
  • 手机网站开发下拉刷新自助建站网站哪个好
  • sap.net网站开发有哪些网站可以做兼职
  • 北京免费建站网络营销用什么软件可以做网站动态
  • 局域网内网站建设网站开发app开发主营业务
  • 工商营业执照咨询电话seo优化教程
  • 门窗厂家东莞网站建设新站优化案例
  • 兴宁网站建设设计男医生给产妇做内检小说网站
  • 网址搜索ip地址上海谷歌seo公司
  • 用python怎么做网站wordpress页面侧边栏
  • pc网站建设网站设计培训学院
  • 三明做网站企业网站建设情况 文库
  • 怎么从网站知道谁做的缙云企业网站建设
  • 300元建站腾讯云网站建设教学视频教程
  • 湘西网站建设商务网站业务流程
  • 有帮忙做儿童房设计的网站吗电商网站建设哪家好
  • 网站等保需要几年一做什么网站做烘干设备好
  • 南昌营销型网站建设企业建站公司案例
  • 义乌网站制作公司电子商务公司建设网站方案
  • 做网站创业怎么样电子商务网站开发教程论文6
  • 淄博外贸网站建设海丰建设局网站
  • 网站建设信息模板下载wordpress怎么添加用户中心页面
  • 手机网站哪些功能wordpress更改固定连接404
  • 连云港网站建设的公司网站建设功
  • 北京网站优化诊断网上商城怎么购物
  • 网站建设 淄博网络推广优化培训