Java-21 深入浅出 MyBatis - 手写ORM框架2 手写Resources、MappedStatment、XMLBuilder等

点一下关注吧!!!非常感谢!!持续更新!!!

大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html

在这里插入图片描述

目前已经更新到了:

  • MyBatis(正在更新)

框架实现

在当前的项目中,在 resources 下新建:

  • sqlMapConfig.xml
  • mapper.xml

sqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration><property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property><property name="jdbcUrl" value="jdbc:mysql://172.16.1.130:3306/wzk-mybatis?characterEncoding=utf-8"></property><property name="user" value="hive"></property><property name="password" value="hive@wzk.icu"></property><mapper resource="mapper.xml"></mapper>
</configuration>

对应的截图如下所示:
在这里插入图片描述

这段代码是一个 MyBatis 的配置文件,通常命名为 mybatis-config.xml 或类似的名字。它主要完成以下任务:

  • 配置数据库连接属性,例如驱动类、JDBC URL、用户名和密码。
  • 引入 MyBatis 的映射文件,用于定义 SQL 语句和映射关系。

mapper.xml

实现一个单查询和列表的查询

<mapper namespace="icu.wzk.dao.UserInfoMapper"><select id="selectOne" parameterType="icu.wzk.model.UserInfo" resultType="icu.wzk.model.UserInfo">SELECT*FROMuser_infoWHEREusername=#{username}</select><select id="selectList" parameterType="icu.wzk.model.UserInfo" resultType="icu.wzk.model.UserInfo">SELECT*FROMuser_info</select>
</mapper>

对应的截图如下所示:
在这里插入图片描述
命名空间 (namespace):

  • mapper namespace=“icu.wzk.dao.UserInfoMapper”:定义了映射文件的命名空间,用于标识当前的 Mapper 文件。这里的命名空间与 Java 接口类 UserInfoMapper 对应。

单条记录查询 (selectOne):

  • select id=“selectOne” parameterType=“icu.wzk.model.UserInfo” resultType=“icu.wzk.model.UserInfo”:这是一个 select 标签,用于查询单条记录。id=“selectOne” 定义了方法名称,与 UserInfoMapper 接口中的方法名对应。parameterType=“icu.wzk.model.UserInfo” 指定了方法的参数类型,这里是 UserInfo 对象。resultType=“icu.wzk.model.UserInfo” 指定了返回结果的类型,同样是 UserInfo 对象。

实体相关

model

新建一个实体类,UserInfo

package icu.wzk.model;import lombok.Data;@Data
public class UserInfo {private Long id;private String username;private String password;private Integer age;}

资源相关

Configuration

package icu.wzk.bean;import lombok.Data;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;@Data
public class Configuration {private DataSource dataSource;private Map<String, MappedStatement> mappedStatementMap = new HashMap<>();}

MappedStatment

package icu.wzk.bean;import lombok.Data;@Data
public class MappedStatement {private String id;private String sql;private String parameterType;private String resultType;}

Resources

package icu.wzk.bean;import java.io.InputStream;public class Resources {public static InputStream getResourceAsStream(String path) {return Resources.class.getClassLoader().getResourceAsStream(path);}}

解析相关

XMLConfigerBuilder

package icu.wzk.bean;import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import java.beans.PropertyVetoException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;public class XMLConfigerBuilder {private Configuration configuration;public XMLConfigerBuilder(Configuration configuration) {this.configuration = configuration;}public Configuration parseConfiguration(InputStream inputStream) throws DocumentException, PropertyVetoException, ClassNotFoundException {Document document = new SAXReader().read(inputStream);Element rootElement = document.getRootElement();List<Element> propertyElements = rootElement.selectNodes("//property");Properties properties = new Properties();for (Element element : propertyElements) {String name = element.attributeValue("name");String value = element.attributeValue("value");properties.setProperty(name, value);}ComboPooledDataSource comboSource = new ComboPooledDataSource();comboSource.setDriverClass(properties.getProperty("driverClass"));comboSource.setJdbcUrl(properties.getProperty("jdbcUrl"));comboSource.setUser(properties.getProperty("user"));comboSource.setPassword(properties.getProperty("password"));configuration.setDataSource(comboSource);List<Element> mappedElements = rootElement.selectNodes("//mapper");XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configuration);for (Element element : mappedElements) {String mapperPath = element.attributeValue("resource");InputStream resourceAsStream = Resources.getResourceAsStream(mapperPath);xmlMapperBuilder.parse(resourceAsStream);}return configuration;}}

这段代码是一个用于解析 XML 配置文件的 Java 类,主要作用是读取 XML 配置文件内容,初始化应用程序所需的配置信息(例如数据库连接池配置、Mapper 文件解析等)。

类的定义

类名 XMLConfigerBuilder:表示这是一个 XML 配置解析器。
成员变量 configuration:保存应用的配置信息,类型为 Configuration。

