Mybatis死磕源码笔记之SqlSession启动原理及对数据库操作原理(一)

本文深入剖析MyBatis框架的启动流程与SqlSession创建原理,揭示如何通过接口编程访问数据库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近空闲下来决定读一读mybatis源码,先从启动入手,mybatis是一个轻量级ORM框架,它封装了对数据库的常用操作,我们用起来非常简单,可是对它的内部原理我们一无所知,这不利于我们调试和优化代码,因此最好的方式就是深入源码去理解其原理,下面,本文从mybatis启动来深入源码探究。

首先,举一个简单的例子来入手:
GetSqlSession.java:

package cn.just.configuration;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class GetSqlSession {
    private static SqlSessionFactory sqlSessionFactory;
    private static Reader reader; 
    private static SqlSession sqlSession;
    static{
        try{
            reader= Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); //
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static SqlSession GetSqlSession(){
    try {
        sqlSession=sqlSessionFactory.openSession();
        System.out.println("创建SqlSession");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return sqlSession;
    }   
}

BuilderConfig.java

package cn.just.configuration;


import org.apache.ibatis.session.SqlSession;

import cn.just.interfaceMapper.UserMapper;
import cn.just.mapper.Test;

public class BuilderConfig {
   public static void main(String[] args) {

        SqlSession sqlSession=GetSqlSession.GetSqlSession();
        UserMapper user=sqlSession.getMapper(UserMapper.class);
        Test test=user.selectById(1);
        System.out.println(test.toString());
    }
}

UserMapper .java

package cn.just.interfaceMapper;

import cn.just.mapper.Test;

public interface UserMapper {
    public Test selectById(Integer id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.just.interfaceMapper.UserMapper">
    <select id="selectById" resultType="cn.just.mapper.Test">
    select * from test where id=#{id}
    </select>   
</mapper>

上面是该实例的部分代码,全局配置以及数据库连接属性这里省略,非常简单,就是通过mybatis接口编程来从数据库查询对象。我们不加细讲上面代码,直接打断点开始阅读源码。

一、SqlSessionFactory启动原理

为了更方便理解源码,这里我先给出SqlSession创建过程导航图,然后我们来根据该图一步一步来进入源码探究。这样也不至于绕晕在源码中。
这里写图片描述

OK,从上面导航图我们可以看出,当项目启动首先通过SqlSessionFactoryBuilder的build(inputStream)方法进入创建SqlSession。因此我们打断点进入build方法:
这里写图片描述

进入build方法后我们会看到一个XmlConfigBuilder对象,它将参数传入并且创建,这里我们猜想,如果要想创建SqlSession就是要和数据库建立连接,因此它就要解析全局XML配置文件来读取数据源并且连接数据库,因此XmlConfigBuilder这个对象就是一个xml解析器。所以我们继续进入parse()方法。
这里写图片描述

进入parse方法后我们惊奇的发现它会创建一个Configuration对象,而这个Configuration对象封装了我们全局配置中的所有属性,比如settings,properties,mappers等等,这就很明显了,Configuration对象就是在parse解析全局XML配置文件后的一个封装类,它会通过这个类去创建建立数据库连接以及SqlSession的创建,我们接着往下走。
这里写图片描述
在这里,有一个要点,就是创建好Configuration后,它有一个MapperRegistry它封装着一个代理类,因为我们是通过接口变成的方式去操作数据库,因此它会为该接口创建一个代理类来实例化该接口。
这里写图片描述

最后,在疯转好所有的配置后,返回build方法创建一个DefaultSqlSessionFactory对象来创建回话。
这里写图片描述
这里写图片描述

到这里,我们就可以很清楚的看出mybatis创建SqlSessionFactory创建会话的原理了,最后,我们来探究一下它是如何通过接口来访问获取sql语句查询数据库的。

二、通过接口获取sql查询数据库

这里,我们就需要回到上面Configuration封装的那个类中去,我们可以在上图看出有一个很重要的对象MapperStatement对象,这个对象封装着对mapper文件的配置。

这里写图片描述

接着,我们进入mapperParser的parse方法中去。
这里写图片描述
很明显,它通过反射获取到UserMapper这个接口。我们接着跟下去。
这里写图片描述
这里写图片描述
从上面截图可以看出,它会创建一个MapperAnnotationBuilder对象,它封装着对数据库的各种操作,update,insert等等。
这里写图片描述
最后,我们进入parse防范,它通过反射来获取selectById方法,在parse方法执行后,它会调用 parsePendingMethods(),因此我们进入该方法,会看到它会通过封装好的Configuration对象来得到集合并且遍历,而在这个Conifguration对象中通过namespace获得了sql语句,最后操作数据库。
这里写图片描述

至此,我们就通过源码了解到SqlSessionFactory的启动原理以及通过接口产生代理对象来操作数据库的原理,以上如有什么不足或错误请多多指点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值