深入探索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动态代理的实现原理,我们可以更加灵活地使用这个强大的框架来处理复杂的数据访问需求。

相关推荐
蓝染-惣右介35 分钟前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
武子康2 小时前
Java-07 深入浅出 MyBatis - 一对多模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据库·sql·mybatis·springboot
一二小选手2 小时前
【Mybatis】@Param注解 resultMap手动映射
java·mybatis
郑祎亦4 小时前
Spring Boot 项目 myblog 整理
spring boot·后端·java-ee·maven·mybatis
吾与谁归in8 小时前
【C#设计模式(13)——代理模式(Proxy Pattern)】
设计模式·c#·代理模式
OkeyProxy16 小时前
什麼是ISP提供的公共IP地址?
代理模式·proxy模式·ip地址·isp·海外ip代理
jokerest12318 小时前
web——sqliabs靶场——第十三关——报错注入+布尔盲注
mybatis
武子康19 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
WindFutrue21 小时前
使用Mybatis向Mysql中的插入Point类型的数据全方位解析
数据库·mysql·mybatis