深入实现 MyBatis 底层机制的实现任务阶段 7- 实现动态代理 Mapper 的方法

前言
在Java世界里,MyBatis 是一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis消除了几乎所有的JDBC代码和参数的手动设置以及结果集的检索。MyBatis 可以使用简单的 XML 或注解进行配置,并且能映射基本类型、Map接口及任何 Java POJO(Plain Old Java Object)到数据库记录。
.
在这篇文章中,我们将深入探讨如何通过简化的 MyBatis 框架来创建 Mapper 的动态代理。

个人主页:尘觉主页

个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力

在csdn获奖荣誉: csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣  端午大礼包获得者
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 阿里云专家博主
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 亚马逊DyamoDB结营

欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦

文章目录

  • 实现任务阶段 7- 实现动态代理 Mapper 的方法
    • 代码实现
      • 创建WyxMapperProxy
        • 说明:
      • 修改WyxSqlsession.java
      • 创建WyxSessionFactory类
      • 完成测试
    • 总结
      • **深入解析:自己实现 MyBatis 底层机制系列**

实现任务阶段 7- 实现动态代理 Mapper 的方法

深入实现 MyBatis 底层机制的实现任务阶段 7- 实现动态代理 Mapper 的方法_第1张图片

代码实现

创建WyxMapperProxy



/**
 * WyxMapperProxy: 动态代理生成Mapper对象,调用WyxExecutor方法
 */
public class WyxMapperProxy implements InvocationHandler {
    //属性
    private WyxSqlSession wyxSqlSession;
    private String mapperFile;
    private WyxConfiguration wyxConfiguration;

    //构造器
    public WyxMapperProxy(WyxConfiguration wyxConfiguration,
                          WyxSqlSession wyxSqlSession,
                          Class clazz) {

        this.wyxConfiguration = wyxConfiguration;
        this.wyxSqlSession = wyxSqlSession;
        this.mapperFile = clazz.getSimpleName() + ".xml";
    }


    //前面讲解spring 时,讲过动态代理机制=>提示, 如果忘记了动态代理知识
    //去spring的博客笔记和代码回顾
    //提示:当执行Mapper接口的代理对象方法时,会执行到invoke方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        MapperBean mapperBean =
                wyxConfiguration.readMapper(this.mapperFile);

        //判断是否是xml文件对应的接口
        if (!method.getDeclaringClass().getName().equals(mapperBean.getInterfaceName())) {
            return null;
        }

        //取出mapperBean的functions
        List<Function> functions = mapperBean.getFunctions();
        //判断当前mapperBean解析对应MappperXML后 , 有方法
        if (null != functions && 0 != functions.size()) {

            for (Function function : functions) {
                //当前要执行的方法和function.getFuncName()一样
                //说明我们可以从当前遍历的function对象中,取出相应的信息sql, 并执行方法
                if(method.getName().equals(function.getFuncName())) {
                    //如果我们当前的function 要执行的sqlType是select
                    //我们就去执行selectOne
                    /**
                     *
                     * 说明:
                     * 1. 如果要执行的方法是select , 就对应执行selectOne
                     * 2. 因为就在WyxSqlSession就写了一个 selectOne
                     * 3. 实际上WyxSqlSession 应该对应不同的方法(多个方法)
                     * , 根据不同的匹配情况调用不同方法, 并且还需要进行参数解析处理, 还有比较复杂的字符串处理,拼接sql ,处理返回类型等等工作
                     * 4. 因为主要是讲解mybatis 生成mapper动态代理对象, 调用方法的机制,所以我做了简化
                     */
                    if("select".equalsIgnoreCase(function.getSqlType())) {
                        return wyxSqlSession.selectOne(function.getSql(),String.valueOf(args[0]));
                    }
                }
            }
        }

        return null;
    }


}

说明:

  1. 如果要执行的方法是select , 就对应执行selectOne

  2. 因为就在WyxSqlSession就写了一个 selectOne

  3. 实际上WyxSqlSession

