zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Effective Java 19 Use interfaces only to define types
    Effective Java 18 Prefer interfaces to abstract classes
    Effective Java 17 Design and document for inheritance or else prohibit it
    Effective Java 16 Favor composition over inheritance
    Effective Java 15 Minimize mutability
    Effective Java 14 In public classes, use accessor methods, not public fields
    Effective Java 13 Minimize the accessibility of classes and members
    Effective Java 12 Consider implementing Comparable
    sencha touch SortableList 的使用
    sencha touch dataview 中添加 button 等复杂布局并添加监听事件
  • 原文地址:https://www.cnblogs.com/sfnz/p/15618329.html
Copyright © 2011-2022 走看看