当前位置:首页 > mybatis > 正文内容

源码解析--mybatis mapper接口为啥没有实现类

关中浪子2年前 (2022-04-06)mybatis1643
【腾讯云】2核2G4M云服务器新老同享99元/年,续费同价
找梯子最重要的就是稳定,这个已经上线三年了,一直稳定没有被封过,赶紧下载备用吧!

mybatis接口没有实现类,是如何实现功能的呢?

程序员都知道是mapper里面的接口名称和mapper.xml里面的名称一致,然后用的时候直接调用接口的方法就好了,但是里面具体的技术实现细节很多码农不一定懂,今天我就分析一下带领大家分析下具体实现原理。


1.加载配置文件创建SqlSession

 

public SqlSessionFactory getSqlSessionFactory() throws IOException {
        // 1.加载核心配置文件
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        // 2.读取配置文件的内容
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
        return sqlSessionFactory;
    }


如果是springboot项目,不需要此配置文件sqlMapConfig.xml,springboot启动时直接从yml配置文件中相关的mybats配置中加载相关xml和数据库连接配置。

启动时根据mapper.xml文件中的namespace来创建mapper对象(利用class.forname反射来生成类对象)



2.打开openSession

数据库连接信息mybatis会生成一个configuration类,此类里面会保存数据库连接信息


3.得到mapper对象


public void addUser() throws IOException {
        // 3.使用sqlSessionFactory对象,创建SqlSession对象,开启自动提交事务
        SqlSession sqlSession = this.getSqlSessionFactory().openSession(true);
        // 调用方法执行
        User user = new User();
        //user.setId(4);
        user.setUsername("林诗音");
        user.setBirthday(new Date());
        user.setSex("女");
        user.setAddress("来自大明朝");
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.addUser(user);
        //sqlSession.insert("com.test.mybatis.UserMapper.addUser", user);
        // 事务提交
        // sqlSession.commit();
        // 释放资源
        sqlSession.close();
    }
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

我们来分析这行代码,点进去如图


再进去如图,会出现一个 mapperProxyFactory 的类,而且是直接获取的,为啥呢,因为在启动的时候已经add进去了,根据配置文件xml,所以这里直接获取到 mapper代理工厂,然后调用代理工厂的newInstance方法



4.创建代理类

我们在往下看,

代码走到35行,我们看到new 了一个 mapperPorxy 的类,给他传入了mapper接口

然后代码走到31行,直接proxy类创建了一个newProxyInstance,并传入刚才创建的mapperProxy类

这里的话,我们需要复习下java动态代理的知识


我们在看看mapperProxy长啥样,如图,实现了InvocationHandler接口,我们知道实现InvocationHandler接口的类,被调用时会执行invoke方法,这些是java动态代理的知识,java动态代理只能用于接口,无法用于具体的类包括抽象类,因此这就是mybatis mapper中的接口只有接口没有实现类的原因。


那么啥时候执行invoke呢,就是在执行下面代码的时候

userMapper.addUser(user);

执行这行代码的时候会调用invoke,我们看看


image.png

MapperMethod mapperMethod = this.cachedMapperMethod(method);

mapperMethod 对象就是我们的mapper接口中的 addUser方法

return mapperMethod.execute(this.sqlSession, args);

args就是传入的实体对象,然后执行execute方法实现了操作数据库


5.XML中的SQL语句如何得到

也是从configuration.getMappedStatement(具体的方法名称)得到,sql有了,参数和实体也有了,就可以直接执行了


到此我们的分析基本结束,比较浅陋,但是基本流程大致如此,对了如果是springboot项目如何得到mapper对象呢,应该也是一样的,在我们的service层中的类中的 mapper接口字段,注解@Autowired时会被注入进去,咋么来的呢,当然是在启动的时候就已经添加进去了通过addmapper,所以不需要像单独mybatis 测试时的代码需要单独get才可以获取mapper。

好了,分析到此为止,有啥问题和建议,请私信或者公众号。欢迎大家关注我的公众号 【码农翻生】



扫描二维码推送至手机访问。

版权声明:本文由码农翻生发布,如需转载请注明出处。

本文链接:https://lubojian.cn/post/161.html

分享给朋友:

相关文章

mybatis框架学习(完整)强烈推荐

mybatis框架学习(完整)强烈推荐

目录 总结jdbc出现的问题mybatis介绍mybatis入门程序占位符#{}与字符串拼接符${}区别mybatis框架的原理别名配置与映射文件加载方式mybatis与hibernate的比较 一、总结jdbc出现的问...

超全MyBatis动态代理详解!(绝对干货)绝命三连问

超全MyBatis动态代理详解!(绝对干货)绝命三连问

前言假如有人问你这么几个问题,看能不能答上来Mybatis Mapper 接口没有实现类,怎么实现的动态代理JDK 动态代理为什么不能对类进行代理(充话费送的问题)抽象类可不可以进行 JDK 动态代理(附加问题)答不上来的铁汁,证明 Pro...

MyBatis源码分析 SqlSession.getMapper()背后做了什么

一、什么是 MyBatis?       直接看官方文档:https://mybatis.org/mybatis-3/zh/index.html。       ...

源码解析--mybatis一级缓存和二级缓存

源码解析--mybatis一级缓存和二级缓存

MyBatis缓存使用缓存可以时应用更快地获取数据,避免频繁地数据库交互,尤其是在查询越多、缓存命中率越高地情况下,使用缓存地作用就越明显。MyBatis作为持久化框架,提供了非常强大地查询缓存特性,可以非常方便地配置和定制使用。MyBat...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。