最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何獲取MyBatis Plus執(zhí)行的完整的SQL語句

 更新時(shí)間:2024年07月17日 10:50:15   作者:梁云亮  
這篇文章主要介紹了如何獲取MyBatis Plus執(zhí)行的完整的SQL語句問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

注意:本示例介紹的方法僅支持MyBatis Plus

原理

自定義插件,將SQL語句中的?替換成具體的參數(shù)值。

實(shí)現(xiàn)

自定義插件

import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.tiku.utils.LogUtil;
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 java.sql.SQLException;
import java.text.DateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;

public class MyBatisPlusSqlLogInterceptor implements InnerInterceptor {
    private static boolean printSQL = true;

    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        if (printSQL) {
            MappedStatement mappedStatement = ms;
            String sqlId = mappedStatement.getId();
            Configuration configuration = mappedStatement.getConfiguration();
            String sql = getSql(configuration, boundSql, sqlId);

            final String ip = RequestUtil.getIp();
            final String requestType = RequestUtil.getMethod();
            final String url = RequestUtil.getRequestUrl();
            final String parameters = RequestUtil.getParameters();

            String userAgent = RequestUtil.getUserAgent();
            UserAgent agent = UserAgent.parseUserAgentString(userAgent);
            final String browser = agent.getBrowser().getName();
            final String os = agent.getOperatingSystem().getName();

            LogUtil.println("用戶訪問了:{},瀏覽器是:{},操作系統(tǒng)是:{},IP是:{},請(qǐng)求方式是:{},請(qǐng)求參數(shù)是:{},SQL語句是:{}", url, browser, os, ip, requestType, parameters, sql);
        }
    }

    @Override
    public void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException {
        if (printSQL) {
            MappedStatement mappedStatement = ms;
            String sqlId = mappedStatement.getId();
            Configuration configuration = mappedStatement.getConfiguration();
            BoundSql boundSql = mappedStatement.getBoundSql(parameter);
            String sql = getSql(configuration, boundSql, sqlId);

            final String ip = RequestUtil.getIp();
            final String requestType = RequestUtil.getMethod();
            final String url = RequestUtil.getRequestUrl();
            final String parameters = RequestUtil.getParameters();

            String userAgent = RequestUtil.getUserAgent();
            UserAgent agent = UserAgent.parseUserAgentString(userAgent);
            final String browser = agent.getBrowser().getName();
            final String os = agent.getOperatingSystem().getName();

            LogUtil.println("用戶訪問了:{},瀏覽器是:{},操作系統(tǒng)是:{},IP是:{},請(qǐng)求方式是:{},請(qǐng)求參數(shù)是:{},SQL語句是:{}", url, browser, os, ip, requestType, parameters, sql);
        }
    }

    private String getSql(Configuration configuration, BoundSql boundSql, String sqlId) {
        try {
            String sql = showSql(configuration, boundSql);
            StringBuilder str = new StringBuilder(100);
            str.append(sqlId);
            str.append(" ==> ");
            str.append(sql);
            str.append(";");
            return str.toString();
        } catch (Error e) {
            LogUtil.error("解析 sql 異常", e);
        }
        return "";
    }

    private String showSql(Configuration configuration, BoundSql boundSql) {
        Object parameterObject = boundSql.getParameterObject();
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
        if (parameterMappings != null && parameterMappings.size() > 0 && parameterObject != null) {
            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
            if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(parameterObject)));
            } else {
                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)) {
                        Object obj = boundSql.getAdditionalParameter(propertyName);
                        sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj)));
                    }
                }
            }
        }
        return sql;
    }

    private String getParameterValue(Object obj) {
        String value = null;
        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(obj) + "'";
        } else if (obj instanceof LocalDate) {
            value = "'" + ((LocalDate) obj).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "'";
        } else if (obj instanceof LocalDateTime) {
            value = "'" + ((LocalDateTime) obj).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "'";

        } else {
            if (obj != null) {
                value = obj.toString();
            } else {
                value = "";
            }
        }
        return value;
    }
}

