网站分页样式,shopify如何做瀑布流网站,成都手机网站制作,网站建设文章一 mybatis的拦截器
1.1 拦截器介绍
拦截器是一种基于 AOP#xff08;面向切面编程#xff09;的技术#xff0c;它可以在目标对象的方法执行前后插入自定义的逻辑。
1.2 语法介绍
1.注解Intercepts
Intercepts({Signature(type StatementHandler.class, method “…一 mybatis的拦截器
1.1 拦截器介绍
拦截器是一种基于 AOP面向切面编程的技术它可以在目标对象的方法执行前后插入自定义的逻辑。
1.2 语法介绍
1.注解Intercepts
Intercepts({Signature(type StatementHandler.class, method “prepare”, args {Connection.class, Integer.class})})表示在 SQL 执行之前进行拦截处理。
Intercepts 的作用声明这是一个拦截器。
属性Signature注解
Signature要拦截的具体方法
属性: type-拦截接口四种类型
method-拦截的方法updateinsertselect
args-重载时根据参数列表确定要拦截的方法。
2.介绍
Executor拦截执行器的方法例如 update、query、commit、rollback 等。可以用来实现缓存、事务、分页等功能。ParameterHandler拦截参数处理器的方法例如 setParameters 等。可以用来转换或加密参数等功能。ResultSetHandler拦截结果集处理器的方法例如 handleResultSets、handleOutputParameters 等。可以用来转换或过滤结果集等功能。StatementHandler拦截语句处理器的方法例如 prepare、parameterize、batch、update、query 等。可以用来修改 SQL 语句、添加参数、记录日志等功能。
1.3 API接口
1.intercept主要是写我们具体业务逻辑比如针对增删改sql语句添加更新日期。
2.plugin生成代理对象
3.setProperties设置拦截器属性 二 实现案例
2.1 结构 2.2 代码
package com.ljf.springboot.mybaits.demos.utils;import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.stereotype.Component;import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Properties;/*** 1. 打印mysql完整的执行语句* 2. 打印mysql语句执行时间* 这里我们拦截Executor里面的query和update方法*/
Component
Intercepts({Signature(method query,type Executor.class,args {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),Signature(type Executor.class,method update,args {MappedStatement.class, Object.class})
})
public class LogInterceptor implements Interceptor {/*** 是否显示语句的执行时间*/public static final String PROPERTIES_KEY_ENABLE_EXECUTOR_TIME enableExecutorTIme;public static final String ENABLE_EXECUTOR_TIME 0; // 显示private boolean enableExecutorTime false;Overridepublic Object intercept(Invocation invocation) throws Throwable {System.out.println(dddddd);// 获取执行方法的MappedStatement参数,不管是Executor的query方法还是update方法第一个参数都是MappedStatementMappedStatement mappedStatement (MappedStatement) invocation.getArgs()[0];Object parameter null;if (invocation.getArgs().length 1) {parameter invocation.getArgs()[1];}String sqlId mappedStatement.getId();BoundSql boundSql mappedStatement.getBoundSql(parameter);Configuration configuration mappedStatement.getConfiguration();long sqlStartTime System.currentTimeMillis();Object re invocation.proceed();long sqlEndTime System.currentTimeMillis();// 打印mysql执行语句String sql getSql(configuration, boundSql, sqlId);System.out.println(sql);// 打印mysql执行时间if (enableExecutorTime) {String sqlTimeLog sqlId 方法对应sql执行时间: (sqlEndTime - sqlStartTime) ms;System.out.println(sqlTimeLog);}return re;}/*** 通过该方法决定要返回的对象是目标对象还是对应的代理* 不要想的太复杂一般就两种情况* p* 1. return target; 直接返回目标对象相当于当前Interceptor没起作用不会调用上面的intercept()方法* 2. return Plugin.wrap(target, this); 返回代理对象会调用上面的intercept()方法** param target 目标对象* return 目标对象或者代理对象*/Overridepublic Object plugin(Object target) {System.out.println(dssssssssss);return Plugin.wrap(target, this);}/*** 用于获取在Configuration初始化当前的Interceptor时时候设置的一些参数** param properties Properties参数*/Overridepublic void setProperties(Properties properties) {if (properties ! null) {String executorTImeValue properties.getProperty(PROPERTIES_KEY_ENABLE_EXECUTOR_TIME);if (executorTImeValue ! null) {enableExecutorTime executorTImeValue.equals(ENABLE_EXECUTOR_TIME);}}}private static String getSql(Configuration configuration, BoundSql boundSql, String sqlId) {return sqlId 方法对应sql执行语句: assembleSql(configuration, boundSql);}/*** 转义正则特殊字符 $()*.[]?\^{}* \\需要第一个替换否则replace方法替换时会有逻辑bug*/private static String makeQueryStringAllRegExp(String str) {if (str ! null !str.equals()) {return str.replace(\\, \\\\).replace(*, \\*).replace(, \\).replace(|, \\|).replace({, \\{).replace(}, \\}).replace((, \\().replace(), \\)).replace(^, \\^).replace($, \\$).replace([, \\[).replace(], \\]).replace(?, \\?).replace(,, \\,).replace(., \\.).replace(, \\);}return str;}/*** 获取参数对应的string值** param obj 参数对应的值* return string*/private static String getParameterValue(Object obj) {String value;if (obj instanceof String) {value obj.toString() ;} else if (obj instanceof Date) {DateFormat formatter DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);value formatter.format(new Date()) ;} else {if (obj ! null) {value obj.toString();} else {value ;}}// 对特殊字符进行转义方便之后处理替换return value ! null ? makeQueryStringAllRegExp(value) : value;}/*** 组装完整的sql语句 -- 把对应的参数都代入到sql语句里面** param configuration Configuration* param boundSql BoundSql* return sql完整语句*/private static String assembleSql(Configuration configuration, BoundSql boundSql) {// 获取mapper里面方法上的参数Object sqlParameter boundSql.getParameterObject();// sql语句里面需要的参数 -- 真实需要用到的参数 因为sqlParameter里面的每个参数不一定都会用到ListParameterMapping parameterMappings boundSql.getParameterMappings();// sql原始语句(?还没有替换成我们具体的参数)String sql boundSql.getSql().replaceAll([\\s], );if (parameterMappings.size() 0 sqlParameter ! null) {// sql语句里面的?替换成真实的参数TypeHandlerRegistry typeHandlerRegistry configuration.getTypeHandlerRegistry();if (typeHandlerRegistry.hasTypeHandler(sqlParameter.getClass())) {sql sql.replaceFirst(\\?, getParameterValue(sqlParameter));} else {MetaObject metaObject configuration.newMetaObject(sqlParameter);for (ParameterMapping parameterMapping : parameterMappings) {// 一个一个把对应的值替换进去 按顺序把?替换成对应的值String propertyName parameterMapping.getProperty();if (metaObject.hasGetter(propertyName)) {Object obj metaObject.getValue(propertyName);sql sql.replaceFirst(\\?, getParameterValue(obj));} else if (boundSql.hasAdditionalParameter(propertyName)) {Object obj boundSql.getAdditionalParameter(propertyName);sql sql.replaceFirst(\\?, getParameterValue(obj));}}}}return sql;}
}2.3 验证效果
1.请求 2.日志结果