分页插件PaginationInterceptor
其原理与mybatis插件的创建没有区别。
1. PaginationInterceptor,implements Interceptor
2. 使用@Intercepts注解完成插件签名
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
拦截的是4大对象中的StatementHandler中的prepare方法,参数有两个
3. 将插件注册到全局配置文件中
<!--注册分页插件--> <bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"> </bean>
其执行过程就是创建StatementHandler对象的时候,执行plugin方法,生成代理对象。当执行prepare方法的时候,先执行intercept方法
DialectModel model = DialectFactory.buildPaginationSql(page, buildSql, dbType, dialectClazz);
针对不同的dbType,生成不同的分页sql
public class MySqlDialect implements IDialect { @Override public DialectModel buildPaginationSql(String originalSql, long offset, long limit) { String sql = originalSql + " LIMIT " + FIRST_MARK + StringPool.COMMA + SECOND_MARK; return new DialectModel(sql, offset, limit).setConsumerChain(); } }
其sql为:SELECT id,last_name,email,gender,age FROM tbl_employee LIMIT ?,?
于是,通过拦截器修改了要执行的sql语句,从而实现了分页
执行分析插件SqlExplainInterceptor
SQL执行分析拦截器,只支持MySQL5.6.3以上版本
该插件的作用是分析DELETE UPDATE语句,防止小白或者恶意进行DELETE UPDATE全表操作
只建议在开发环境中使用,不建议在生产环境使用
之前的版本是这样做的:
在插件的底层通过SQL语句分析命令:Explain 分析当前的SQL语句,根据结果集中的Extra列来断定当前是否全表操作
现在的版本:更新/删除的时候,判断update/delete子句是否有where子句,如果没有where子句,那么就prohibit掉;否则,如通过UpdateWrapper构造出这样的sql:DELETE FROM tbl_employee WHERE id <> 0,还是会全表删除掉的
public abstract class AbstractSqlParserHandler类中
private List<ISqlParser> sqlParserList; private ISqlParserFilter sqlParserFilter;
如何给AbstractSqlParserHandler中的sqlParserList赋值呢?
在applicationContext.xml中
<!--SQL执行分析插件--> <bean name="sqlExplainInterceptor" class="com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor"> <property name="sqlParserList" ref="blockAttackSqlParser" /> </bean>
效果:
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of full table deletion
性能分析插件PerformanceInterceptor
// 计算执行 SQL 耗时 long start = SystemClock.now(); Object result = invocation.proceed(); long timing = SystemClock.now() - start;
如果超过maxTime,会提示:
### Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: The SQL execution time is too large, please optimize !
乐观锁插件OptimisticLockerInterceptor
乐观锁的实现原理:
取出记录时,获取当前version 2
更新时,带上这个version 2
执行更新时,set version = yourVersion+1 where version = yourVersion
如果version不对,就更新失败
@Version 用于注解实体字段,必须要有。
表中也要有这个字段
执行的sql: