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

2023-09-11 15:14:11

😀前言
在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. 如果要执行的方法是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连支持一下,创造不易您们的支持是我的动力🤞

更多推荐

Android UT开发简介

一、概述AndroidUT(UnitTesting)开发是指在Android应用程序中进行单元测试的开发过程。单元测试是一种软件测试方法,用于测试应用程序中的最小可测试单元(通常是函数或方法)的正确性。AndroidUT开发的主要目标是确保应用程序的各个单元在不同情况下能够按照预期正确运行。通过编写、运行和维护单元测试

免费、安全、可靠!一站式构建平台 ABS 介绍及实例演示 | 龙蜥技术

编者按:操作系统是一个大的软件集合,成百上千个软件之间有相互调用、相互依赖等各种复杂的关联关系,所以统一的软件包格式,能够更友好地管理、定义这些复杂关系。今天,龙蜥社区基础设施Contributor单凯伦带大家了解龙蜥社区官方构建平台ABS,熟悉AnolisOS软件包、镜像构建流程以及ABS未来规划等。本文整理自龙蜥大

【Windows 11】安装 Android子系统 和 Linux子系统

本文使用电脑系统:文章目录一、安卓子系统1.1安装WSA1.2使用二、Linux子系统2.1安装WSL以及WSL相关概念2.2安装一个Linux发行版2.21从MicrosoftStore安装2.22用命令安装2.23拓展三、拓展3.1存储位置3.2虚拟化技术3.3Windows虚拟内存3.3wsl帮助文件一、安卓子系

MySQL 锁机制

1.锁是什么?是为了保证数据并发访问时的一致性和有效性,数据库提供的一种机制。锁机制的优劣直接影响到数据库的并发处理能力和系统性能,所以锁机制也就成为了各种数据库的核心技术之一。同时,锁机制也为实现MySQL事务的各个隔离级别提供了保证。2.锁的缺点锁是一种消耗资源的机制,想要实现锁的各种操作,包括获得锁、检测锁是否已

2023数学建模国赛游记

第一参加数学建模国赛,大概也是最后一次参加了,记录一下这几天的历程吧。我们队的情况是计算机+电气+数统,计算机负责编程,电气学院的负责论文部分,数统的同学负责建模,数据处理部分我们是共同承担。第一天下午6点发题,5点学校的所有队伍基本都到管理学院的机房在等着发题,5点多题发了,我们开始看题,几个人扫了一下C题觉得可以做

Can‘t call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.

错误Can'tcallnumpy()onTensorthatrequiresgrad.Usetensor.detach().numpy()instead.原因变量带有梯度,直接将其转换为numpy数据将破坏计算图,因此numpy拒绝进行数据转换,实际上这是对开发者的一种提醒。如果自己在转换数据时不需要保留梯度信息,可以

【探索C++】C++对C语言的扩展

(꒪ꇴ꒪),Hello我是祐言QAQ我的博客主页:C/C++语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮!送给自己和读者的一句鸡汤🤔:集中起来的意志可以击穿顽石!作者水平很有限,如果发现错误,请在评论区指正,感谢🙏一、引用1.变量名变量名本质上就

优思学院|看板方式与传统生产方式的对比

看板方式的起源有些人以为“丰田生产方式”和“看板方式”是一样的,其实并非如此。前者是物品的制造方式、流动方式,后者则是传递制造资讯的方式。创造出看板方式的灵感,是从超市的销售方式得来的。超市的顾客只会在有需要的时候购买所需要的物品,而且只购买需要的数量。准时生产(JIT):市场需求驱动的制造策略从这一点衍伸出准时生产(

JAVA设计模式1:单例模式,确保每个类只能有一个实例

作者主页:Designer小郑作者简介:3年JAVA全栈开发经验,专注JAVA技术、系统定制、远程指导,致力于企业数字化转型,CSDN学院、蓝桥云课认证讲师。主打方向:Vue、SpringBoot、微信小程序本文讲解了Java设计模式中的单例模式,并给出了样例代码,单例模式,确保每个类只能有一个实例,并提供一个全局访问

Vue3自定义指令

文章目录Vue3自定义指令1.自定义全局指令v-focus2.自定义局部指令v-focus3.指令定义的钩子函数3.1概念3.2钩子函数参数3.3vnode&prevNode3.4简写3.5指令函数接受JavaScript表达式Vue3自定义指令1.自定义全局指令v-focus除了默认设置的核心指令(v-model和v

【python】入门第一课:了解基本语法(数据类型)

目录一、介绍1、什么是python?2、python的几个特点二、实例1、注释2、数据类型2.1、字符串str2.2、整数int2.3、浮点数float2.4、布尔bool2.5、列表list2.6、元组tuple2.7、集合set2.8、字典dict一、介绍1、什么是python?Python是一种通用的高级编程语言

热文推荐