• 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

  • 相关阅读:
    例行性工作排程 (crontab)
    数组
    继续我们的学习。这次鸟哥讲的是LVM。。。磁盘管理 最后链接文章没有看
    htop资源管理器
    转:SSL协议详解
    转:SSL 握手协议详解
    转:Connection reset原因分析和解决方案
    使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件(转)
    转:logback的使用和logback.xml详解
    转:Java logger组件:slf4j, jcl, jul, log4j, logback, log4j2
  • 原文地址:https://www.cnblogs.com/sfnz/p/15618329.html
Copyright © 2020-2023  润新知