深入探索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,如下:

java 复制代码
<?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文件:

java 复制代码
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文件:

java 复制代码
<!-- 加载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接口,声明需要执行的数据库操作方法:

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

2. XML映射文件

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

xml 复制代码
<?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中

java 复制代码
<mappers>
	<mapper resource="UserMapper.xml"/>
</mappers>

4. 创建SqlSessionFactory

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

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

5. 获取Mapper代理对象

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

java 复制代码
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

6. 调用代理对象方法

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

java 复制代码
User user = userMapper.getUserById(1);

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

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

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

五、结论

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

相关推荐
艾菜籽18 小时前
MyBatis动态sql与留言墙联系
java·数据库·sql·spring·mybatis
l0sgAi19 小时前
PageHelper-Cursor:支持游标分页的 PageHelper 修改版,解决 MyBatis 深分页性能问题
spring boot·mybatis
计算机学姐1 天前
基于SpringBoo+Vue的医院预约挂号管理系统【个性化推荐算法+可视化统计】
java·vue.js·spring boot·mysql·intellij-idea·mybatis·推荐算法
计算机学姐1 天前
基于微信小程序的奶茶店点餐平台【2026最新】
java·vue.js·spring boot·mysql·微信小程序·小程序·mybatis
~~李木子~~2 天前
动态规划算法实践:从斐波那契到数字推理
算法·动态规划·代理模式
后端小张2 天前
【JAVA 进阶】Mybatis-Plus 实战使用与最佳实践
java·spring boot·spring·spring cloud·tomcat·mybatis·mybatis plus
拜见老天師2 天前
使用mybatis-plus,实现将排序时,字段值为NULL的数据排在最后
java·mybatis
superlls2 天前
(场景题)怎么实现数据的批量插入?
笔记·mybatis
紫荆鱼2 天前
设计模式-代理模式(Proxy)
c++·后端·设计模式·代理模式
YA3332 天前
java设计模式七、代理模式
java·设计模式·代理模式