mybatis插入mysql字段默認值不生效的問題


在項目中使用mybatis做為持久層框架,mysql數據庫。項目上線前,DBA要求我們將每張數據庫表中的字段都設置默認值和not null。之前項目中有一些insert語句是將表中所有字段都列出來,然后把它做為一個通用的插入語句來使用。舉個簡單的例子:假如一張數據庫表blog中有如下幾個字段:id,title,content,author,除id外,每個字段都設置了默認值Empty String(空字符串),寫的一個insert語句是這樣的: 

<insert id="addOneBlog" parameterType="main.Blog">  
    insert into blog(title,author,content)  
    values(#{title},#{author},#{content})  
</insert>  

原以為有這么一個insert語句就萬事大吉了,我們以為,以后做插入操作的時候,無論有多少個字段,都使用這一個insert語句,如果字段沒有值,就會被賦值為mysql字段的默認值。。。 

    但事實證明,根本不是這樣的。 

    當我們只給title字段賦值,然后執行一個insert語句時,mybatis馬上報出這樣的異常: 

  1. Caused by: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Column 'content' cannot be null  

    顯然,所有字段規定了not null,看來按照這種insert的方法,未賦值的字段並沒有賦值為mysql的默認值。 那么如果把數據庫字段的not null限制去掉呢?再次執行剛才的insert操作,這次沒有拋出異常,但查看數據庫后,我們發現,新插入的表記錄中,沒有賦值的字段仍然不是mysql的默認值,而是null值。 

    所以,按照上面所謂的通用insert語句,是無法讓未賦值字段的值變為mysql默認值的。這種insert語句無法做到通用。

1.問題分析

由於我們誤將一個包含所有字段的insert語句做為通用的insert。那么顯而易見,解決此問題的方法是,我們需要針對不同的業務需求,嚴格按照需要插入的字段來寫不同的sql,不需要插入的字段,在insert語句中不能夠出現。

那么sql可以這么寫:

<insert id="addOneBlog" parameterType="main.Blog">  
    insert into blog(author)  
    values (#{author})  
</insert>

這個方法雖然奏效,但在實際項目開發中,為了開發效率的需要,我們仍然希望能夠有一個通用的insert語句,供所有涉及單表插入操作的業務調用。剛才說過,mybatis有一個非常強大的特色功能:動態sql,使用動態sql即可解決此問題。

2.問題解決

1)<sql>、<include>、<trim>標簽簡介

    mybatis的動態sql功能包含了很多實用的標簽:<sql>標簽表示一個sql片段,使用此標簽不僅可以重用很多sql代碼,而且使sql語句更清晰;定義好<sql>標簽后,在調用它的地方使用<include>標簽,即可將定義好的sql片段拼接進來;<trim>標簽可以在標簽體內的sql片段首尾任意添加或覆蓋字符。

於是解決的最終方法如下:

<sql id="blogColumns">  
    <trim suffixOverrides=",">  
        <if test="title != null">title,</if>  
        <if test="author != null">author,</if>  
        <if test="content != null">content</if>  
    </trim>  
</sql>  
  
<sql id="blogValues">  
    <trim suffixOverrides=",">  
        <if test="title != null">#{title},</if>  
        <if test="author != null">#{author},</if>  
        <if test="content != null">#{content}</if>  
    </trim>  
</sql>  
  
<insert id="addOneBlog" parameterType="Blog">  
    insert into blog(<include refid="blogColumns"/>)  
    values (<include refid="blogValues"/>)  
</insert>  

參考:

https://www.cnblogs.com/yuhuameng/p/10703931.html

https://blog.csdn.net/c851204293/article/details/93623200


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM