2021一路有你,2022我们继续加油!你的肯定是我最大的动力博主在参加博客之星评比,点击链接,https://bbs.csdn.net/topics/603957267疯狂打Call!五星好评感谢吃透Mybatis源码-Mybatis初始化(一)吃透Mybatis源码-Mybatis执行流程(二)`吃透Mybatis源码-缓存的理解(三)吃透Mybatis源码-通过分析Pagehelper源码来理解Mybatis的拦截器(四)吃透Mybatis源码-面试官问我mapper映射器是如何工作的(五)吃透Mybatis源码-面试官问我Spring是怎么整合Mybatis的(六)前言我们在项目中都是
2021一路有你,2022我们继续加油!你的肯定是我最大的动力博主在参加博客之星评比,点击链接,https://bbs.csdn.net/topics/603957267疯狂打Call!五星好评感谢前言面试官:你说一下为什么Mapper映射器是一个interface,而我们却可以直接调用它的方法,还能执行对应的SQL。额…也许你不知道,也许你知道个大概,本篇文章将带你从源码的角度彻彻底底理解Mybatis的Mapper映射器Mapper的注册我们在执行Mybatis的时候可以使用sqlSession.selectOne("cn.whale.mapper.StudentMapper.s
2021一路有你,2022我们继续加油!你的肯定是我最大的动力博主在参加博客之星评比,点击链接,https://bbs.csdn.net/topics/603957267疯狂打Call!五星好评感谢前言面试官:用过pagehelper做分页把,你说一下pagehelper的分页实现原理。额…此时你只能说我不知道。如果你事先看了我接下来的这篇文章,相信你一定也把这个面试题答得很好。认识Mybatis插件(拦截器)SpringMVC的拦截器相信大家都清楚,作用是在Controller执行前或执行后拦截器请求从而实现对请求做增强,比如:登录检查等。在mybais中也有拦截器(当然它应该叫插件,我觉得
来来来,给俏如来扎起。感谢老铁们对俏如来的支持,2021一路有你,2022我们继续加油!你的肯定是我最大的动力博主在参加博客之星评比,点击链接,https://bbs.csdn.net/topics/603957267疯狂打Call!五星好评感谢前言对于Mybatis的缓存在上一章节《吃透Mybatis源码-Mybatis执行流程》我们有提到一部分,这篇文章我们对将详细分析一下Mybatis的一级缓存和二级缓存。一级缓存市面上流行的ORM框架都支持缓存,不管是Hibernate还是Mybatis都支持一级缓存和二级缓存,目的是把数据缓存到JVM内存中,减少和数据库的交互来提高查询速度。同时My
来来来,给俏如来扎起。感谢老铁们对俏如来的支持,2021一路有你,2022我们继续加油!你的肯定是我最大的动力博主在参加博客之星评比,点击链接,https://bbs.csdn.net/topics/603957267疯狂打Call!五星好评感谢。前言上一篇文章我们分析了一下Mybatis的初始化流程,跟踪了一下Mybatis的配置解析过程,SqlSessionFactory和SqlSession的创建过程,这篇文章我们来分析一下SqlSession的执行流程Mybatis的执行流程下面这个图是在上一章《Mybatis初始化》有分析过的Mybatis的执行流程Mybatis执行流程如下初始化阶
来来来,给俏如来扎起。感谢老铁们对俏如来的支持,2021一路有你,2022我们继续加油!你的肯定是我最大的动力博主在参加博客之星评比,点击链接,https://bbs.csdn.net/topics/603957267疯狂打Call!五星好评感谢。前言Mybatis是Java项目开发使用率非常高的一款持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。MyBatis可以通过简单的XML或注解来配置和映射原始类型、接口和JavaPOJO(PlainOldJavaObjects,普通老式Java对象)为数据库中的记录。同时
上一篇Mybatis源码分析刚讲过PageHelper分页机制https://blog.csdn.net/shenchaohao12321/article/details/80168655,但是没有分析reasonable参数,碰到这次自己遇上个坑总结一下。问题描述及原因使用MybatisPageHelper插件做了表的分页查询,要求查询符合某一条件的所有记录做处理,就写了一个迭代器在while循环里对每条记录做处理,直到符合条件的记录都处理完程序返回。代码如下publicclassReconPaymentIteratorimplementsIterator<ReconPayment&g
PageInterceptor是Mybatis的插件,用于拦截Executor的query方法,增强这个方法用于分页查询。@Intercepts({@Signature(type=Executor.class,method="query",args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class}),@Signature(type=Executor.class,method="query",args={MappedStatement.class,Object.
MyBatis允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis允许使用插件来拦截的方法调用包括:Executor(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)ParameterHandler(getParameterObject,setParameters)ResultSetHandler(handleResultSets,handleOutputParameters)StatementHandler(prepare,parameterize,batch,upd
Mybatis懒加载是通过动态代理完成的,通常来说Mybaits的映射实体都是POJO,所以Mybatis默认使用Cglib来做动态代理框架的。使用CglibProxyFactory的createProxy方法创建代理对象。其中又直接调用了EnhancedResultObjectProxyImpl静态createProxy方法。publicObjectcreateProxy(Objecttarget,ResultLoaderMaplazyLoader,Configurationconfiguration,ObjectFactoryobjectFactory,List<Class<?
ResultSetHandler提供了处理不同Statement的方法,我们这里分析最常用的handleResultSets。调用此方法将一个Statement对象转换为一个List对象。publicList<Object>handleResultSets(Statementstmt)throwsSQLException{ErrorContext.instance().activity("handlingresults").object(mappedStatement.getId());finalList<Object>multipleResults
上一篇分析到如果二级缓存没有命中,则会调用一个Executor(默认是SimpleExecutor)的query方法,SimpleExecutor继承了BaseExecutor,直接调用BaseExecutor的query方法。BaseExecutor有一个PerpetualCache实例localCache(一级缓存,因为生命周期和executor一样)用于缓存查询结果。public<E>List<E>query(MappedStatementms,Objectparameter,RowBoundsrowBounds,ResultHandlerresultHandle
DefaultSqlSession执行selectList方法内实际调用CachingExecutor的query方法,上篇文章分析过了BoundSql的获取过程,下面继续往下说一下二级缓存。public<E>List<E>query(MappedStatementms,ObjectparameterObject,RowBoundsrowBounds,ResultHandlerresultHandler)throwsSQLException{BoundSqlboundSql=ms.getBoundSql(parameterObject);CacheKeykey=crea
上篇文章分析Mapper的查询操作最终都会调用SqlSession的selectList方法,接下来几篇文章分析一下DefaultSqlSession的selectList的执行过程。public<E>List<E>selectList(Stringstatement,Objectparameter,RowBoundsrowBounds){try{MappedStatementms=configuration.getMappedStatement(statement);returnexecutor.query(ms,wrapCollection(parameter),r
当我们通过DefaultSqlSession的Mapper方式操作数据库时使用如下api:<T>TgetMapper(Class<T>type);此方法返回一个实现了type接口的实现类的实力,我们分析一下此实力的创建过程。public<T>TgetMapper(Class<T>type){returnconfiguration.<T>getMapper(type,this);}public<T>TgetMapper(Class<T>type,SqlSessionsqlSession){returnmapper
SqlSession是我们操作数据库的主要客户端API,是由SqlSessionFactory的openSession方法所创建。openSession有多个重载方法,我们看一下:publicinterfaceSqlSessionFactory{SqlSessionopenSession();SqlSessionopenSession(booleanautoCommit);SqlSessionopenSession(Connectionconnection);SqlSessionopenSession(TransactionIsolationLevellevel);SqlSessionopen
Mybatis中DataSourceFactory是负责创建DataSource对象的,Mybatis一共为我们提供了3种DataSourceFactory的实现,不同的DataSourceFactory创建不同的DataSource,分别为UnpooledDataSourceFactory,PooledDataSourceFactory和JndiDataSourceFactory。具体使用哪种DataSourceFactory我们在《SqlSessionFactory的创建过程》中分析过了,下面详细说一下PooledDataSourceFactory和UnpooledDataSourceFa
上一篇我们讲解到mapperElement方法用来解析mapper的,我们以packae属性为例详细分析一下:privatevoidmapperElement(XNodeparent)throwsException{if(parent!=null){for(XNodechild:parent.getChildren()){if("package".equals(child.getName())){StringmapperPackage=child.getStringAttribute("name");configuration.addMappers(ma
我们使用mybatis操作数据库都是通过SqlSession的API调用,而创建SqlSession是通过SqlSessionFactory。下面我们就通过一个例子看看SqlSessionFactory的创建过程。publicclassTestEntity{privatelongid;privateStringname;privateDatedate;}publicinterfaceTestMapper{TestEntitygetById(longid);}<?xmlversion="1.0"encoding="UTF-8"?><!DO
一、Mybatis核心流程图解在前面的三篇文章我们按照Mybatis的三大核心流程分析了每个流程的具体工作,本文我们通过流程图的形式展现整个流程,因为流程比较长,还是分为三个图来展示。1.1初始化阶段数据初始化阶段是读取配置,初始化Configuration对象,获取SqlSessionFactory的过程。1.2代理阶段代理阶段是根据接口类型和方法,返回一个代理对象1.3数据读取阶段数据读取阶段,通过代理对象最终执行对应的sql语句。更加详细的流程可以阅读参考文章…二、参考[1]20-Mybatis核心流程01-初始化阶段[2]21-Mybatis核心流程02-代理阶段[3]22-Mybat
核心流程-数据读取阶段一、核心流程-数据读取阶段Mybatis的核心流程三大阶段是:初始化–>动态代理–>数据读写阶段,本文主要分析数据读取阶段。在完成了第一阶段的配置初始化和第二阶段的动态代理之后,我们获得了一个代理对象来面向接口编程,便捷的访问数据库,按照前一篇文章21-Mybatis核心流程02-代理阶段的分析我们知道底层还是会走到sqlsession,数据读取阶段就是通过SqlSession完成SQL解析,参数的映射,SQL的执行,结果的解析映射的这个过程。二、Executor2.1功能Executor是数据读取阶段的关键,从21-Mybatis核心流程02-代理阶段我们知
核心流程-代理阶段一、核心流程-代理阶段1.1分析Mybatis的核心流程三大阶段是:初始化–>动态代理–>数据读写阶段,本文主要分析代理阶段。在初始化阶段主要完成了配置的初始化,代理阶段主要是封装ibatis的编程模型,完成相关的工作以满足通过Java接口访问数据库的功能,代理阶段主要是在binding模块实现的,该模块通过读取配置信息,然后通过动态代理来实现面向接口的数据库操作。从最初我写过的入门的文章里面可以看到,即使没有Java接口,也可以直接使用sqlSession来调用Mapper.xml映射文件里面的语句执行数据库的操作,只要定位到映射文件中正确的namespace+
核心流程-初始化阶段一、核心流程-初始化阶段Mybatis的核心流程三大阶段是:初始化–>动态代理–>数据读写阶段,本文主要分析初始化阶段。初始化阶段主要是完成XML配置文件和注解配置信息的读取,创建全局单例的Configuration配置对象,完成各部分的初始化工作,具体的创建过程需要三个核心类来完成解析。二、核心类2.1创建Configuration的三个核心类创建Configuration的核心类和作用如下类名作用XmlConfigBuilder加载解析主配置文件XmlMapperBuilder加载解析mapper映射文件中非SQL节点部分XmlStatementBuilde
四大对象-ResultSetHandler(结果集映射)一、ResultSetHandlerResultSetHandler在Mybatis四大对象中负责将数据库结果集转换为Java对象集合。它是一个接口,有且只有一个实现类DefaultResultSetHandler。publicinterfaceResultSetHandler{/***将ResultSet映射成对应Java类集合*/<E>List<E>handleResultSets(Statementstmt)throwsSQLException;/***将ResultSet处理成Cursor对象*/<E
Mybatis参数读取源码分析Mybatis框架最底层需要访问数据库,本质是到数据库去执行sql语句,那么给sql语句传递参数是必不可少的一个环节,sql语句在预编译阶段会用占位符替换参数的位置,在需要执行的时候需要将参数放到对应的位置上,这个将参数替换占位符的工作就是ParameterHandler来完成的,本文我们来看看这个对象处理的相关知识。一、ParameterHandlerParameterHandler在Mybatis四大对象中负责将sql中的占位符替换为真正的参数,它是一个接口,有且只有一个实现类DefaultParameterHandlerpublicinterfacePara
StatementHandler一、StatementHandler和Statement1.1StatementHandler接口StatementHandler是Mybatis四大对象之一,它完成Mybatis最核心的工作,它封装了Statement的相关操作来完成数据库的访问,也是Executor组件的基础。包括创建Statement对象,为sql绑定参数,执行sql,结果集映射等。它是一个接口,使用不同的实现类来处理不同的情况,并且采用了模板模式,使用BaseStatementHandler来完成基本骨架,子类继承然后实现具体方法细节。在了解StatementHandler之前,我们先了
SqlSession模块与策略模式一、策略模式策略模式请参考:03-行为型模式(上)二、功能SqlSession是Mybatis的对外最核心的接口,通过该接口来实现数据库的读写命令,事物管理等。SqlSession本质是提供数据库操作的,包括数据库的四大操作。如下是ibatis的编程方式,我们直接通过Sqlsession来访问数据库。@Testpublicvoidquery(){SqlSessionsqlSession=SqlSessionFactoryUtil.getSqlSessionFactoryInstace().openSession();List<Object>list
Mybatis插件一、自定义插件1.1示例如下是Mybatis分页插件里面实现的一个插件,我们从这里开始看实现自定义插件的方法/***QueryInterceptor规范*详细说明见文档:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/Interceptor.md*@authorliuzh/abel533/isea533*@version1.0.0*/@Intercepts({@Signature(type=Executor.class,method="query",args={Ma
Executor组件与模板模式一、Executor组件Executor是Mybatis中用于执行数据库操作的核心接口,定义了数据库操作的基本方法。我们知道SqlSession是对用户暴露的核心接口,用户通过SqlSession来操作数据库,但实际上底层调用的就是Executor组件的接口。在数据库的查询操作过程中,Mybatis中定义的整体操作流程是差不多的,以查询为例:大体分为SqlSession执行sql->获取sql信息->拼装缓存key->判断是否需要清空一级缓存->查找一级缓存->根据是否命中判断是否需要查询数据库->查询结果->缓存会写-&
数据源创建和和策略模式一、数据源在10-Mybatis源码和设计模式-1(数据源模块和工厂模式,代理模式)中我们了解了数据源模块有三种类型,POOL,UNPOOL和JNDI三种,知道这三种类型的数据源都是通过工厂模式创建出来的,但没有分析数据源的创建过程和创建的策略,仅仅只是静态分析了源码结构。数据源的类型由Environment里的type指定,对于客户端来说不管底层是如何创建数据源的都没有关系,只需要修改配置就能够生产出3种不同类型的数据源。而这种思想恰好和策略模式相符合,因此数据源的创建使用了策略模式。关于策略模式,可以参考:03-行为型模式(上)1.1配置配置示例如下:<!--配