平沙寒漠 發表於 2025-6-23 14:32:10

XML重复查询一条Sql语句的解决方法

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">一、核心问题:从SQL重复执行到日志失效</a></li><li><a href="#_label1">二、根因剖析:DTO断裂引发的级联故障</a></li><li><a href="#_label2">三、解决方案:修复数据链路</a></li><li><a href="#_label3">四、核心经验:Controller层的数据责任</a></li></ul></div><p class="maodian"><a name="_label0"></a></p><h2>一、核心问题:从SQL重复执行到日志失效</h2>
<p>1. 首要现象:XML重复查询失效在排查服务性能时发现:</p>
<div class="jb51code"><pre class="brush:xml;">&lt;!-- MyBatis XML片段 --&gt;
&lt;select id="List" resultMap="Map"&gt;   
SELECT * FROM user WHERE name = #{name}   
&lt;!-- 参数name为null时重复执行相同全表查询 --&gt;
&lt;/select&gt;</pre></div>
<p><strong>症状</strong>:</p>
<ul><li>相同SQL反复执行&nbsp;</li></ul>
<p><strong>2. 调试暴露第二问题:日志输出异常</strong>为定位参数问题,在Controller添加日志:</p>
<div class="jb51code"><pre class="brush:sql;">log.info("请求参数: {}", userListDto); // 打印输入参数</pre></div>
<p>却得到:</p>
<div class="jb51code"><pre class="brush:sql;">请求参数: com.domain.dto.user.UserListDto@599f4346// 对象内存地址</pre></div>
<p><strong>后果</strong>:</p>
<ul><li><strong>无法识别空参数来源</strong>:日志无法展示实际传入的<code>name</code>值</li></ul>
<p class="maodian"><a name="_label1"></a></p><h2>二、根因剖析:DTO断裂引发的级联故障</h2>
<p><strong>关键断层点分析</strong>:</p>
<ul><li><p><strong>DTO层面:</strong></p>
<ul><li><strong>致命缺陷</strong>:缺少<code>@Data</code>导致:
<ul><li><code>toString()</code>未生成 &rarr;&nbsp;<strong>日志无法格式化输出</strong></li><li><code>getter</code>未生成 &rarr;&nbsp;Service层获取<code>name</code>时隐含空指针风险</li></ul></li></ul></li></ul>
<p><strong>文档缺失</strong>:字段无注释导致维护成本增加</p>
<div class="jb51code"><pre class="brush:java;">// UserListDto.java(问题版本)
public class UserListDto {   
private String name;   // 无业务注释   
private Integer pageNum;// 未标识必填
}</pre></div>
<ul><li><p><strong>Controller层面(核心责任方)</strong>:</p>
<ul><li><strong>未校验入参</strong>:直接传递DTO到Service</li><li><strong>未处理日志</strong>:放任对象原始输出</li></ul></li><li><p><strong>Service/DAO层面</strong>:</p>
<ul><li><strong>参数未过滤</strong>:XML直接使用<code>#{name}</code>未判空 &rarr;&nbsp;<strong>重复触发全表扫描</strong></li><li><strong>无缓存机制</strong>:相同查询反复访问数据库</li></ul></li></ul>
<p class="maodian"><a name="_label2"></a></p><h2>三、解决方案:修复数据链路</h2>
<p>1. DTO层修正(止血点)</p>
<div class="jb51code"><pre class="brush:java;">@Data // 核心修复!
生成toString/getter/setter
public class StickerListDto {   
// 增加必要注释    private String name;      
// 贴纸名称(可空)    private Integer pageNum;   
// 页码(必填)}</pre></div>
<p>2. Controller层加固(责任方修复)</p>
<div class="jb51code"><pre class="brush:java;">/**
* 获取列表信息
*
* @param dto 请求参数封装对象
* @return 贴纸列表信息
*/
public TableDataInfo&lt;UserListVo&gt; getUserList(UserListtDto dto) {
    // 关键日志完善 → 打印完整且精准的参数信息
    log.info("请求获取贴纸列表,参数为:Name = {}, PageNum = {}",
             dto.getName(), dto.getPageNum() == null ? "null" : dto.getPageNum());
    // 参数校验增强 → 细化校验逻辑,全面检查参数合法性
    if (dto == null) {
      throw new IllegalArgumentException("请求参数整体为空,无法进行查询");
    }
    if (dto.getPageNum() == null || dto.getPageNum() &lt; 1) {
      throw new IllegalArgumentException("页码参数异常,必须为大于等于1的正整数");
    }
    // 补充对其他关键参数的校验示例(按实际需求调整)
    if (dto.getName() != null &amp;&amp; dto.getName().length() &gt; 50) {
      throw new IllegalArgumentException("名称参数过长,长度不得超过50字符");
    }
    // 正常业务逻辑调用 → 参数已校验,可安全传递给服务层处理
    return productStickerService.getStickerList(dto);
}</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>四、核心经验:Controller层的数据责任</h2>
<ul><li><p><strong>DTO是Controller的盔甲</strong>:</p>
<ul><li>缺失<code>@Data</code>&nbsp;&asymp; 解除防御 &rarr; 导致<strong>日志失效+参数穿透</strong></li><li>无字段注释 &asymp; 丢失地图 &rarr;&nbsp;<strong>增加协作成本</strong></li></ul></li><li><p><strong>日志是指纹采集器</strong>:</p>
<ul><li>打印对象地址 &rarr; 相当于案发现场无痕迹 &rarr;&nbsp;<strong>完全丧失调试能力</strong></li><li>定制化日志格式(如<code>name={}</code>)&rarr; 直接锁定问题参数</li></ul></li><li><p><strong>空参数是系统毒药</strong>:</p>
<ul><li>未在Controller拦截 &rarr;&nbsp;<strong>毒药流入Service层</strong></li><li>DAO层无防御 &rarr;&nbsp;<strong>数据库成为最终受害者</strong></li></ul></li></ul>
<blockquote><p><strong>教训总结</strong>:<br /><code>UserListDto</code>缺失<code>@Data</code>导致:</p>
<ul><li><strong>调试黑洞</strong>:日志输出无意义地址符</li><li><strong>安全缺口</strong>:空值穿透至DAO层</li><li><strong>性能灾难</strong>:XML重复全表查询<br /><strong>修复本质</strong>:<strong>在Controller层建立数据安检站</strong>(DTO规范+参数校验)</li></ul></blockquote>
頁: [1]
查看完整版本: XML重复查询一条Sql语句的解决方法