构造方法

XMLConfigerBuilder(Configuration configuration):通过构造方法将 Configuration 对象传入并保存在成员变量中。

parseConfiguration 方法

该方法负责解析 XML 文件并初始化 Configuration 对象,主要包括以下几个步骤:
解析 XML 文档:

  • 使用 SAXReader 读取输入流(InputStream),生成 XML 文档对象。
  • 获取 XML 的根元素(rootElement)。

读取数据库配置:

  • 查找 XML 中的 节点,解析出 name 和 value 属性,将其存入 Properties 对象。
  • 创建 ComboPooledDataSource 对象,用于配置数据库连接池,设置驱动类、URL、用户名和密码等信息。
  • 将初始化好的数据源对象设置到 configuration 中。

解析 Mapper 文件

  • 查找 XML 中的 节点,提取每个节点的 resource 属性值(Mapper 文件路径)。
  • 逐个读取 Mapper 文件,通过 XMLMapperBuilder 的 parse 方法解析每个文件,将其结果更新到 configuration 中。

返回最终的 Configuration 对象

  • 方法执行完成后,返回已经完整解析并初始化的 Configuration 对象。

XMLMapperBuilder

package icu.wzk.bean;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import java.io.InputStream;
import java.util.List;public class XMLMapperBuilder {private Configuration configuration;public XMLMapperBuilder(Configuration configuration) {this.configuration = configuration;}public void parse(InputStream inputStream) throws DocumentException, ClassNotFoundException {Document document = new SAXReader().read(inputStream);Element rootElement = document.getRootElement();String namespace = rootElement.attributeValue("namespace");List<Element> selectList = rootElement.selectNodes("select");for (Element element : selectList) {String id = element.attributeValue("id");String parameterType = element.attributeValue("parameterType");String resultType = element.attributeValue("resultType");String key = namespace + "." + id;String textTrim = element.getTextTrim();MappedStatement mappedStatement = new MappedStatement();mappedStatement.setId(id);mappedStatement.setParameterType(parameterType);mappedStatement.setResultType(resultType);mappedStatement.setSql(textTrim);configuration.getMappedStatementMap().put(key, mappedStatement);}}}

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

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

相关文章

关于Python的常用模块

Python拥有丰富的标准库和第三方库&#xff0c;这些库提供了大量的模块&#xff0c;使得Python能够广泛应用于各个领域。以下是一些Python的常用模块&#xff1a; 一、系统交互与文件操作模块 os模块&#xff1a;用于与操作系统进行交互&#xff0c;如获取当前工作目录、创建…

专业135+总分400+华中科技大学824信号与系统考研经验华科电子信息与通信工程,真题,大纲,参考书。

考研成功逆袭985&#xff0c;上岸华科电子信息&#xff0c;初试专业课824信号与系统135&#xff0c;总分400&#xff0c;成绩还是很满意&#xff0c;但是也有很多遗憾&#xff0c;总结一下自己的复习&#xff0c;对于大家复习给些参考借鉴&#xff0c;对自己考研画个句号&#…

ElementUI:el-tabs 切换之前判断是否满足条件

<div class"table-card"><div class"card-steps-class"><el-tabsv-model"activeTabsIndex":before-leave"beforeHandleTabsClick"><el-tab-pane name"1" label"基础设置"><span slot&…

java中的数组(2)

大家好&#xff0c;我们今天继续来看java中数组这方面的知识点&#xff0c;那么话不多说&#xff0c;我们直接开始。 一.数组的使用 1.数组中元素访问 数组在内存中是一段连续的空间,空间的编号都是从0开始的,依次递增,数组可以通过下标访问其任意位置的元素. 也可以进行修改…

在 OAuth 2.0 中,refreshToken(刷新令牌)存在的意义

在 OAuth 2.0 中&#xff0c;refreshToken&#xff08;刷新令牌&#xff09; 的主要目的是为了提升用户体验和安全性&#xff0c;同时确保访问令牌的有效性。以下是需要使用 refreshToken 的原因&#xff1a; 1. 访问令牌的有限生命周期 访问令牌&#xff08;accessToken&…

#渗透测试#红蓝对抗#SRC漏洞挖掘# Yakit(6)进阶模式-Web Fuzzer(下)

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

Oracle 19c RAC到单机ADG部署及Broker管理配置-最佳实践

一、概述 前面文章列举了几种ADG常见的搭建方式&#xff0c;此处我以最佳的方式作为实践过程演示&#xff1b;架构为RAC到单机&#xff0c;通常这种架构大家用得比较多&#xff1b;这里实践的案例ADG全程是Broker进行管理&#xff0c;Broker其实是ADG非常简单易用的工具&#x…

每日一题 LCR 097. 不同的子序列

LCR 097. 不同的子序列 使用动态规划就可以解决&#xff0c;重点是知道 动态规划的状态是如何转移的 class Solution { public:int numDistinct(string s, string t) {int ns s.size();int nt t.size();vector<vector<long>> dp(ns1,vector<long>(nt1,0)…

如何在 JavaScript 中进行深度克隆?

在 JavaScript 中进行深度克隆&#xff08;deep clone&#xff09;是指创建一个对象的完整副本&#xff0c;并且副本中所有的嵌套对象也被复制&#xff0c;而不是只是引用原始对象中的嵌套对象。深度克隆与浅克隆的主要区别在于&#xff0c;浅克隆只复制对象的引用&#xff0c;…

C# 关于加密技术以及应用(一)

在 开发过程中&#xff0c;加密是一个常见的需求&#xff0c;数字签名和验证、网络通信安全、数据加密解密、用于保护数据的安全性和隐私。如几种常用的加密技术AES、SSL/TLS、RSA、HMAC 、SHA等&#xff0c;都是我们开发过程中常用到的加密方式&#xff0c;只不过每一个加密方…

Python 爬虫 (1)基础 | XHR

一、XHR 1、概念 XHR&#xff0c;全称XMLHttpRequest&#xff0c;是一种在无需重新加载整个网页的情况下&#xff0c;能够更新部分网页的技术。它允许网页的JavaScript代码与服务器进行异步通信&#xff0c;即在发送请求后&#xff0c;浏览器不会阻塞用户的后续操作&#xff0…

二进制部署Prometheus+grafana+alertmanager+node_exporter

Prometheus 是一个开源的监控和告警工具包&#xff0c;旨在提供高可靠性和可扩展性。它最初由 SoundCloud 开发&#xff0c;现已成为云原生计算基金会&#xff08;CNCF&#xff09;的一部分。以下是 Prometheus 的一些关键特性和概念&#xff1a; 1. **时间序列数据库**&#…

工业智能网关如何为企业实现智能制造赋能?

在数字化转型的浪潮中&#xff0c;工业智能网关作为连接物理世界与数字世界的桥梁&#xff0c;正逐步成为智能制造领域的核心组件。本文将通过一个实际使用案例&#xff0c;深入剖析工业智能网关如何助力企业实现生产流程的优化、数据的高效采集与分析&#xff0c;以及智能化决…

算法设计6_随机化算法

随机化算法 随机算法的随机性&#xff08;基本特征&#xff09; – 对于同一实例的多次执行, 效果可能完全不同 – 时间复杂性的一个随机变量 – 解的正确性和准确性也是随机的 数值随机化算法 随机数值算法 – 主要用于数值问题求解 – 算法的输出往往是近似解 – 近似…

使用mmdeploy框架C++预测mask并绘制最小外接矩形

目录 解决目标 逻辑思路 代码实现 第1部分 第2部分 解决目标 这段代码实现了&#xff0c;一个基于深度学习的图像检测程序。它使用mmdeploy框架&#xff0c;加载一个预训练的模型【实例分割模型】来检测图像中的物体。 逻辑思路 程序首先加载模型&#xff0c;然后&#…

Java --- JVM编译运行过程

目录 一.Java编译与执行流程&#xff1a; 二.编译过程&#xff1a; 1.编译器&#xff08;javac&#xff09;&#xff1a; 2.字节码文件&#xff08;.class&#xff09;&#xff1a; 三.执行过程&#xff1a; 1.启动JVM&#xff08;Java虚拟机&#xff09;&#xff1a; 2…

【Makefile】编译日志之输出重定向符号 >

用法1 make all >& compilelog.txt make all > compilelog.txt这两个编译命令在功能上有一些细微的区别&#xff0c;主要在于标准输出和标准错误的处理方式。 make all >& compilelog.txt 这个命令会将标准输出&#xff08;stdout&#xff09;和标准错误&a…

使用 `typing_extensions.TypeAlias` 简化类型定义:初学者指南

使用 typing_extensions.TypeAlias 简化类型定义&#xff1a;初学者指南 什么是 TypeAlias&#xff1f;安装 typing_extensions示例代码&#xff1a;如何使用 TypeAlias示例 1&#xff1a;为简单类型定义别名示例 2&#xff1a;为复杂类型定义别名示例 3&#xff1a;结合 Union…

11.关于vim编辑器的简单配置

1. 说明 在linux系统中编辑文件内容的方式有很多种&#xff0c;比如直接在系统中暗中某些IDE&#xff0c;方便快捷&#xff0c;也可以直接在windows系统中编辑好文件后上传到linux系统中&#xff0c;这些方式对于编写内容较多的文件或者整个项目的文件还是非常适合的。不过有时…

qq空间管理小助手教程代码演示

headers {"Authorization": "Bearer YOUR_ACCESS_TOKEN","Content-Type": "application/json" }# 发布说说示例&#xff08; def post_moment(content):url "https://qzone-api.example.com/post_moment"data {"con…