<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>踩坑日记归档 - 枫阿雨&#039;s blog</title>
	<atom:link href="https://www.crazyfay.com/tag/%E8%B8%A9%E5%9D%91%E6%97%A5%E8%AE%B0/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.crazyfay.com/tag/踩坑日记/</link>
	<description>CrazyFay</description>
	<lastBuildDate>Tue, 04 Apr 2023 03:07:30 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.2</generator>

<image>
	<url>https://www.crazyfay.com/wp-content/uploads/2023/04/cropped-DockerGopher-32x32.png</url>
	<title>踩坑日记归档 - 枫阿雨&#039;s blog</title>
	<link>https://www.crazyfay.com/tag/踩坑日记/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>记一次gorm.ErrRecordNotFound踩坑记录</title>
		<link>https://www.crazyfay.com/2022/08/20/%e8%ae%b0%e4%b8%80%e6%ac%a1gorm-errrecordnotfound%e8%b8%a9%e5%9d%91%e8%ae%b0%e5%bd%95/</link>
					<comments>https://www.crazyfay.com/2022/08/20/%e8%ae%b0%e4%b8%80%e6%ac%a1gorm-errrecordnotfound%e8%b8%a9%e5%9d%91%e8%ae%b0%e5%bd%95/#respond</comments>
		
		<dc:creator><![CDATA[crazyfay]]></dc:creator>
		<pubDate>Sat, 20 Aug 2022 03:05:31 +0000</pubDate>
				<category><![CDATA[实践经验]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[踩坑日记]]></category>
		<guid isPermaLink="false">http://net.crazyfay.xyz/?p=164</guid>

					<description><![CDATA[<p>在某个项目中，有个数据验证的业务，即在数据库中查询数据是否存在，若数据已存在则返回错误并给前端提示。稍想了一下 [&#8230;]</p>
<p><a rel="nofollow" href="https://www.crazyfay.com/2022/08/20/%e8%ae%b0%e4%b8%80%e6%ac%a1gorm-errrecordnotfound%e8%b8%a9%e5%9d%91%e8%ae%b0%e5%bd%95/">记一次gorm.ErrRecordNotFound踩坑记录</a>最先出现在<a rel="nofollow" href="https://www.crazyfay.com">枫阿雨&#039;s blog</a>。</p>
]]></description>
										<content:encoded><![CDATA[<p>在某个项目中，有个数据验证的业务，即在数据库中查询数据是否存在，若数据已存在则返回错误并给前端提示。稍想了一下就能写出如下代码<code>Func01</code></p>
<p><code>Func01</code></p>
<pre><code class="language-go">func (t *ServiceInfo) Find(c *gin.Context, tx *gorm.DB, search *ServiceInfo) (*ServiceInfo, error) {
    out := &amp;ServiceInfo{}
    err := tx.WithContext(c).Where(search).Find(out).Error
    if err != nil {
        return nil, err
    }
    return out, nil
}</code></pre>
<p>gorm在之前的版本中，因为gorm的查询是链式的语句，所以中间出现的错误会存入到Error的参数集中处理。而且当没有查询到数据的时候也会得到错误ErrRecordNotFound。所以此代码就把错误同一处理，当controller中没有收到任何错误时，可以说明数据库中查询到了此数据，即校验重复了。</p>
<p>但是经过测试后发现无论如何err都是nil，且RowsAffected也明明为0。在网上也没有直接搜到这个坑的blog，于是我去翻了gorm最新的文档，发现了此段话！</p>
<p><img decoding="async" src="https://img-1307890592.cos.ap-chengdu.myqcloud.com/typroa/image-20220725104008262.png" alt="image-20220725104008262" /></p>
<p>即说明Find()方法不会再得到ErrRecordNotFound的错误</p>
<p>于是我采用了First()进行了测试</p>
<p><code>Func02</code></p>
<pre><code class="language-go">func (t *ServiceInfo) Find(c *gin.Context, tx *gorm.DB, search *ServiceInfo) (*ServiceInfo, error) {
    out := &amp;ServiceInfo{}
    resultFind := tx.WithContext(c).Where(search).Find(out)
    resultFirst := tx.WithContext(c).Where(search).First(out)
    log.Print(&quot;Find() Err: &quot;, resultFind.Error, &quot;\tFind Rows Affected: &quot;, resultFind.RowsAffected)
    log.Print(&quot;First() Err: &quot;, resultFirst.Error, &quot;\tFind Rows Affected: &quot;, resultFirst.RowsAffected)
    err := resultFind.Error
    if err != nil {
        return nil, err
    }
    return out, nil
}</code></pre>
<p>得到输出</p>
<pre><code class="language-shell">2022/07/25 10:00:35 Find() Err: &lt;nil&gt;   Find Rows Affected: 0
2022/07/25 10:00:35 First() Err: record not found       Find Rows Affected: 0</code></pre>
<p>很明显，当查询不到结果的时候First()方法会返回ErrRecordNotFound，而Find()方法并不会</p>
<p>因此，若不改变代码原有的逻辑基础上，可以通过手动添加Error的方法来完成数据校验的工作</p>
<p><code>Func03</code></p>
<pre><code class="language-go">func (t *ServiceInfo) Find(c *gin.Context, tx *gorm.DB, search *ServiceInfo) (*ServiceInfo, error) {
    out := &amp;ServiceInfo{}
    resultFind := tx.WithContext(c).Where(search).Find(out)
    if resultFind.RowsAffected &lt; 1 {
        err := resultFind.AddError(gorm.ErrRecordNotFound)
        if err != nil {
            return nil, err
        }
    }
    err := resultFind.Error
    if err != nil {
        return nil, err
    }
    return out, nil
}</code></pre>
<p>即通过<code>resultFind.RowsAffected &lt; 1</code>来判断是否查询到数据，再通过 <code>resultFind.AddError(gorm.ErrRecordNotFound)</code> 手动添加</p>
<p>ErrRecordNotFound错误，藉此来完成在旧版本中存在的功能。</p>
<blockquote>
<p>PS：我个人并不是很理解为什么要取消Find()方法中的这个错误提示</p>
<p>此实现方式仅供参考，如有更漂亮的方法希望不吝赐教</p>
</blockquote>
<p><a rel="nofollow" href="https://www.crazyfay.com/2022/08/20/%e8%ae%b0%e4%b8%80%e6%ac%a1gorm-errrecordnotfound%e8%b8%a9%e5%9d%91%e8%ae%b0%e5%bd%95/">记一次gorm.ErrRecordNotFound踩坑记录</a>最先出现在<a rel="nofollow" href="https://www.crazyfay.com">枫阿雨&#039;s blog</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.crazyfay.com/2022/08/20/%e8%ae%b0%e4%b8%80%e6%ac%a1gorm-errrecordnotfound%e8%b8%a9%e5%9d%91%e8%ae%b0%e5%bd%95/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
