当前位置: 首页 > news >正文

网站开发 安全验证邢台123生活信息网

网站开发 安全验证,邢台123生活信息网,医院网站建设招标说明,广州花都区网站建设【工具】 MyBatis Plus的SQL拦截器自动翻译替换"?"符号为真实数值 使用MyBatis的配置如下所示: mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl调用接口,sql日志打印如下: 参数和sql语句不…

【工具】 MyBatis Plus的SQL拦截器自动翻译替换"?"符号为真实数值

使用MyBatis的配置如下所示:

mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

调用接口,sql日志打印如下:

image-20240531164616237

参数和sql语句不在同一行显示,需要自己代入思考,不够直观。

实现"?"的自动翻译,步骤如下:

1)编写sql语句拦截器:

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class,Object.class}),@Signature(type = Executor.class, method = "query", args = {MappedStatement.class,Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})})
public class SqlStatementInterceptor implements Interceptor {public static final Logger log = LoggerFactory.getLogger("sys-sql");@Overridepublic Object intercept(Invocation invocation) throws Throwable {long startTime = System.currentTimeMillis();try {return invocation.proceed();} finally {long timeConsuming = System.currentTimeMillis() - startTime;log.info("执行SQL:{}ms", timeConsuming);if (timeConsuming > 999 && timeConsuming < 5000) {log.info("执行SQL大于1s:{}ms", timeConsuming);} else if (timeConsuming >= 5000 && timeConsuming < 10000) {log.info("执行SQL大于5s:{}ms", timeConsuming);} else if (timeConsuming >= 10000) {log.info("执行SQL大于10s:{}ms", timeConsuming);}}}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}
}

2)编写MyBatisPlus日志拦截器:

import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
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.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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;import java.sql.SQLException;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;public class MybatisPlusAllSqlLog implements InnerInterceptor {public static final Logger log = LoggerFactory.getLogger("sys-sql");@Overridepublic void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {logInfo(boundSql, ms, parameter);}@Overridepublic void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException {BoundSql boundSql = ms.getBoundSql(parameter);logInfo(boundSql, ms, parameter);}private static void logInfo(BoundSql boundSql, MappedStatement ms, Object parameter) {try {log.info("parameter = " + parameter);// 获取到节点的id,即sql语句的idString sqlId = ms.getId();log.info("sqlId = " + sqlId);// 获取节点的配置Configuration configuration = ms.getConfiguration();// 获取到最终的sql语句String sql = getSql(configuration, boundSql, sqlId);log.info("完整的sql:{}", sql);} catch (Exception e) {log.error("异常:{}", e.getLocalizedMessage(), e);}}// 封装了一下sql语句,使得结果返回完整xml路径下的sql语句节点id + sql语句public static String getSql(Configuration configuration, BoundSql boundSql, String sqlId) {return sqlId + ":" + showSql(configuration, boundSql);}// 进行?的替换public static String showSql(Configuration configuration, BoundSql boundSql) {// 获取参数Object parameterObject = boundSql.getParameterObject();List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();// sql语句中多个空格都用一个空格代替String sql = boundSql.getSql().replaceAll("[\\s]+", " ");if (!CollectionUtils.isEmpty(parameterMappings) && parameterObject != null) {// 获取类型处理器注册器,类型处理器的功能是进行java类型和数据库类型的转换TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();// 如果根据parameterObject.getClass()可以找到对应的类型,则替换if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {sql = sql.replaceFirst("\\?",Matcher.quoteReplacement(getParameterValue(parameterObject)));} else {// MetaObject主要是封装了originalObject对象,提供了get和set的方法用于获取和设置originalObject的属性值,主要支持对JavaBean、Collection、Map三种类型对象的操作MetaObject metaObject = configuration.newMetaObject(parameterObject);for (ParameterMapping parameterMapping : parameterMappings) {String propertyName = parameterMapping.getProperty();if (metaObject.hasGetter(propertyName)) {Object obj = metaObject.getValue(propertyName);sql = sql.replaceFirst("\\?",Matcher.quoteReplacement(getParameterValue(obj)));} else if (boundSql.hasAdditionalParameter(propertyName)) {// 该分支是动态sqlObject obj = boundSql.getAdditionalParameter(propertyName);sql = sql.replaceFirst("\\?",Matcher.quoteReplacement(getParameterValue(obj)));} else {// 打印出缺失,提醒该参数缺失并防止错位sql = sql.replaceFirst("\\?", "缺失");}}}}return sql;}// 如果参数是String,则添加单引号, 如果是日期,则转换为时间格式器并加单引号; 对参数是null和不是null的情况作了处理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;}}

3)编写MyBatisPlus配置:

@Configuration
public class MybatisConfiguration {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new MybatisPlusAllSqlLog());return mybatisPlusInterceptor;}}

测试:

调用接口,sql日志如下所示:

image-20240531165929624

http://www.yayakq.cn/news/878043/

相关文章:

  • 北京建站公司方管结构图集久久建筑网
  • 网站二维码收费怎么做社交网站的建设现状
  • 如何制作营销网站许昌 网站开发
  • 长沙 建站优化服饰视频网站建设
  • 景区旅游门户网站建设方案电商平台站内推广有哪些
  • vs2010做网站教程做外贸卖小商品是哪个网站
  • 如何利用路由建设网站备用网站域名
  • 厦门网站建设68网站策划怎么做
  • 全国做临期进口食品的网站网站的当前位置导航如何做
  • 网站服务器 502副业做网站程序
  • 网站建设实训经验总结vs做网站如何发布
  • 网站建设公司大全手机wap网站建站系统
  • 内蒙古网站开发网站建设论文的结论
  • 网站建设教程集体苏州久远网络福建 建设网站
  • 网站首页怎么做全屏swf手机网站怎样做的
  • 建筑模型网站有哪些凡科建站快车官网
  • 上海临平路网站建设怎样申请免费的网站空间
  • 做网页的网站叫什么红色扁平化网站
  • 门户网站开发公司威海屋顶防水价格威海做防水网站
  • 随州学做网站的学校滴滴推广联盟
  • 网站权重查询接口做国际网站需要多少钱
  • 为什么要进行电子商务网站规划网站怎么做才会有收录
  • 专利减缓在哪个网站上做做网站注意设么
  • 太原网站优化常识手机app开发工资高吗
  • 某网站seo诊断分析wordpress 主题预览
  • 化妆培训学校网站源码 下载中国最大的网站
  • 呼伦贝尔做网站的公司网站维护后期费用
  • 德阳建设银行招聘网站滕州网站优化
  • 网站建设管理 优帮云wordpress 屏蔽中文浏览器
  • 游戏交易网站开发手机怎么开发软件app