mybatis的mapper接口没有实现为什么可以调用

关于mybatis的mapper接口是如何实现的,下面有两个小案例帮助理解。

1.关于jdk的动态代理

JAVA实现动态代理的两种方式…
本以为JDK的动态代理只能代理接口的实现类,今天才发现它可以直接代理接口,并通过Proxy类来生成接口的代理对象,原谅我个小白。
实验一下:
首先创建了一个接口类TestObject,定义了一个抽象方法sayHello。

public interface TestObject {
    public String sayHello(String name);
}

创建了一个主类,通过Proxy去生成TestObject接口的代理对象res,这里使用匿名内部类的方式创建了InvocationHandler接口的对象,并实现了invoke方法,在这个方法里我们可以代理对象、目标对象的方法对象、目标对象的方法参数等信息,方法内部我们返回了一个字符串。
然后获取到代理对象res,并调用sayHello方法传入参数“liaopeng”,结果输出了”hello liaopeng“,表示成功了。

public class Test {

    public static void main(String[] args){

        TestObject res = (TestObject) Proxy.newProxyInstance(TestObject.class.getClassLoader(),
                new Class[]{TestObject.class},
                (Object proxy, Method method, Object[] params)->{
                    return "hello "+params[0].toString();
                });
        System.out.println(res.sayHello("liaopeng"));
        
    }
}

运行结果:
在这里插入图片描述

2. mybatis的mapper接口的实现原理

在mybatis中我们可以通过调用mapper接口去直接获取数据库中的数据,而不需要去实现mapper接口,其实是就是使用了动态代理的方式,为mapper接口创建了代理对象,在代理对象中实现了相应的访问数据库的逻辑。
示例:
这里定义了一个接口包含两个抽象方法sayHello和sayAge。

public interface TestObject {

    public String sayHello(String name);

    public int sayAge(int age);

}

这里大致和上一个示例差不多,只是匿名内部类的实现方法不同。这里根据不同的方法名称实现了不同逻辑,其实就是对接口类的实现。
我们知道mybatis中是通过namespace+id的方式来唯一确定一条mapper.xml中配置的Sql语句。而mybatis有两种方式执行sql访问数据库,第一种是mapper接口的方式,第二种是通过调用sqlSession的方法传入一条sql的定位和参数去访问,如:sqlSession.selectOne("com.test.mapper.UserMapper.getUserById",1);
其实mapper接口的方式,底层就是通过动态代理的方式生成代理对象,对接口方法进行实现。而这里的实现就是使用以上的第二种方式进行实现,例如,以上的selectOne方法的第一个参数就是接口的全限类名+方法名,第二个参数就是传入接口方法的参数。
以下只是一个示例,帮助理解,详情参见源码。

public class Test {

    public static void main(String[] args){

        TestObject res = (TestObject) Proxy.newProxyInstance(TestObject.class.getClassLoader(),
                new Class[]{TestObject.class},
                (proxy, method, params)->{

            System.out.println("method:                 "+method.getName());
            System.out.println("method resultType:      "+method.getReturnType());
            System.out.println("method parametersType:  "+method.getGenericReturnType());
            System.out.println("method parametersCount: "+method.getParameterCount());

            switch (method.getName()){
                case "sayHello":
                    return "hello "+params[0].toString();
                case "sayAge":
                    return params[0];
            }
            return null;

        });
        System.out.println(res.sayHello("liaopeng"));
        System.out.println();
        System.out.println(res.sayAge(18));

    }

}

运行结果:
在这里插入图片描述

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值