当前位置: 首页> 教育> 幼教 > MyBatis总结(2)- MyBatis实现原理(二)

MyBatis总结(2)- MyBatis实现原理(二)

时间:2025/7/11 15:06:06来源:https://blog.csdn.net/Machiel_One/article/details/139505157 浏览次数:0次

核心配置

  • Mybatis-config.xml(基础配置)

作用

Mybatis-config.xml实现:

  1. 这在前面说过,加载解析都是在Configuration对象被创建时发生:
    org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration:
private void parseConfiguration(XNode root) {try {// issue #117 read properties firstpropertiesElement(root.evalNode("properties"));Properties settings = settingsAsProperties(root.evalNode("settings"));loadCustomVfsImpl(settings);loadCustomLogImpl(settings);typeAliasesElement(root.evalNode("typeAliases"));pluginsElement(root.evalNode("plugins"));objectFactoryElement(root.evalNode("objectFactory"));objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));reflectorFactoryElement(root.evalNode("reflectorFactory"));settingsElement(settings);// read it after objectFactory and objectWrapperFactory issue #631environmentsElement(root.evalNode("environments"));databaseIdProviderElement(root.evalNode("databaseIdProvider"));typeHandlersElement(root.evalNode("typeHandlers"));mappersElement(root.evalNode("mappers"));} catch (Exception e) {throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);}}
  1. 一个基础简单配置定义:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="db.properties"/><settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings><typeAliases><package name="org.example.pojo"/></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><mappers><mapper class="org.example.daos.UserMapper"/><mapper class="org.example.daos.TeacherMapper"/><mapper class="org.example.daos.StudentMapper"/></mappers></configuration>

具体配置标签使用

这是官网的参考链接:Mybatis配置定义
在这里,将知识转化成自己的方式理解,这才是学到了。
以下是按照自己的理解总结:

Properties

定义配置属性,一般用在对DataSource参数的设置上:

  1. 针对不同地方定义属性值的代码实现:
  • 使用java.util.Properties,put存放数值利用ConcurrentHashMap的不可重复特性,覆盖去重;
  • 加载resource/url资源配置时,通过properties #load方法直接转化,对原始转化做了个完美的语法糖:
		...// 原始基础原理:一步步的,先读取到缓冲字节区域buffer,然后经由buffer再写入/处理// 这里的buffer,我理解成:“倒爷”InputStream inputStream = getClass().getResourceAsStream(filePath);ServletOutputStream outputStream = response.getOutputStream();byte[] buffer = new byte[1024];int lens;while((lens = inputStream.read(buffer))> 0){outputStream.write(buffer, 0, lens);}...
  • 关闭资源时,可以用try-resources语句,针对实现了AutoCloseable接口的资源类,程序会在使用完资源后后台自动帮忙关闭。
  1. 具体实现:
<!-- Properties标签: URL|Resource(只能二选一)resource 属性读取**类路径**下属性文件;url 属性**指定的路径**读取属性文件properties设置有三种途径(按照优先级高低):方法参数(builder.build(..., props)) >>>> url | resource定义的配置属性 >>>> properties标签下定义的属性--><!--例子1:引入外部properties文件,设置全部属性 ${} --><properties resource="db.properties"/>读取类路径下的资源<properties url=""/>URL:可以是网络资源,也可以本地服务器资源<!--例子2:引入外部properties文件,设置部分属性 ${}--><properties resource="db1.properties"><property name="user" value="root"/><property name="pwd" value="root"/></properties><!--例子3:引入外部properties文件,设置部分属性,当属性key一致时,优先使用properties外部资源的属性 ${}--><properties resource="db.properties"><property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=true
"/><property name="driver" value="com.mysql.cj.jdbc.Driver"/></properties>

Setting

针对Mybatis一些行为的设置,记住常用的几个,其他的,用的时候查阅参考链接即可:

<settings><!--指定日志的具体实现:	STDOUT_LOGGING:  --><setting name="logImpl" value="STDOUT_LOGGING"/>标准日志输出,一般用在本地调试,可在console中查看代码的执行过程<setting name="logImpl" value="LOG4J2"/>可通过log4j2配置文件定制化日志文件<setting name="mapUnderscoreToCamelCase" value="true"/>开启驼峰映射:Column(a_b)映射为属性(aB)
</settings>

typeAliases

一个目的:起别名。简化在mapper映射关系中,指定type时,可以简化。一般会为了省掉包名,只用类名来表示。
当然针对,类名可能存在一致的问题(多module开发),那就加上包名来以示区别。

<typeAliases><!--两种方式--><!--给具体的一个javabean起别名 --><typeAlias type="org.example.pojo.User" alias="User"/><!--通过扫描pojo包来设置别名:默认javabean别名为类名的首字母小写 @Alias("user"),也可以在javabean上指定别名通过注解@Alias --><package name="org.example.pojo"/>当前包下的所有bean,就会起效</typeAliases>

应用于mapper.xml中:

<select id="getUserById" resultType="org.example.pojo.User">这里的org.example.pojo.User可以简化为User/userSELECT * FROM mybatis.user where id = #{id}
</select>

typeHandlers

  • 在从ResultSet结果集中获取值时,会用到类型处理器来做转化操作,例如:SqlDateTypeHandlerStringTypeHandler等;
  • 也可自定义实现:重写已有类型处理器,或实现TypeHandler接口,或继承BaseTypeHandler类,参考官网链接。

Plugins

这里提一下,在追代码时看到,在handler处理器处理某个逻辑时,会有一处代码:

interceptorChain.pluginAll(xxx)
这就是plugin的作用之处:利用Mybatis自定义的拦截器Interceptor,在逻辑处理前后增添自定义功能

Environment

每个数据库对应一个SqlSessionFactory实例,每个SqlSessionFactory实例只能选一种环境:

<environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment>
</environments>
  • ID: 可以设置dev,test,SIT,UAT,Stage,Prod等多个环境的配置;
  • TransactionManager:type有两种:MANAGED(默认),JDBC
  • datasource:数据源配置:UNPOOLED | POOLED | JNDI(内建的三种数据源类型),还可通过实现DataSourceFactory,扩展C3P0,DBCP,Druid.

mappers

这是涉及到下一个核心的SQL映射关系的引入:

<mappers><mapper resource="mappers/user-mappers.xml"/> <!--通过资源resource导入--><mapper class="org.example.daos.UserMapper"/> 通过class方式注入<package name="org.example.daos"/>通过package扫描注入
</mappers>

这里需要注意的是,对于将mapper配置放在src/main/java目录下的不能加载问题,第一篇初探有提到过。

总而言之,到这里会发现,(个人感慨)

  • Mybatis做的精明之处就是在于将我们原本复杂的逻辑通过config配置,在经过factory的构建,整合成一个SqlSession给到我们,我们只需要关注到业务的实现,底层的技术细节帮我们处理好了。

  • 除过Mybatis内置的功能外,还给提供了很多对外扩展的接口,比如:
    TypeHandler,plugin, DataSourceFactory, TransactionFactory&Transaction等等。

  • 学习最好的方式就是看源码,根据内置的实现,模仿着去实现自定义,就能理解其中道理;

  • 所以,技术框架的迭代,万变不离其宗,而且技术没有高低之分

  • 后面,总结Spring会发现这种扩展性的接口会更多,也为学习更多的架构层面的策略,以及技术的掌握提供很好的途径。

关键字:MyBatis总结(2)- MyBatis实现原理(二)

版权声明:

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

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

责任编辑: