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

文章目录

  • 深入探索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.rhkb.cn/news/404333.html

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

相关文章

Linux·权限与工具-make

1. Makefile/makefile工具 首先展示一下&#xff0c;makefile工具如何使用。我们先写一个C语言程序 然后我们建立一个Makefile/makefile文件&#xff0c;m大小写均可。我们在文件中写入这样两行 wq保存退出后&#xff0c;我们使用 make 命令 可以看到生成了可执行程序&#xff…

人工智能在Facebook的角色:创新与挑战并存

人工智能&#xff08;AI&#xff09;已经成为推动科技进步的重要力量&#xff0c;而在社交媒体领域&#xff0c;Facebook则是将AI技术广泛应用的先锋。Facebook通过AI来改善用户体验、提高内容质量以及优化广告投放&#xff0c;极大地提升了平台的功能与价值。然而&#xff0c;…

渗透第三次作业

xss game前八关复现 第一关 传参进入h2标签 传入一个alert(1) 发现没有触发&#xff0c;原因是官方禁用了script 选择用img标签 ?somebody<img src1 οnerrοr"alert(1337)"> 第二关 先把它的双引号闭合掉&#xff0c;再执行1337再闭合 ?jeff111";al…

【Python零基础】while循环和用户输入

文章目录 前言一、input()函数二、while循环三、使用while循环来处理列表和字典总结 前言 我们开发一个应用程序&#xff0c;目的都是为了解决最终用户的问题&#xff0c;针对用户界面输入的数据&#xff0c;按照用户期待的逻辑进行处理&#xff0c;得到用户想要的结果。本章将…

Java | Leetcode Java题解之第347题前K个高频元素

题目&#xff1a; 题解&#xff1a; class Solution {public int[] topKFrequent(int[] nums, int k) {Map<Integer, Integer> occurrences new HashMap<Integer, Integer>();for (int num : nums) {occurrences.put(num, occurrences.getOrDefault(num, 0) 1);…

【机器学习】(基础篇六) —— 数据集的划分和过拟合问题

数据集的划分 训练集和测试集 在机器学习中&#xff0c;数据集通常会被划分为训练集&#xff08;Training Set&#xff09;和测试集&#xff08;Test Set&#xff09;&#xff0c;有时还会包括一个验证集&#xff08;Validation Set&#xff09;。这样的划分是为了能够更好地…

SQL 数据库设计、事务、视图 <13>

一、数据库设计 1.多表之间的关系 1&#xff09; 一对一&#xff08;了解&#xff09; 如&#xff1a;人和身份证 分析&#xff1a;一个人只有一个身份证&#xff0c;一个身份证只能对应一个人 2&#xff09;一对多&#xff08;多对一&#xff09; 如&#xff1a;部门和员…

Flink消费Kafka数据积压排查解决

0、背景 有个Flink任务每天不定时会出现数据积压&#xff0c;无论是白天还是数据量很少的夜里&#xff0c;且积压的数据量会越来越多&#xff0c;得不到缓解&#xff0c;只能每日在积压告警后重启&#xff0c;重启之后消费能力一点毛病没有&#xff0c;积压迅速缓解&#xff0…

立仪光谱共焦传感器行业应用|薄膜高度差扫描

01&#xff5c;检测需求&#xff1a;扫描薄膜圆圈的高度差 02&#xff5c;检测方式 客户要求扫描薄膜圆圈的高度差&#xff0c;根据观察样品我们选择立仪科技D40A30镜头搭配H系列控制器进行测量 03&#xff5c;光谱共焦测量结果 薄膜圆圈的高度差轮廓 04&#xff5c;光谱共焦…

在CodeBlocks搭建SDL2工程OLED液晶模拟器虚拟OLED单色液晶(128x64)

在CodeBlocks搭建SDL2工程OLED液晶模拟器虚拟OLED单色液晶 例程说明源码下载目录工程配置一、SDL2的初始化和退出二、OLED画点和读点三、更新OLDE的GRAM四、清屏和清某区域五、点阵字库六、显示字符串七、显示中文字符八、显示图片九、测试代码十、主函数十一、运行结果 例程说…

05 serv00安装typecho

下载 ‍ cd domain/xxx.serv00.net/# 下载typecho git clone https://github.com/typecho/typecho.git# 当前有两个目录 typecho/ 和 public_html/ ls# 替换html rm -rf public_html/ mv typecho public_html‍ 安装 浏览器访问你的网站 xxx.serv0.net&#xff0c;看见 type…

8月15日笔记

masscan安装使用 首先需要有c编译器环境。查看是否有c编译器环境&#xff1a; gcc -v如果系统中已经安装了 GCC&#xff0c;这个命令将输出 GCC 的版本信息。如果未安装&#xff0c;你会看到类似于 “command not found” 的错误消息。 如果没有下载&#xff0c;使用如下命令…

万维网与HTTP协议:基础知识简明指南

引言 在当今的数字时代&#xff0c;了解万维网&#xff08;World Wide Web, WWW&#xff09;和HTTP协议&#xff08;Hyper Text Transfer Protocol&#xff09;是至关重要的。本文将为基础小白们简明扼要地介绍万维网及其核心协议HTTP&#xff0c;并通过简单的例子和清晰的段落…

C语言内存操作函数

目录 一. C语言内存操作函数 1. memcpy的使用和模拟实现 2. memmove函数 3. memset函数 4. memcmp函数 一. C语言内存操作函数 随着知识的不断积累&#xff0c;我们所想要实现的目标程序就会更加复杂&#xff0c;今天我们来学习一个新的知识叫做C语言内存操作函数&#x…

基于Python的火车票售票系统/基于django的火车购票系统

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&…

面试经典算法150题系列-最长公共前缀

最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1&#xff1a; 输入&#xff1a;strs ["flower","flow","flight"] 输出&#xff1a;"fl"示例 2&…

HTML及CSS面试题4

1、BFC 1.1、介绍BFC及其应用 补充——触发BFC的方式&#xff0c;常见的有&#xff1a; 设置浮动overflow设置为&#xff1a;auto、scroll、hiddenpositon设置为&#xff1a;absolute、fixed 介绍&#xff1a; ○ 所谓BFC&#xff0c;指的是&#xff1a;一个独立的布局环境&am…

集合的知识点

一、集合的简介 1.1 什么是集合 集合(Collection)&#xff0c;也是一个数据容器&#xff0c;类似于数组&#xff0c;但是和数组是不一样的。集合是一个可变的容器&#xff0c;可以随时向集合集合中添加元素&#xff0c;也可以随时从集合中删除元素。另外&#xff0c;集合还提…

鸿蒙(API 12 Beta3版)【录像流二次处理(C/C++)】媒体相机开发指导

通过ImageReceiver创建录像输出&#xff0c;获取录像流实时数据&#xff0c;以供后续进行图像二次处理&#xff0c;比如应用可以对其添加滤镜算法等。 开发步骤 导入NDK接口&#xff0c;接口中提供了相机相关的属性和方法&#xff0c;导入方法如下。 // 导入NDK接口头文件#in…

使用python实现3D聚类图

实验记录&#xff0c;在做XX得分预测的实验中&#xff0c;做了一个基于Python的3D聚类图&#xff0c;水平有限&#xff0c;仅供参考。 一、以实现三个类别聚类为例 代码&#xff1a; import pandas as pd import numpy as np from sklearn.decomposition import PCA from sk…