博客
关于我
Mybatis 中$和#千万不要乱用!
阅读量:663 次
发布时间:2019-03-16

本文共 4469 字,大约阅读时间需要 14 分钟。

MyBatis SQL 参数处理问题及解决方案

近期在代码优化过程中,我遇到了一個值得注意的問題。雖然最終找到了問題的根源,但經過一番摸索,這個問題讓我深刻了解到MyBatis中#$在SQL_paramter化处理中的差異。

我曾錯誤地使用了相同的idoxpurposed Parameter in SQL 単纯地來作为字符串值替代。此舉導致部分數據查找失效,原因在于MyBatis對in()字句中的數據處理方式不同。


啟發

兩條最終的SQL 表示式差距如下:

  • wwlr.LabelId in(${showLabels})
  • wwlr.LabelId in(#{showLabels})
  • 當關注這兩者之差時,我注意到:

    • showLabels 是一個字串型參eter,形如 "4,44,514".
    • Problems lay in how MyBatis處理這兩種表達式。

    Parameters in SQL Statements

    1. #{} Usage

    使用 #{} 的時候,MyBatis會先進行预 compile,将 #{} 替換為 ?,然後通過 PreparedStatement 來進行值的命名。這種方式具有預 compile的安全性,避免了 SQL 注入的可能性。但這也意味着,它會在數據的雙 straně加上 single quotes。例如,傳入 "4,44,514" 將會被轉化為 '4,44,514'

    2. ${} Usage

    使用 ${} 的時候,MyBatis 直接將 SQL 中的 ${} 替換為獎項 的值,且則不進行適當的安全處理。例如,傳入 "4,44,514" 將直接替換到 SQL 语句中,resulting in wwlr.LabelId in(4,44,514)


    啟發點

    雖然我並非第一次面對 #$ 的差異,但只有在實際ιο投 сред源後,我才真正明白了它們之間的實際差別。最初,我,這是 varchar 型的 Parameters passed in, 埋藏在 SQL 语句中統一進行字符串操作。

    然而,從 SQL 控制台的輸出我qq看到,問題出在 in() 列表中數據被加上了雙引号,导致 SQL 引擎無法正確解析這些值授權。

    wwlr.LabelId in('4,44,514')

    這會導致 SQL 搜詢導引無法正常約束,我們無法正確查找對應的數據。


    解決辦法

    面對這個問題,我試圖採取了兩種主要途徑來解決。

    1. 直接將#替換為$

    在掛起,大家們會幫我認為,這是最快速的解決方式。但我實際上並未成功。在當地測試 levyokay,問題不 pierce,部署到公司的 contention docke上,問題依然未獲得固定。Calculator,這份 code似乎真正未改變。

    Hmm,這是不是意味著 $ 在某些情況下失誤了安全性?或者,公司 nive.Dock’eken SQL 引擎的防 SQL 注入功能影響了 $ 的效果?

    了解 myocardium,這時我方針 Percentage other_way.

    2. 使用 foreach 標籤 Assume

    最终,我.chunk楊 thought,應該應該使用 MyBatis 的 foreach 標籤,這樣能夠更安全地構建 In 條件。

    foreach item in #({someList}) {   JUST suficienteense uneagram}

    tahéra,這是Pointer 我們的用法重点在於將原始字串型 parameter 转換為 List

    。這樣既保留了功能,又提高了安全性,因为
    foreach 採用的 Parameters 通常都是虛�เฉพาะ议戶 Calendar 的字段名或表名,不會直接插入到數據中。

    這一步讓我驚訝不已:原本的 SQL 誥.computearteک و模式後,數據與索引完全匹配。


    总结

    回顧這次經驗,我學到了多麼多的事項。尤其是識別 MyBatis 中 #$ 的差異,以及理解 SQL 安全性问题,這是值得深思的一考題。

    雖然最快的解決方法是將 # 替換為 $,但這也意個安全性的隧道背後的 shaer returned,特別是最後� Portolo/Forte的 SSLN防誤�遮盖了此解決方案的有效性。

    因此,最良的解決方案為结合 foreach 標籤來處理 Parameters,通過將原始字串转換為 List}

    MyBatis SQL Parameter Handling Tips

    In the course of optimizing my code, I encountered a significant issue that I needed to address. Although the problem was eventually resolved, it highlighted a crucial understanding of the differences between # and $ in MyBatis when used in SQL statements.


    Understanding the Problem

    When dealing with parameter handling in MyBatis, it's essential to understand the distinctions between # and $:

  • #{} Usage:

    • This syntax is used for parameter substitution in SQL statements.
    • MyBatis processes #{} by replacing them with ? and then using PreparedStatement to set the value.
    • When passing a string value like "4,44,514" using #{} will result in '4,44,514' being inserted into the SQL statement.
  • ${} Usage:

    • This syntax is used for dynamic text replacement in SQL statements.
    • MyBatis directly replaces ${} with the parameter value without adding quotes, resulting in a straightforward string replacement.

  • The Issue

    The problem arose because the parameter values were being enclosed in single quotes due to the use of # syntax. This resulted in incorrect database queries and failed lookups for certain data.


    Solution Approach

    Faced with this issue, I explored different solutions:

    1. Direct Replacement of # with $

    • The quickest fix might be to replace # with $. However, this approach didn't solve the problem in our production environment, leaving me perplexed.

    2. Utilizing foreach Label

    • After some research, I realized that the foreach label in MyBatis could be the appropriate solution for this scenario.

    disclaimer:

    The following solution details are based on my personal understanding and may not reflect the exact code implementation used.


    Solution Using foreach Label

    The foreach label allows for the construction of IN conditions by iterating over a list of values. This approach offers a more secure alternative and avoids common SQL injection vulnerabilities.

    Example of foreach Usage:

    This solution converts the original string parameter into a list of integers, ensuring correct querying without the enclosing quotes issue.


    Conclusion

    Reflecting on this experience, I've learned the importance of understanding SQL parameter handling in MyBatis to ensure optimal and secure database interactions. While # and $ both serve similar purposes, their handling can lead to different results, especially concerning SQL syntax and safety.

    By understanding these differences and employing the foreach label, we can address the issue effectively, ensuring both functionality and security in our applications.

    转载地址:http://stnqz.baihongyu.com/

    你可能感兴趣的文章
    带照片捕捉功能的ESP32-CAM PIR运动检测器
    查看>>
    如何使用SSH远程管理Linux服务器
    查看>>
    降级到旧版本macOS的3种方法
    查看>>
    学习Vue.js2.0(国外视频教程)
    查看>>
    wxPython和PyOpenGL视频
    查看>>
    在30分钟内学习PHP
    查看>>
    Python http.server 服务器
    查看>>
    Python svm 支持向量机
    查看>>
    OpenStack 最小化安装配置(一):物理机网桥配置
    查看>>
    PS快速美白照片
    查看>>
    ubuntu 16.04 镜像下载
    查看>>
    CUDA9.1、cuDNN7在Ubuntu16.04上的安装
    查看>>
    解决“预编译器错误:代码使用了scss/sass语言,但未安装相应编译器,请在菜单工具-插件安装里安装相应编译插件”
    查看>>
    微信小程序云开发:怎么删除云函数?已解决
    查看>>
    解决微信小程序项目导入的问题:app.json 未找到、 __wxConfig is not defined
    查看>>
    非迅捷|PDF、Word、PPT、Excel、图片等互相在线转换:免费、简单、快速、零错误、无套路
    查看>>
    第一次被黑
    查看>>
    PyCharm配置anaconda环境
    查看>>
    SpringBoot与缓存(JSR-107、Spring缓存抽象)
    查看>>
    ERROR 总结
    查看>>