深入探索MyBatis的动态代理模式

news2024/11/15 2:11:58

文章目录

  • 深入探索MyBatis的动态代理模式
    • 引言
    • 一、 MyBatis动态代理概述
      • 动态代理的优势
    • 二、准备工作
      • 文件存放结构视图
      • 1、Mybatis的主配置文件 mybatis-config.xml
      • 2、db.properties文件:
      • 3、mybatis-config.xml引用properties文件:
    • 三、MyBatis动态代理的实现原理
      • 1. Mapper接口定义
      • 2. XML映射文件
      • 3. 将sql映射文件添加到MyBatis主配置文件中
      • 4. 创建SqlSessionFactory
      • 5. 获取Mapper代理对象
      • 6. 调用代理对象方法
    • 四、MyBatis动态代理的内部机制
    • 五、结论

深入探索MyBatis的动态代理模式

引言

在Java开发中,MyBatis作为一个半自动的ORM(对象关系映射)框架,被广泛应用于数据持久层。它通过简单的API和灵活的配置,使得数据库操作变得简洁而高效。MyBatis的核心特性之一是动态代理模式,它允许我们通过接口而非具体的实现类来操作数据库。本文将深入探讨MyBatis动态代理的内部机制和实现原理。

一、 MyBatis动态代理概述

动态代理是一种设计模式,它在运行时创建代理对象,以控制对某个对象的访问。MyBatis的动态代理模式允许开发者定义一个Mapper接口,而无需提供实现类。MyBatis会在运行时自动创建这个接口的代理对象,代理对象会拦截接口方法的调用,并执行相应的数据库操作。

动态代理的优势

  • 解耦数据库操作和业务逻辑:通过接口定义数据库操作,使业务逻辑与数据访问分离。
  • 提高代码的可维护性:接口的变更不会影响业务逻辑,只需调整Mapper接口或XML配置。
  • 简化数据访问代码:避免了重复编写大量的数据访问代码,如开关事务、处理SQL语句等。

二、准备工作

文件存放结构视图

在这里插入图片描述

1、Mybatis的主配置文件 mybatis-config.xml

mybatis-config.xml主要用来配置mybatis的运行环境,数据源、事务等。

在classpath下创建mybatis-config.xml,如下:

<?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>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <!-- 可以配置多个environment -->
        <environment id="development">
            <!-- 使用jdbc事务管理-->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/shopdb" />
                <property name="username" value="root" />
                <property name="password" value="123" />
            </dataSource>
        </environment>
    </environments>
</configuration>

2、db.properties文件:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

3、mybatis-config.xml引用properties文件:

<!-- 加载properties文件 -->
	<properties resource="db.properties"></properties>
	<!-- 和spring整合后 environments配置将废除-->
	<environments default="development">
		<!-- 可以配置多个environment -->
		<environment id="development">
			<!-- 使用jdbc事务管理-->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池-->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>

三、MyBatis动态代理的实现原理

1. Mapper接口定义

首先,定义一个Mapper接口,声明需要执行的数据库操作方法:

public interface UserMapper {
    User getUserById(int id);
    void insertUser(User user);
    // 更多数据库操作方法...
}

2. XML映射文件

然后,创建一个XML映射文件,将Mapper接口中的方法与SQL语句关联起来:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace命名空间,作用就是对sql进行分类管理
	注意:使用mapper代理方法开发时,namespace需要特殊设置
 -->
<mapper namespace="com.example.mapper.UserMapper">
    <select id="getUserById" resultType="com.example.model.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
    <!-- 更多SQL映射配置... -->
</mapper>

注意:sql语句的id必须和接口中对应方法名称一致才能关联起来

3. 将sql映射文件添加到MyBatis主配置文件中

mybatis框架需要加载映射文件,将UserMapper.xml添加到mybatis-config.xml中

<mappers>
	<mapper resource="UserMapper.xml"/>
</mappers>

4. 创建SqlSessionFactory

使用MyBatis的配置文件和XML映射文件,创建一个SqlSessionFactory

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

5. 获取Mapper代理对象

通过SqlSession获取Mapper接口的代理对象:

SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

6. 调用代理对象方法

调用Mapper代理对象的方法,MyBatis会拦截这些调用,并执行相应的数据库操作:

User user = userMapper.getUserById(1);

四、MyBatis动态代理的内部机制

MyBatis使用JDK的动态代理机制来实现Mapper接口的代理对象。当调用getMapper方法时,MyBatis会检查是否已经为该接口创建了代理对象。如果没有,它会使用Proxy.newProxyInstance方法创建一个代理对象,该对象实现了Mapper接口,并拦截所有方法调用。

代理对象的invoke方法会根据方法的签名找到对应的SQL语句,并执行。这是通过MapperMethod实现的,它将接口方法与XML映射文件中的SQL语句关联起来。

五、结论

MyBatis的动态代理模式提供了一种声明式的数据访问方式,它简化了数据库操作,并提高了代码的可维护性。通过理解MyBatis动态代理的实现原理,我们可以更加灵活地使用这个强大的框架来处理复杂的数据访问需求。

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

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

相关文章

基于STM32F103的FreeRTOS系列(十)·消息队列的使用详细介绍以及代码编写

目录 1. 消息队列简介 1.1 概念 1.2 数据存储 1.3 阻塞机制 1.3.1 出队阻塞 1.3.2 入队阻塞 1.4 操作示意图 1.4.1 创建队列 1.4.2 向队列发送第一个消息 1.4.3 向队列发送第二个消息 1.4.4 从队列读取消息 1.5 消息队列的控制块 2. 常用API函数介绍…

android13顶部状态栏里面调节背光,不隐藏状态栏面板

总纲 android13 rom 开发总纲说明 目录 1.前言 2.代码分析 3.修改方法 4.编译运行 5.彩蛋 1.前言 android13顶部状态栏里面调节背光,这个时候状态栏面板会被隐藏掉,有些需求就需要不隐藏这个面板。 2.代码分析 查找亮度条属性 id/brightness_slider ./frameworks/b…

Vue 3 + 天地图 + D3.js 绘制行政区划

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;组件封装篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来组件封装篇专栏内容:组件封装-天地图 目录 引入天地图 API 初始化地图 引入 D3.js 加载行政区划数据 添…

k8s高版本(1,28)部署NodePort模式下的ingress-nginx的详细过程及应用案例

文章目录 前言环境ingress安装应用案例(ingress-http案例&#xff1a; 基于名称的负载均衡) 前言 这个是nodeport模式下的&#xff0c;如果需要loadbalancer模式下的&#xff0c;看看博主下面以前的博客 链接: k8s学习–负载均衡器matelLB的详细解释与安装 链接: k8s学习–ing…

机器学习 之 使用逻辑回归 进行银行贷款预测(请帮忙点点赞谢谢,这对我很重要)

目录 一、逻辑回归简介 逻辑回归的基本原理 线性组合&#xff1a; Sigmoid函数&#xff1a; 二、实战案例 1.导入数据 2.准备环境 混淆矩阵的基本概念 混淆矩阵的作用 3.加载数据 4.数据预处理 什么是标准化&#xff1f; 标准化的计算公式 划分数据集 5.逻辑回归模…

19.缓存的认识和基本使用

缓存介绍 缓存是数据交换的缓冲区Cache&#xff0c;是临时存储数据的地方&#xff0c;一般读写性能较高。 数据库的缓存就是建立索引。 缓存的作用 1.降低后端负载。 2.提高读写效率&#xff0c;降低响应时间。 缓存的问题 1.保证数据的一致性。 2.增加代码维护成本。解…

Kafka运行机制(二):消息确认,消息日志的存储和回收

前置知识 Kafka基本概念https://blog.csdn.net/dxh9231028/article/details/141270920?spm1001.2014.3001.5501Kafka运行机制&#xff08;一&#xff09;&#xff1a;Kafka集群启动&#xff0c;controller选举&#xff0c;生产消费流程https://blog.csdn.net/dxh9231028/arti…

Qt 0816作业

一、思维导图 二、将day1做的登录界面升级优化【资源文件的添加】 三、在登录界面的登录取消按钮进行一下设置 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到…

C++ | Leetcode C++题解之第350题两个数组的交集II

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {sort(nums1.begin(), nums1.end());sort(nums2.begin(), nums2.end());int length1 nums1.size(), length2 nums2…

函数递归VS操作符深入?

1>>前言 函数递归函数递归&#xff0c;当小白听到这样的词会感到无比陌生&#xff0c;请不要惊慌&#xff0c;这是正常的&#xff0c;以至于都不是很经常用到&#xff0c;但是它的算法&#xff0c;它的思想是值得我们深入思考的。还有一些复杂操作符&#xff0c;如按位与…

【原创】java+swing+mysql共享充电宝管理系统设计与实现

个人主页&#xff1a;程序员杨工 个人简介&#xff1a;从事软件开发多年&#xff0c;前后端均有涉猎&#xff0c;具有丰富的开发经验 博客内容&#xff1a;全栈开发&#xff0c;分享Java、Python、Php、小程序、前后端、数据库经验和实战 文末有本人名片&#xff0c;希望和大家…

PyTorch之TensorBoard使用

接回上一篇&#xff1a;PyTorch深度学习框架-CSDN博客 在学习这篇之前建议先按照上一篇搭建好整个PyTorch环境 然后这一篇讲怎么用TensorBoard&#xff0c;这个玩意是Tensorflow官方推出的一个可视化工具&#xff0c;当使用Tensorflow训练大量深层的神经网络时&#xff0c;我们…

全局锁、表级锁、行级锁

锁的作用和特点 WHY&#xff1a;锁的出现是为了解决并发场景下不同用户同时对共享资源进行操作&#xff0c;而可能引发的并发问题。 HOW&#xff1a;控制不同线程对资源访问的规则。 全局锁 顾名思义&#xff0c;全局锁就是对整个数据库实例加锁。一般在进行全库备份的时候…

prometheus + grafana + 告警

配置环境 准备三台主机&#xff0c;将三台主机的信息分别写入/etc/hosts文件中 192.168.100.115 server.example.com server 192.168.100.116 agent1.example.com agent1 192.168.100.117 grafana.example.com grafana [rootserver ~]# cat /etc/hosts 127.0.0.1 localhos…

【MySQL 08】内置函数 (带思维导图)

文章目录 &#x1f308; 一、日期函数⭐ 1. 常见日期函数⭐ 2. 日期函数使用示例⭐ 3. 日期函数综合案例 &#x1f308; 二、字符串函数⭐ 1. 常见字符串函数⭐ 2. 字符串函数使用示例⭐ 3. 字符串函数综合案例 &#x1f308; 三、数值函数⭐ 1. 常见数值函数⭐ 2. 数值函数使用…

探索GitHub的无限可能:从注册到Linux环境下的库分支链接

在这个数字化时代&#xff0c;GitHub已成为开发者们不可或缺的宝藏库。无论你是编程新手还是资深开发者&#xff0c;GitHub都能为你打开一扇通往无限创意与协作的大门。今天&#xff0c;就让我们一起踏上这段探索之旅&#xff0c;从GitHub的注册开始&#xff0c;再到如何在Linu…

google transalte api的使用,V2服务账户方式(google-cloud-java)

Google Cloud Translation API 有几个不同的使用方式&#xff0c;其中之一是使用最新的 Google Cloud Client Library。这些库提供了简化的 API&#xff0c;使得与 Google Cloud 服务的交互变得更加容易。 对于gcp平台的创建方式&#xff0c;我记得得绑定真信用卡了&#xff0c…

Debug-021-el-table实现分页多选的效果(切换分页,仍可以保持前一页的选中效果)

前情提要&#xff1a; 这个功能实现很久了&#xff0c;但是一直没有留意如何实现&#xff0c;今天想分享一下。具体就是我们展示table数据的时候&#xff0c;表格中的数据多数情况是分页展示&#xff0c;毕竟数据量太多&#xff0c;分页的确是有必要的。那么我们有业务需要给表…

portswigger的Exploiting DOM clobbering to enable XSS

目录 尝试一下看看可不可以XSS DOM破坏 查看源码确定DOM破坏漏洞点以及代码分析 首先查看/resources/labheader/js/labHeader.js&#xff0c;没有什么作用 然后domPurify这东西是一个过滤框架也没啥子用 看/resources/js/loadCommentsWithDomClobbering.js尝试分析代码(对…

使用Poi-tl对word模板生成动态报告

一、pom依赖问题&#xff1a; <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.2</version> </dependency> 使用 poi-tl 的 1.12.2版本&#xff0c;如果使用了poi依赖&#x…