MyBatis源码学习(2)

本文详细介绍了MyBatis框架的初始化过程,从加载配置文件到创建SqlSessionFactory及SqlSession对象,逐步剖析了MyBatis的内部实现机制,包括资源加载、配置解析、会话工厂与会话创建等关键步骤。

MyBatis源码初探

搭建好了 MyBatis的环境,接下来就是debug学习了,正常的一个main函数执行流程是,加载xml–>生成SqlSessionFactory–>生成SqlSession–>get到你的xml对应的mapper–>调用Mapper的方法。
那么这其中涉及到的MyBatis的类有Resource、SqlSessionFactory、SqlSession,这是我们能看见的,这其中当然也包括内部调用了MyBatis的别的类的方法,下面我们来一个一个看一看。
首先Resource没什么可说的就是加载进资源,目的是得到一个InputStream流,main方法里的代码:

String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
            } catch (IOException e) {
                e.printStackTrace();
            }

得到InputStream用来干嘛呢?用来生成SqlSessionFactory,这里MyBatis用了建造者模式,它里面很多地方都用了这个设计模式,SqlSessionFactory是个接口它获取这个接口的实现是通过SqlSessionFactoryBbuilder来获取的

  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

这个SqlSessionFactoryBbuilder里面有九个build方法,类图:
类里面没有任何属性只有9个方法
方法的参数各自不同,简单说来就是流、Properties和一个String类型表是数据库环境的字段,最终所有方法都会走到一个三个参数都有的build方法中,

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
        SqlSessionFactory var5;
        try {
            XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
            var5 = this.build(parser.parse());
        } catch (Exception var14) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
        } finally {
            ErrorContext.instance().reset();

            try {
                inputStream.close();
            } catch (IOException var13) {
                ;
            }

在这个方法里面主要就是做了两件事,一件事是new了一个XmlConfigBuilder类,这个类首先是BaseBuilder的子类
XMLConfigBuilder有三个自己的属性
boolean类型表是是否已经解析,还有一个XPath解析器,还有一个数据库的版本,在它内部的构造方法里面它做了这么几件事,第一它调用了它父类BaseBuiler的一个构造方法,传入的参数是它new了一个Configuration传了进去,

 private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
        super(new Configuration());
        ErrorContext.instance().resource("SQL Mapper Configuration");
        this.configuration.setVariables(props);
        this.parsed = false;
        this.environment = environment;
        this.parser = parser;
    }

这个Configuration也是MyBatis内部的一个类,这个类很重要用来保存MyBatis的配置数据,比如我们<set>标签里的节点,
这里写图片描述
对应我们的mybatis-config.xml
这里写图片描述

protected boolean cacheEnabled = true;

缓存标识,也就是说MyBatis默认启用了一级缓存,protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
本地缓存的级别是Session,还提供了生成执行器Executor的方法,回到SqlSessionFactory里面new完XmlConfigBuilder类之后,会调用SqlSessionFactory里面一个build方法就是this.build传入的参数就是我们刚刚new的XMLcONFIGBuiler里面生成的Configuration对象,做了一件什么事呢?就是new了一个DefaultSqlSessionFactory类,

  public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
    }

DefaultSqlSessionFactory是MyBatis接口SqlSessionFactory的一个实现类,最主要的方法当然就是openSession的实现了,那么openSession有很多种实现,就是参数不同,参数共有三种configuration、事物隔离级别TransactionIsolationLevel和是否开始事物的标识autoCommit有传入启事物标识的,有传入执行器的,等等。那么所有的openSession其实也都是调用它内部的一个所有参数都传的一个方法叫做openSessionFromSource三个参数就是,

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
        Transaction tx = null;

        DefaultSqlSession var8;
        try {
            Environment environment = this.configuration.getEnvironment();
            TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
            tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
            Executor executor = this.configuration.newExecutor(tx, execType);
            var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
        } catch (Exception var12) {
            this.closeTransaction(tx);
            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + var12, var12);
        } finally {
            ErrorContext.instance().reset();
        }

        return var8;
    }

那么这个里面它其实就做了一件事就是new了一个DefaultSqlSession由此那么SqlSessionFactory是接口,SqlSession是接口,那么我们默认情况下,MyBatis都会创建一个接口的默认实现,比如DefaultSqlSessionFactory,这里面又有一个DefaultSqlSession,这个DefaultSqlSession的构造方法是三个参数configuration、executor执行器和autoCommint是否自动提交,

    public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
        this.configuration = configuration;
        this.executor = executor;
        this.dirty = false;
        this.autoCommit = autoCommit;
    }

那么我们来看DefaultSqlSessionFactory
executor怎么获取的呢,通过configuration来获取,这Configuration类的片段:

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? this.defaultExecutorType : executorType;
        executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
        Object executor;
        if (ExecutorType.BATCH == executorType) {
            executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
            executor = new ReuseExecutor(this, transaction);
        } else {
            executor = new SimpleExecutor(this, transaction);
        }

        if (this.cacheEnabled) {
            executor = new CachingExecutor((Executor)executor);
        }

        Executor executor = (Executor)this.interceptorChain.pluginAll(executor);
        return executor;
    }

也是没有指定的话,MyBatis会默认给一个,就是SimpleExecutor类,这个类实现了Executor这个接口,也是MyBatis提供的三个Executor实现类之一,那么这个也值得一说,我们今天先不看,免得迷失在一堆类、方法的调用中,越来越乱,还是顺着一条直线放下走。到此我们就可以调用openSession方法来获取一个SqlSession对象了,然后利用SqlSession的getMapper方法获取Mapper,调用Mapper的方法来和数据库通信,就是增删改查嘛,至此,一个大流程,我们梳理完了,这其中还有还多细节,我们没有关注,比如:一级缓存,缓存在哪里做的?Mapper是利用动态代理来实现的,那么具体是怎么实现的呢?最后又是怎么和JDBC包装来访问的数据库呢?事物机制是怎么做的呢?这些问题都要看,所以这只是万里长征第一步,接下来我们在带着这些问题逐一去探索吧,今天先写到这里。

内容概要:本文系统阐述了Java Persistence API(JPA)的核心概念、技术架构、核心组件及实践应用,重点介绍了JPA作为Java官方定义的对象关系映射(ORM)规范,如何通过实体类、EntityManager、JPQL和persistence.xml配置文件实现Java对象与数据库表之间的映射与操作。文章详细说明了JPA解决的传统JDBC开发痛点,如代码冗余、对象映射繁琐、跨数据库兼容性差等问题,并解析了JPA与Hibernate、EclipseLink等实现框架的关系。同时提供了基于Hibernate和MySQL的完整实践案例,涵盖Maven依赖配置、实体类定义、CRUD操作实现等关键步骤,并列举了常用JPA注解及其用途。最后总结了JPA的标准化优势、开发效率提升能力及在Spring生态中的延伸应用。 适合人群:具备一定Java基础,熟悉基本数据库操作,工作1-3年的后端开发人员或正在学习ORM技术的中级开发者。 使用场景及目标:①理解JPA作为ORM规范的核心原理与组件协作机制;②掌握基于JPA+Hibernate进行数据库操作的开发流程;③为技术选型、团队培训或向Spring Data JPA过渡提供理论与实践基础。 阅读建议:此资源以理论结合实践的方式讲解JPA,建议读者在学习过程中同步搭建环境,动手实现文中示例代码,重点关注EntityManager的使用、JPQL语法特点以及注解配置规则,从而深入理解JPA的设计思想与工程价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值