Mybatis初始化过程中深度解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Mybatis初始化过程中深度解析

Mybatis的初始化过程,就是组装Configuration的过程,在这个过程中,用到了一些工具,我列举了六个基本工具,如图所示。

 

 

图中展示了XMLConfigBuilder为了组装出Configuration对象所作出的努力,配备了至少六个基本工具。本文的重点,就是分析这六个工具的作用。

 

好怕怕啊,一下子分析六个那么多。别怕,每个工具不超过三行代码,你就会彻底明白(相信你自己)。

 

1. ObjectFactory

 

 

ObjectFactory objectFactory = new DefaultObjectFactory();List<String> list = objectFactory.create(ArrayList.class);list.add("apple");System.out.println(list);

 

out put:[apple]

 

ObjectFactory:反射创建对象工厂类。

 

2. Reflector、Invoker、ReflectorFactory

 

 

ObjectFactory objectFactory = new DefaultObjectFactory();

 

Student student = objectFactory.create(Student.class);

 

Reflector reflector = new Reflector(Student.class);Invoker invoker = reflector.getSetInvoker("studId");invoker.invoke(student, new Object[] { 20 });invoker = reflector.getGetInvoker("studId");System.out.println("studId=" + invoker.invoke(student, null));

 

output:studId=20

 

代码逻辑:使用默认构造方法,反射创建一个Student对象,反射获得studId属性并赋值为20,System.out输出studId的属性值。

 

(Made In Intellij Idea IDE)

 

Invoker:反射类Class的Method、Field封装。

GetFieldInvoker等于从Field取值:field.get(obj)。

 

SetFieldInvoker等于给Field赋值:field.set(obj, args[0])。

 

MethodInvoker等于Method方法调用:method.invoke(obj, args)。

 

Reflector:保存一个类Class的反射Invoker信息集合。

 

DefaultReflectorFactory。

 

private final ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<Class<?>, Reflector>();

缓存了多个类Class的反射器Reflector。(避免一个类,多次重复反射)

 

3. XPath、EntityResolver

 

 

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>  <settings>    <setting name="defaultExecutorType" value="REUSE" />    <setting name="defaultStatementTimeout" value="25000" />  </settings>  <mappers>    <mapper resource="com/mybatis3/mappers/StudentMapper.xml" />    <mapper resource="com/mybatis3/mappers/TeacherMapper.xml" />  </mappers></configuration>

 

XPath,是针对Xml的“正则表达式”。

 

我们使用XPath技术,来编写一个小例子。

 

 

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();builderFactory.setValidating(false);

 

DocumentBuilder builder = builderFactory.newDocumentBuilder();// builder.setEntityResolver(new XMLMapperEntityResolver());InputSource inputSource = new InputSource(Resources.getResourceAsStream("mybatis-config.xml"));

 

Document document = builder.parse(inputSource);

 

XPathFactory xPathFactory = XPathFactory.newInstance();XPath xpath = xPathFactory.newXPath();String value = (String) xpath.evaluate("/configuration/settings/setting[@name='defaultStatementTimeout']/@value", document, XPathConstants.STRING);

 

System.out.println("defaultStatementTimeout=\"" + value + "\"");

 

Node node = (Node) xpath.evaluate("/configuration/mappers/mapper[1]", document, XPathConstants.NODE);NamedNodeMap attributeNodes = node.getAttributes();for (int i = 0; i < attributeNodes.getLength(); i++) {  Node n = attributeNodes.item(i);  System.out.println(n.getNodeName() + "=\"" + n.getNodeValue() + "\"");}

 

output:defaultStatementTimeout="25000"resource="com/mybatis3/mappers/StudentMapper.xml"

/configuration/settings/setting[@name='defaultStatementTimeout']/@value

 

含义为:取configuration下面的settings下面的属性name值等于defaultStatementTimeout的setting节点的value属性值。

 

/configuration/mappers/mapper[1]

 