应该对应不同的方法(多个方法) 根据不同的匹配情况调用不同方法, 并且还需要进行参数解析处理,还有比较复杂的字符串处理,拼接sql ,处理返回类型等等工作

  1. 因为主要是讲解mybatis 生成mapper动态代理对象, 调用方法的机制,所以我做了简化

修改WyxSqlsession.java

  1. 返回mapper的动态代理对象

  2. 这里clazz 到时传入的是 MonsterMapper.class

  3. 返回的就是MonsterMapper接口代理对象

  4. 当执行接口方法时(通过代理对象调用), 根据动态代理机制会执行到WyxMapperProxy-invoke

如果感觉高亮警告不舒服可以在方法上设置@SuppressWarnings(“unchecked”)

如果需要整个类没有警告可以使用 @SuppressWarnings(“all”)

    /**
     * 1. 返回mapper的动态代理对象
     * 2. 这里clazz 到时传入的是 MonsterMapper.class
     * 3. 返回的就是MonsterMapper接口代理对象
     * 4. 当执行接口方法时(通过代理对象调用), 根据动态代理机制会执行到WyxMapperProxy-invoke
     */
    public <T> T getMapper(Class<T> clazz) {

        //返回动态代理对象
        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz},
                new WyxMapperProxy(wyxConfiguration,this,clazz));
    }

创建WyxSessionFactory类

会话工厂-返回会话WyxSqlSession

package com.wyxedu.wyxmybatis.sqlsession;

/**
 * WyxSessionFactory 会话工厂-返回会话WyxSqlSession
 */
public class WyxSessionFactory {

    public static WyxSqlSession openSession() {
        return new WyxSqlSession();
    }
}

完成测试

修改 MonsterMapperTest增加测试方法

    @Test
    public void openSession() {

        WyxSqlSession wyxSqlSession = WyxSessionFactory.openSession();
        MonsterMapper mapper = wyxSqlSession.getMapper(MonsterMapper.class);
        Monster monster = mapper.getMonsterById(1);
        System.out.println("monster===" + monster);
    }

img

总结

通过本文,我们详细解析了如何创建一个简化版的MyBatis框架,通过动态代理来实现Mapper的功能。虽然我们目前只支持一个简单的select查询和一个参数,但这提供了一个很好的起点,可以进一步扩展来支持更复杂的查询和多个参数。

注意这是一个简化的例子,实际的 MyBatis 框架将包含许多其他功能和优化,包括错误处理、事务管理和更多。但通过这个简化的例子,我们可以更好地理解MyBatis背后的一些核心概念和工作原理。

深入解析:自己实现 MyBatis 底层机制系列

第一篇–>深入剖析:自己实现 MyBatis 底层机制的步骤与原理解析

第二篇–>深入解析:自己实现 MyBatis 底层机制的任务阶段1 - 读取配置文件与建立数据库连接

第三篇–>深入实现 MyBatis 底层机制的任务阶段2 - 编写执行器与数据库操作

第四篇-> 深入实现 MyBatis 底层机制的任务阶段3 - 封装 SqlSession 到执行器

第五篇–>深入实现 MyBatis 底层机制的任务阶段4 - 开发 Mapper 接口和 Mapper.xml

第六篇–>深入实现 MyBatis 底层机制的任务阶段 5- 开发和 Mapper 接口相映射的 MapperBean

第七篇–>深入实现 MyBatis 底层机制的任务阶段 6-实现任务阶段 6- 在 WyxConfiguration, 读取 XxxMapper.xml,能够创建 MappperBean 对象

第八篇->深入实现 MyBatis 底层机制的实现任务阶段 7- 实现动态代理 Mapper 的方法

热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力

你可能感兴趣的:(手写机制和源码分析,mybatis,oracle,数据库,java,maven,spring,boot,intellij-idea)