找不到mybatis的conf源码中的mapper_为啥mybatis的mapper只有接口没有实现类,但它却能工作?...

本文探讨了 MyBatis 中 mapper 接口没有实现类却能正常工作的原理。通过一个简单的 UserMapper 示例,解释了动态代理的概念,包括 JDK 动态代理和 CGlib 动态代理。分析了 MyBatis 源码,展示了从 SqlSession.getMapper 开始,如何通过反射和动态代理生成 mapper 对象,最终在 invoke 方法中执行 SQL 操作。文章还邀请读者思考 Spring Data JPA 的底层实现技术。
摘要由CSDN通过智能技术生成

b202b854a176a35ab5b9168488e8c37d.png

说起mybatis,大伙应该都用过,有些人甚至底层源码都看过了。在mybatis中,mapper接口是没有实现类的,取而代之的是一个xml文件。也就是说我们调用mapper接口,其实是使用了mapper.xml中定义sql完成数据操作。

大家有没想过,为什么mapper没有实现类,它是如何和xml关联起来的?

一个简单的例子

ok,别急,现在我们已经抛出问题,现在我们从demo开始,再结合我们所拥有的知识点出发,一一剖析整个过程。

先来搞个简单的查询:

UserMapper一个接口:

User findById(Long id);

userMapper.xml的sql语句

namespace="com.lfq.UserMapper">

id="findById" resultType="com.lfq.User">

select * * from user where id = #{id}

猜想

我们知道,接口是不直接被初始化的,但是可以被实现,所以new对象的时候是初始化实现类,然后接口再引用该对象。那么调用接口的方法实际上就是调用被引用对象的方法,也就是实现类的方法。

那么,UserMapper.findById被调用时候,不禁有这两个疑问?

  • 被引用的对象是谁呢?

  • 接口被调用时候发生了什么?

我们先来回答第二个问题,既然找不到实现类,UserMapper有没可能被代理起来呢,findById方法调用时候,我们找到代理对象来执行就行了。

代理有两种方式:

  • 静态代理

  • 动态代理

而静态代理基本是不可能的了,静态代理需要对UserMapper所有的方法进行重写。那么只能是动态代理,动态代理接口的所有方法,每次接口被调用,就会进入动态代理对象的invoke方法,然后加载xml中的sql完成操作数据库,再返回结果。

再然后说到动态代理,常见的方式有以下2种方式:

  • JDK动态代理:

  • 利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

  • CGlib动态代理:

  • 利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

所以,动态代理代理还是对象类,那么我们只有接口,不能new,哪来的对象呢?别忘了,我们还有反射机制,我们是不是可以通过反射给接口生成对象,还记得Class.*forName*吗。

综合上面的猜想:

第一步:通过反射机制给接口生成对象

第二步:动态代理反射对象,这样接口被调用,就会触发动态代理

嗯,好像有点道理,我果然是个天才!

知识点:动态代理

动态代理有几种实现方式,这里我们就先讲JDK动态代理,使用步骤如下:

  • 新建一个接口

  • 创建代理类,实现java.lang.reflect.InvocationHandler接口

  • 接口测试

接口我们就用UserMapper,我们来写个代理对象。

public class Test {

// 接口

static interface Subject{

void sayHi();

void sayHello();

}

// 默认实现类(我们可以反射生成)

static class SubjectImpl implements Subject{

@Override

public void sayHi() {

System.out.println(

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值