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

核心配置

  • 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会发现这种扩展性的接口会更多,也为学习更多的架构层面的策略,以及技术的掌握提供很好的途径。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/849420.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker构建java项目镜像

资料参考 参考自黑马教程&#xff1a;10.Docker基础-自定义镜像_哔哩哔哩_bilibili 初步准备 打包好java项目jar包&#xff0c;和Dockerfile文件一起放到指定目录下&#xff0c;后续操作都是在该目录下操作&#xff0c; 我这边是&#xff1a;/usr/local/src/train-ticket/ …

栈 数组和链表实现

stack 栈 LIFO后进先出 应用 实现递归 编辑器的撤回工作&#xff08;按下ctrl z&#xff09; 数组实现 // 列表的插入和删除从一端实现 那么就得到了栈 // array和linked lists//stack-Array based implementation #include<stdio.h> #include<stdlib.h> #def…

【git】TortoiseGitPlink Fatal Error 解决方法

背景 使用 TortoiseGit报错&#xff1a; TortoiseGitPlink Fatal Error No supported authentication methods available (server sent: publickey) 解决方法 1、有很多是重置git的秘钥解决的 2、重置ssh工具

AI-知识库搭建(一)腾讯云向量数据库使用

一、AI知识库 将已知的问答知识&#xff0c;问题和答案转变成向量存储在向量数据库&#xff0c;在查找答案时&#xff0c;输入问题&#xff0c;将问题向量化&#xff0c;匹配向量库的问题&#xff0c;将向量相似度最高的问题筛选出来&#xff0c;将答案提交。 二、腾讯云向量数…

路由器设置桥接(作为网络扩展器)

下面提到的路由器都是家用路由器 一、原理图(使用交换模式&#xff0c;有线连接) 二、无线连接 &#xff08;副路由器的无线信号 连接 主路由器的无线信号&#xff09; 三、注意事项 1、路由器之前配置过怎么办&#xff1f; 长按重置键7秒&#xff0c;重置路由器 2.副路由…

python脚本打包为exe并在服务器上设置定时执行

python脚本打包为exe并在服务器上设置定时执行 1. Python脚本打包2. 将打包好的Python脚本放入服务器3. 在服务器上设置其定时执行 1. Python脚本打包 首先&#xff0c;下载pyinstaller 键盘winR打开终端&#xff0c;输入命令&#xff1a;pip install pyinstaller&#xff0c;…

谷歌的AI大变革:商业模式转型

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

界面控件DevExpress WinForms的流程图组件 - 可完美复制Visio功能(二)

DevExpress WinForms的Diagram&#xff08;流程图&#xff09;组件允许您复制Microsoft Visio中的许多功能&#xff0c;并能在下一个Windows Forms项目中引入信息丰富的图表、流程图和组织图。 P.S&#xff1a;DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows F…

【论文速读】| BIOCODER:一个具有上下文实用知识的生物信息学代码生成基准测试

本次分享论文&#xff1a;BIOCODER: A Benchmark for Bioinformatics Code Generation with Contextual Pragmatic Knowledge 基本信息 原文作者&#xff1a;Xiangru Tang, Bill Qian, Rick Gao, Jiakang Chen, Xinyun Chen, Mark Gerstein 作者单位&#xff1a;耶鲁大学, Go…

爬取基金收盘价并用pyecharts进行展现

爬取基金收盘价并用pyecharts进行展现 一、用到的第三方包 因为使用到了一些第三方的包&#xff0c;包还是比较大的如果直接从社区下载比较费劲&#xff0c;所以建议配置国内镜像源&#xff0c;这里以清华的镜像源为例。 pip config set global.index-url https://pypi.tuna…

QT知识积累:qt取整函数

在Qt中&#xff0c;你可以使用以下函数来进行取整操作&#xff1a; qFloor&#xff1a;向下取整&#xff0c;返回不大于给定浮点数的最大整数。 qreal qFloor(qreal value)qCeil&#xff1a;向上取整&#xff0c;返回不小于给定浮点数的最小整数。 qreal qCeil(qreal value)qRo…

具有 MOSFET 的电压到电流 (V-I) 转换器电路

设计说明 该单电源、低侧、V-I 转换器向可以连接到比运算放大器电源电压更高的电压的负载提供经过良好调节的电流。该 电路接受介于 0V 和 2V 之间的输入电压&#xff0c;将其转换为介于 0mA 和 100mA 之间的电流。通过将低侧电流检测电 阻 R3 上的压降反馈到运算放大器的反相…

十、C语言:数据存储(大端小端存储,整型、浮点型存储)

一、大端存储与小端存储 大端字节序&#xff1a; 数据的低位字节序内容存放在高地址处&#xff0c;高位字节序内容存放在低地址处 小端字节序&#xff1a; 数据的低位字节序内容存放在低地址处&#xff0c;高位字节序内容存放在高地址处 //每个地址单元对应一个字节 二、 整型存…

AI绘画如何打造高质量数据集?

遇到难题不要怕&#xff01;厚德提问大佬答&#xff01; 厚德提问大佬答11 你是否对AI绘画感兴趣却无从下手&#xff1f;是否有很多疑问却苦于没有大佬解答带你飞&#xff1f;从此刻开始这些问题都将迎刃而解&#xff01;你感兴趣的话题&#xff0c;厚德云替你问&#xff0c;你…

鸿蒙开发教程:新手入门必看

一 开发设备要求 Windows环境运行要求&#xff1a; 根据华为官方文档&#xff0c;为了开发基于鸿蒙系统的应用&#xff0c;电脑的配置需求如下&#xff1a; 操作系统&#xff1a;建议至少为Windows 10 64位或Windows 11 64位版本。内存&#xff1a;至少需要8GB以上。硬盘空间…

flash和emmc的差异

Flash和eMMC&#xff08;Embedded MultiMediaCard&#xff09;作为两种常见的非易失性存储器&#xff08;NVM&#xff09;&#xff0c;在多个方面存在显著的差异。以下是对它们差异的详细分析&#xff1a; 存储方式和性能&#xff1a; Flash存储器&#xff1a;具有较快的读写速…

使用Redis缓存实现短信登录逻辑,手机验证码缓存,用户信息缓存

引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency> 加配置 spring:redis:host: 127.0.0.1 #redis地址port: 6379 #端口password: 123456 #密码…

毫米波雷达深度学习技术-1.6目标识别1

1.6 目标识别 利用检测和跟踪在距离、多普勒和角度这两个维度中的任意一个进行精确的目标定位后&#xff0c;将检测到的目标分类到所需的类别中。与检测类似&#xff0c;提出了多种框架来同时使用图像和点云进行目标分类。使用图像进行目标分类的最常见方法是从检测到的目标特征…

17.2 命令行-标志的类型、自定义帮助信息、子命令

1. 命令行标志的类型 针对标志值的每一种数据类型&#xff0c;flag包都提供了相对应的函数。 name : flag.String("name", "Anonymous", "Your name") // 名字&#xff0c;字符串型 age : flag.Int("age", 20, "Your age&qu…

10款必备软件,每款都是神器,赶快用起来吧!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/最近有很多小伙伴在咨询&#xff0c;我也抓紧时间整理了一些不错的软件和我陆续收到的&#xff0c;希望对大家有所帮助。 1. 全球鼠标——MouseI…