含义为:取configuration下面的mappers下面的第1个mapper节点。

 

XPathConstants.STRING:说明获取的目标对象是一个String值。

 

XPathConstants.NODE:说明获取的目标对象是一个Node节点。

 

如果使用上面的代码运行XPath,程序将像蜗牛一样缓慢,问题原因是Xml内部的:

 

 

http://mybatis.org/dtd/mybatis-3-config.dtd

JDK会使用网络,去上面这个地址下载dtd文件,并解析,所以慢的像蜗牛(和网络环境有关)。

 

 

builder.setEntityResolver(new XMLMapperEntityResolver());

加入上面这句话,程序瞬间快如闪电。XMLMapperEntityResolver是Mybatis针对EntityResolver的实现类,它从本地环境去寻找dtd文件,而不是去网络上下载,所以,速度飞快。

 

Mybatis就是通过上面六个工具,去读取配置文件的。工具虽多,但架不住我三两句话把它描述清楚,避免长篇大论。

 

4. Mybatis中的XNode和XPathParser

 

上面有关XPath的例子,示例了解析一个String和一个Node。假设我想要解析Float类型和List<Node>集合,那么需要简单封装一下。

 

 

public Float evalFloat(Object root, String expression) {    return Float.valueOf((String)(xpath.evaluate(expression, root, XPathConstants.STRING)));}public List<Node> evalNodes(Object root, String expression) {      NodeList nodeList = (NodeList) xpath.evaluate(expression, document, XPathConstants.NODESET);      List<Node> list = new ArrayList<Node>();      for (int i = 0; i < nodeList.getLength(); i++) {        Node n = nodeList.item(i);        list.add(n);      }      return list;}

除了Float和List<Node>,可能还有Integer、Double、Long等类型,于是,Mybatis把这些方法封装到一个类中,取名叫XPathParser。

 

在面对一个Node时,假设我想要把Node的属性集合都以键、值对的形式,放到Properties对象里,同时把Node的body体也通过XPathParser解析出来,并保存起来(一般是Sql语句),方便程序使用,代码可能会是这样的。

 

 

private Node node;private String body;private Properties attributes;private XPathParser xpathParser;

Mybatis又把上面几个必要属性封装到一个类中,取名叫XNode。

 

这就是这俩兄弟的来历。概念多了易乱,可以忽视XNode和XPathParser的存在,心中只有Node和XPath。

相关文章
|
2月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
31 3
|
2月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
47 3
|
2月前
|
Python
深入解析 Python 中的对象创建与初始化:__new__ 与 __init__ 方法
深入解析 Python 中的对象创建与初始化:__new__ 与 __init__ 方法
19 1
|
4月前
|
安全 Java 数据库连接
后端框架的学习----mybatis框架(3、配置解析)
这篇文章详细介绍了MyBatis框架的核心配置文件解析,包括环境配置、属性配置、类型别名设置、映射器注册以及SqlSessionFactory和SqlSession的生命周期和作用域管理。
后端框架的学习----mybatis框架(3、配置解析)
|
6月前
|
Java 关系型数据库 数据库连接
【MyBatis】初步解析MyBatis:实现数据库交互与关系映射的全面指南
【MyBatis】初步解析MyBatis:实现数据库交互与关系映射的全面指南
352 1
|
6月前
|
SQL Java 数据库连接
MyBatis插件深度解析:功能、原理、使用、应用场景与最佳实践
MyBatis插件深度解析:功能、原理、使用、应用场景与最佳实践
|
6月前
|
SQL Java 数据库连接
Mybatis日志SQL解析
Mybatis日志SQL解析
|
6月前
|
SQL Java 数据库连接
【MyBatis】深入解析MyBatis:高效操作数据库技术详解
【MyBatis】深入解析MyBatis:高效操作数据库技术详解
46 0
|
2月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
119 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
2月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
56 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块

推荐镜像

更多
下一篇
无影云桌面