上面代碼用到的兩個(gè)工具類:

  • RequestUtil.java
import com.tiku.enums.ResultEnum;
import com.tiku.ex.GlobalException;
import jakarta.servlet.http.HttpServletRequest;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author hc
 */
public class RequestUtil {
    /**
     * 私有構(gòu)造方法,防止實(shí)例化
     */
    private RequestUtil() {

    }

    /**
     * 獲取所有的請(qǐng)求參數(shù)及值
     *
     * @return eg:pageNum=3&pageSize=5&state=0
     */
    public static String getParameters() {
        HttpServletRequest request = SpringContextUtil.getRequest();
        if (null == request) {
            return null;
        }
        Enumeration<String> paraNames = request.getParameterNames();
        if (paraNames == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        while (paraNames.hasMoreElements()) {
            String paraName = paraNames.nextElement();
            sb.append("&").append(paraName).append("=").append(request.getParameter(paraName));
        }
        return sb.toString();
    }

    public static Map<String, String> getParameterMap(HttpServletRequest request) {
        // 參數(shù)Map
        Map<String, String[]> properties = request.getParameterMap();
        // 返回值Map
        Map<String, String> returnMap = new HashMap<>(16);
        Iterator<Map.Entry<String, String[]>> entries = properties.entrySet().iterator();
        Map.Entry<String, String[]> entry;
        String name;
        String value = "";
        while (entries.hasNext()) {
            entry = entries.next();
            name = entry.getKey();
            Object valueObj = entry.getValue();
            if (null == valueObj) {
                value = "";
            } else {
                String[] values = (String[]) valueObj;
                for (String value1 : values) {
                    value = value1 + ",";
                }
                value = value.substring(0, value.length() - 1);
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }

    /**
     * 獲取用戶所有的請(qǐng)求參數(shù),以Map的形式返回
     *
     * @return
     */
    public static Map<String, String[]> getParametersMap() {
        HttpServletRequest request = SpringContextUtil.getRequest();
        if (null == request) {
            return new HashMap<>();
        }
        return request.getParameterMap();
    }

    /**
     * 獲取請(qǐng)求頭中指定名稱的值
     *
     * @param name
     * @return
     */
    public static String getHeader(String name) {
        HttpServletRequest request = SpringContextUtil.getRequest();
        if (null == request) {
            return null;
        }
        return request.getHeader(name);
    }

    public static String getReferer() {
        return getHeader("Referer");
    }

    /**
     * 獲取用戶代理對(duì)象
     *
     * @return
     */
    public static String getUserAgent() {
        return getHeader("User-Agent");
    }

    /**
     * 獲取請(qǐng)求用戶的IP地址
     *
     * @return
     */
    public static String getIp() {
        HttpServletRequest request = SpringContextUtil.getRequest();
        if (null == request) {
            return null;
        }
        return IPUtil.getIpAddr(request);
    }

    /**
     * 獲取用戶請(qǐng)求的Controller的路徑
     *
     * @return 比如:http://localhost/list
     */
    public static String getRequestUrl() {
        HttpServletRequest request = SpringContextUtil.getRequest();
        if (null == request) {
            return null;
        }
        return request.getRequestURL().toString();
    }

    /**
     * 獲取URI
     *
     * @return
     */
    public static String getRequestUri() {
        HttpServletRequest request = SpringContextUtil.getRequest();
        if (null == request) {
            return null;
        }
        return request.getRequestURI();
    }

    /**
     * 獲取用戶請(qǐng)求的方式,值有: POST GET 3 PUT DELETE
     *
     * @return
     */
    public static String getMethod() {
        HttpServletRequest request = SpringContextUtil.getRequest();
        if (null == request) {
            return null;
        }
        return request.getMethod();
    }

    /**
     * 判斷用戶的請(qǐng)求是否是AJAX請(qǐng)求
     *
     * @param request
     * @return
     */
    public static boolean isAjax(HttpServletRequest request) {
        if (null == request) {
            request = SpringContextUtil.getRequest();
        }
        if (null == request) {
            return false;
        }
        // 解析原錯(cuò)誤信息,封裝后返回,此處返回非法的字段名稱,原始值,錯(cuò)誤信息
        // 使用HttpServletRequest中的header檢測(cè)請(qǐng)求是否為ajax, 如果是ajax則返回json, 如果為非ajax則返回view(即ModelAndView)
        String contentTypeHeader = request.getHeader("Content-Type");
        String acceptHeader = request.getHeader("Accept");
        String xRequestedWith = request.getHeader("X-Requested-With");
        return (contentTypeHeader != null && contentTypeHeader.contains("application/json"))
                || (acceptHeader != null && acceptHeader.contains("application/json"))
                || "XMLHttpRequest".equalsIgnoreCase(xRequestedWith);
    }

    /**
     * 從HttpServletReqeust對(duì)象中獲取key對(duì)應(yīng)的值 先從Reqeust Parameter中獲取,如果沒有再從Header中獲取
     *
     * @param key
     * @return
     */
    public static String getValueFromRequest(String key) {
        HttpServletRequest request = SpringContextUtil.getRequest();
        return getValueFromRequest(request, key);
    }

    /**
     * 從HttpServletReqeust對(duì)象中獲取key對(duì)應(yīng)的值 先從Reqeust Parameter中獲取,如果沒有再從Header中獲取
     *
     * @param request
     * @param key
     * @return
     */
    public static String getValueFromRequest(HttpServletRequest request, String key) {
        String token = request.getParameter(key);
        // 從header中獲取值
        if (token == null) {
            token = request.getHeader(key);
        }
        if (token == null) {
            throw new GlobalException(ResultEnum.TOKEN_INVALID);
        }
        return token;
    }
}
  • UserAgent

該工具類是第三方j(luò)ar包中定義的:UserAgentUtils-1.21.jar

注冊(cè)插件

@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        interceptor.addInnerInterceptor(new MyBatisPlusSqlLogInterceptor());
        return interceptor;
    }

}

這樣在執(zhí)行CRUD操作數(shù)據(jù)時(shí),就會(huì)在控制臺(tái)中輸出相應(yīng)的完整的SQL語句

比如:

2024-05-20 07:46:22.365 [INFO ] [] 6868 --  SqlLogInterceptor.beforeQuery() Line: 48 Line:100 :  用戶訪問了:http://127.0.0.1:8081/tiku/user/v1/login,瀏覽器是:Chrome 12,操作系統(tǒng)是:Windows 10,IP是:127.0.0.1,請(qǐng)求方式是:POST,請(qǐng)求參數(shù)是:,SQL語句是:com.tiku.mapper.UserDetailsMapper.selectById ==> SELECT id,num,nickname,`name`,avatar,gender,birth,email,tel,qq,wechat,credit,interest,country_id,addr,verify_time,login_time,login_ip,login_addr,creator_id,updater_id,info,priority,create_time,update_time FROM sys_user_details WHERE id=1;

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用Spring Security OAuth2實(shí)現(xiàn)單點(diǎn)登錄

    使用Spring Security OAuth2實(shí)現(xiàn)單點(diǎn)登錄

    在本教程中,我們將討論如何使用Spring Security OAuth和Spring Boot實(shí)現(xiàn)SSO - 單點(diǎn)登錄。感興趣的朋友跟隨小編一起看看吧
    2019-06-06
  • IDEA中將SpringBoot項(xiàng)目提交到git倉庫的方法步驟

    IDEA中將SpringBoot項(xiàng)目提交到git倉庫的方法步驟

    本文主要介紹了IDEA中將SpringBoot項(xiàng)目提交到git倉庫的方法步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • JeecgBoot頁面Online報(bào)表配置過程(動(dòng)態(tài))

    JeecgBoot頁面Online報(bào)表配置過程(動(dòng)態(tài))

    文章介紹了如何根據(jù)登錄者角色信息動(dòng)態(tài)配置報(bào)表,并詳細(xì)說明了Online報(bào)表的配置步驟,包括數(shù)據(jù)源選擇、字段顯示、查詢條件設(shè)置等,同時(shí),文章還涉及了頁面代碼部分,包括依賴引入、用戶信息獲取、參數(shù)配置和form表單配置等
    2026-01-01
  • springboot @ConditionalOnMissingBean注解的作用詳解

    springboot @ConditionalOnMissingBean注解的作用詳解

    這篇文章主要介紹了springboot @ConditionalOnMissingBean注解的作用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • uploadify上傳及后臺(tái)文件合法性驗(yàn)證的代碼解析

    uploadify上傳及后臺(tái)文件合法性驗(yàn)證的代碼解析

    這篇文章主要介紹了uploadify上傳及后臺(tái)文件合法性驗(yàn)證的代碼解析,整段代碼分為后臺(tái)上傳方法,文件合法性驗(yàn)證類,前端上傳js,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • 基于SpringBoot + Android實(shí)現(xiàn)登錄功能

    基于SpringBoot + Android實(shí)現(xiàn)登錄功能

    在移動(dòng)互聯(lián)網(wǎng)的今天,許多應(yīng)用需要通過移動(dòng)端實(shí)現(xiàn)與服務(wù)器的交互功能,其中登錄是最常見且基礎(chǔ)的一種功能,本篇博客將詳細(xì)介紹如何使用 Spring Boot 和 Android 實(shí)現(xiàn)一個(gè)完整的登錄功能,需要的朋友可以參考下
    2024-11-11
  • IDEA?mybatis?Mapper.xml報(bào)紅的最新解決辦法

    IDEA?mybatis?Mapper.xml報(bào)紅的最新解決辦法

    這篇文章主要介紹了IDEA?mybatis?Mapper.xml報(bào)紅的解決辦法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • 詳解Java設(shè)計(jì)模式編程中的里氏替換原則

    詳解Java設(shè)計(jì)模式編程中的里氏替換原則

    這篇文章主要介紹了Java設(shè)計(jì)模式編程中的里氏替換原則,有這個(gè)名字是因?yàn)檫@是由麻省理工學(xué)院的一位姓里的女士Barbara Liskov提出來的(嗯...),需要的朋友可以參考下
    2016-02-02
  • Java Random 隨機(jī)數(shù)的用法小結(jié)

    Java Random 隨機(jī)數(shù)的用法小結(jié)

    本文主要介紹了Java Random隨機(jī)數(shù)的用法小結(jié),Random類功能全面,支持生成整數(shù)、浮點(diǎn)數(shù)、布爾值及實(shí)現(xiàn)洗牌等高級(jí)操作,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • 深入談?wù)刯ava的枚舉(enum)類型

    深入談?wù)刯ava的枚舉(enum)類型

    這篇文章介紹的是java中的枚舉類型,對(duì)于枚舉類型的相關(guān)知識(shí),我們也介紹過不少方面的內(nèi)容。希望本文能夠給你帶來幫助,下面來一起看看,有需要的可以參考借鑒。
    2016-09-09

最新評(píng)論

庆云县| 垦利县| 黄山市| 阿尔山市| 崇阳县| 舒兰市| 普兰店市| 日喀则市| 青神县| 当雄县| 涞水县| 岳西县| 柳州市| 连州市| 五寨县| 前郭尔| 通山县| 玉林市| 金山区| 长治市| 米林县| 巩留县| 于都县| 林周县| 安多县| 大兴区| 福鼎市| 漠河县| 呼伦贝尔市| 万安县| 庆安县| 修文县| 元谋县| 德格县| 贵德县| 手游| 达拉特旗| 扎兰屯市| 东阳市| 华安县| 祁东县|