• 深入实现 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 的方法

    img

    代码实现

    创建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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    说明:
    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));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    创建WyxSessionFactory类

    会话工厂-返回会话WyxSqlSession

    package com.wyxedu.wyxmybatis.sqlsession;
    
    /**
     * WyxSessionFactory 会话工厂-返回会话WyxSqlSession
     */
    public class WyxSessionFactory {
    
        public static WyxSqlSession openSession() {
            return new WyxSqlSession();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    完成测试

    修改 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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    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连支持一下,创造不易您们的支持是我的动力🤞

  • 相关阅读:
    ELK企业级日志分析系统
    桌面运维命令
    PVE Cloud-INIT 模板配置
    微信小程序能给花店带来哪些作用_分享花店微信小程序开发优势
    python装13的一些写法
    PaddlePaddle框架安装
    一级造价工程师(安装)- 计量笔记 - 第六章第一节电气工程
    Python数据类型——字典(Dictionary)
    前端面试题集锦(3)
    【开源】基于JAVA的大学兼职教师管理系统
  • 原文地址:https://blog.csdn.net/apple_67445472/article/details/132808457