mybatiplus的apply_MyBatis Plus插件机制与执行流程原理分析详解

MyBatis Plus插件MyBatis Plus提供了分页插件PaginationInterceptor、执行分析插件SqlExplainInterceptor、性能分析插件PerformanceInterceptor以及乐观锁插件OptimisticLockerInterceptor。Mybatis 通过插件 (Interceptor) 可以做到拦截四大对象相关方法的执行 ,根据需求完成相关...
摘要由CSDN通过智能技术生成

MyBatis Plus插件

MyBatis Plus提供了分页插件PaginationInterceptor、执行分析插件SqlExplainInterceptor、性能分析插件PerformanceInterceptor以及乐观锁插件OptimisticLockerInterceptor。

Mybatis 通过插件 (Interceptor) 可以做到拦截四大对象相关方法的执行 ,根据需求完成相关数据的动态改变。

四大对象是:

Executor

StatementHandler

ParameterHandler

ResultSetHandler

四大对象的每个对象在创建时,都会执行interceptorChain.pluginAll(),会经过每个插件对象的 plugin()方法,目的是为当前的四大对象创建代理。代理对象就可以拦截到四大对象相关方法的执行,因为要执行四大对象的方法需要经过代理 。

① xml下插件的配置

如下所示:

② springboot下注册插件

这里以分页插件为例:

@Bean public PaginationInterceptor paginationInterceptor()

{

PaginationInterceptor paginationInterceptor = new PaginationInterceptor();

// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false

// paginationInterceptor.setOverflow(false);

// 设置最大单页限制数量,默认 500 条,-1 不受限制

// paginationInterceptor.setLimit(500);

// 开启 count 的 join 优化,只针对部分 left join

paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));

return paginationInterceptor;

}

③ SqlExplainInterceptor

SQL执行分析拦截器,全类名是com.baomidou.mybatisplus.plugins.SqlExplainInterceptor,只支持 MySQL5.6.3以上版本。

该插件的作用是分析 DELETE UPDATE语句 ,防止小白或者恶意进行DELETE UPDATE全表操作,不建议在生产环境中使用会造成性能下降,

在插件的底层通过SQL语句分析命令 Explain 分析当前的 SQL语句,根据结果集中的 Extra列来断定当前是否全表操作。

④ 性能分析插件

性能分析拦截器,全类名是com.baomidou.mybatisplus.plugins.PerformanceInterceptor,用于输出每条 SQL 语句及其执行时间。SQL性能执行分析 ,开发环境使用 超过指定时间,停止运行。

⑤ 乐观锁插件

全类名是com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor。如果想实现如下需求 : 当要更新一条记录的时候,希望这条记录没有被别人更新,就可以使用该插件进行判断。

乐观锁的实现原理(@Version 用于注解实体字段,必须要有) :

取出记录时,获取当前 version

更新时,带上这个version

执行更新时,set version = yourVersion+1 where version = yourVersion

如果 version不对,就更新失败

【2】获取sqlSessionFactoryBean

如下图所示,在系统启动时会初始化定义的bean。DefaultListableBeanFactory.preInstantiateSingletons方法中会从beanDefinitionNames中获取bean name然后依次创建。

这里可以看到RootBeanDefinition是com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean。

① 获取bean的过程中bean属性

如下所示,在getBean过程中可以看到bean的属性:

② createBean

第一次获取bean的时候会走到AbstractAutowireCapableBeanFactory.createBean进行bean的创建。

/** 创建一个bean实例,为bean实例设置属性值,调用post-processors-bean后置处理器 */@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)

throws BeanCreationException

{//...暂时忽略其他代码

try {// 这里会首先触发BeanPostProcessors ,如果这里能获取到bean则直接返回,不再走doCreateBean

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

if (bean != null)

{

return bean;

} }//...暂时忽略其他代码

在AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation中就会分别执行bean后置处理器的前置和后置方法。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)

{ Object bean = null;

if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved))

{

// Make sure bean class is actually resolved at this point.

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors())

{

Class> targetType = determineTargetType(beanName, mbd);

if (targetType != null) {

bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

if (bean != null)

{

bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);

}

}

}

mbd.beforeInstantiationResolved = (bean != null);

}

return bean;

}

执行后置处理器的前置方法如下所示:

③ doCreateBean

AbstractAutowireCapableBeanFactory.doCreateBean是创建bean的核心方法,这会为bean属性赋值并会触发bean后置处理器、InitializingBean以及自定init方法等。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException

{

// Instantiate the bean.--实例化beanBeanWrapper instanceWrapper = null;if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == nu

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值