mysql字段默认值不生效的问题解决(上)

在项目中使用mybatis作为持久层框架,mysql数据库。项目上线前,DBA要求咱们将每张数据库表中的字段都设置默认值和not null。以前项目中有一些insert语句是将表中全部字段都列出来,而后把它作为一个通用的插入语句来使用。举个简单的例子:假如一张数据库表blog中有以下几个字段:id,title,content,author,除id外,每一个字段都设置了默认值Empty String(空字符串),写的一个insert语句是这样的: 


mysql

Java代码   收藏代码
  1. <insert id="addOneBlog" parameterType="main.Blog">  
  2.     insert into blog(title,author,content)  
  3.     values(#{title},#{author},#{content})  
  4. </insert>  



    原觉得有这么一个insert语句就万事大吉了,咱们觉得,之后作插入操做的时候,不管有多少个字段,都使用这一个insert语句,若是字段没有值,就会被赋值为mysql字段的默认值。。。 

    但事实证实,根本不是这样的。 

    当咱们只给title字段赋值,而后执行一个insert语句时,mybatis立刻报出这样的异常: 


sql

Java代码   收藏代码
  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语句没法作到通用。具体解决方案数据库

 

上一篇简单介绍了一个mysql的问题:字段默认值在使用全字段insert的时候,可能并不会生效。在使用mybatis时,虽然须要本身写sql,但相比原始jdbc的方式来讲,有一个很好的优点——动态sql。针对前一篇文章提出的问题,mybatis的动态sql能够很好地解决这个问题。mybatis

1.问题分析框架

    上一篇文章中描述的问题,是因为咱们误将一个包含全部字段的insert语句作为通用的insert。那么显而易见,解决此问题的方法是,咱们须要针对不一样的业务需求,严格按照须要插入的字段来写不一样的sql,不须要插入的字段,在insert语句中不可以出现。举例上一篇的blog表例子说明,假如咱们有一个插入操做,只须要在插入时给author赋值,那么sql能够这么写:ide

 

Xml代码   收藏代码
  1. <insert id="addOneBlog" parameterType="main.Blog">  
  2.     insert into blog(author)  
  3.     values (#{author})  
  4. </insert>  

 

 

    这个方法虽然奏效,但在实际项目开发中,为了开发效率的须要,咱们仍然但愿可以有一个通用的insert语句,供全部涉及单表插入操做的业务调用。刚才说过,mybatis有一个很是强大的特点功能:动态sql,使用动态sql便可解决此问题。spa

2.<sql>、<include>、<trim>标签简介blog

    mybatis的动态sql功能包含了不少实用的标签:<sql>标签表示一个sql片断,使用此标签不只能够重用不少sql代码,并且使sql语句更清晰;定义好<sql>标签后,在调用它的地方使用<include>标签,便可将定义好的sql片断拼接进来;<trim>标签能够在标签体内的sql片断首尾任意添加或覆盖字符。开发

3.问题解决字符串

先上代码:

 

Xml代码   收藏代码
  1. <sql id="blogColumns">  
  2.     <trim suffixOverrides=",">  
  3.         <if test="title != null">title,</if>  
  4.         <if test="author != null">author,</if>  
  5.         <if test="content != null">content</if>  
  6.     </trim>  
  7. </sql>  
  8.   
  9. <sql id="blogValues">  
  10.     <trim suffixOverrides=",">  
  11.         <if test="title != null">#{title},</if>  
  12.         <if test="author != null">#{author},</if>  
  13.         <if test="content != null">#{content}</if>  
  14.     </trim>  
  15. </sql>  
  16.   
  17. <insert id="addOneBlog" parameterType="Blog">  
  18.     insert into blog(<include refid="blogColumns"/>)  
  19.     values (<include refid="blogValues"/>)  
  20. </insert>  

     对于blog表,上面这段代码便可实现咱们想要的insert重用,无论插入的字段有多少,咱们均可以使用它来实现全部单表insert操做。上面代码中,先定义两个sql片断,分别表明insert语句中的字段列表和参数列表,并使用<trim>标签去除片断首尾可能出现的多余的“,”字符。最后写一个简单的insert,并将上面的sql片断拼接进来。

4.结尾

    关于mybatis的动态sql,它有不少强大的,可高度重用sql的功能。你们若是对一些标签的做用不太清楚,请期待我后续的博文。做为一个半自动的持久层框架,咱们虽然须要本身写sql语句,但mybatis的动态sql可以最大限度地减小咱们的代码量,这也是在ORM横行的JavaEE世界里,mybatis可以独树一帜的缘由。

相关文章
相关标签/搜索