JDK动态代理
Mapper 接口的工作原理是 JDK 动态代理
在 MyBatis 框架中,Mapper 接口的工作原理确实是基于 JDK 动态代理机制。MyBatis 使用动态代理来创建接口的实现类实例,以便在运行时执行 SQL 语句并返回结果。以下是 MyBatis 如何利用 JDK 动态代理实现 Mapper 接口的工作原理:
工作原理
-
Mapper 接口定义:
- 开发者定义一个 Mapper 接口,其中包含了与数据库交互的方法。这些方法通常通过注解或 XML 文件来关联具体的 SQL 语句。
-
动态代理创建代理对象:
- 当应用程序调用
SqlSession.getMapper(Class<T> type)
方法获取 Mapper 接口的实例时,MyBatis 会使用 JDK 动态代理为该接口创建一个代理对象。 - 这个代理对象实现了 Mapper 接口,并且会将对接口方法的调用委托给一个
InvocationHandler
实现。
- 当应用程序调用
-
MapperProxy
作为InvocationHandler
:- MyBatis 使用
MapperProxy
类作为InvocationHandler
的实现。 MapperProxy
的invoke
方法会拦截对 Mapper 接口方法的调用,并根据方法的签名和配置文件中的映射信息来执行相应的 SQL 语句。
- MyBatis 使用
-
执行 SQL 语句:
MapperProxy
从 MyBatis 的配置中获取 SQL 语句,并通过SqlSession
执行这些语句。- SQL 执行的结果会被转换为方法的返回值类型,然后返回给调用者。
-
结果映射:
- MyBatis 会根据配置中的映射规则,将 SQL 执行结果映射为 Java 对象。这通常涉及将结果集的列映射到 Java 对象的属性上。
示例
假设有一个简单的 Mapper 接口:
java
public interface UserMapper {
User selectUserById(int id);
}
在 MyBatis 中使用时,执行过程如下:
- 当调用
UserMapper userMapper = sqlSession.getMapper(UserMapper.class)
时,MyBatis 会创建一个实现UserMapper
接口的代理对象。 - 当调用
userMapper.selectUserById(1)
时,MapperProxy
的invoke
方法会被触发。 MapperProxy
会查找与selectUserById
方法对应的 SQL 语句,并通过SqlSession
执行该语句。- 执行结果会被映射为
User
对象,并返回给调用者。
优势
- 无需手动实现接口:开发者只需定义接口和映射配置,无需编写实现类。
- 灵活性:可以通过配置文件轻松更改 SQL 语句,而不需要修改 Java 代码。
- 简化代码:减少了重复的 JDBC 代码,提高了开发效率。
通过 JDK 动态代理,MyBatis 能够在运行时为 Mapper 接口提供强大的动态 SQL 执行功能,同时保持代码的简洁和可维护性。